using System.Xml.Linq; using MaBibli.Shared.Dtos; namespace MaBibli.Api.Services.Isbn; /// /// Lecture d'une réponse SRU de la BnF au schéma dublincore. /// /// /// Fonction pure : aucun accès réseau, ce qui permet de la tester sur des réponses réelles /// enregistrées sur disque. /// public static class BnfSruParser { private static readonly XNamespace Srw = "http://www.loc.gov/zing/srw/"; private static readonly XNamespace Dc = "http://purl.org/dc/elements/1.1/"; /// Nombre de notices annoncé par <srw:numberOfRecords>, ou 0. public static int LireNombreDeNotices(string xml) { var doc = XDocument.Parse(xml); var valeur = doc.Descendants(Srw + "numberOfRecords").FirstOrDefault()?.Value; return int.TryParse(valeur, out var n) ? n : 0; } /// /// Convertit la réponse SRU en candidats, champs déjà nettoyés de la ponctuation ISBD. /// /// Corps de la réponse SRU. /// Forme d'ISBN qui a produit cette réponse (13 ou 10). /// URL de couverture OpenLibrary à attacher (la BnF n'en fournit pas). public static IReadOnlyList Parser(string xml, string isbnInterroge, string? urlCouverture) { var doc = XDocument.Parse(xml); var candidats = new List(); foreach (var record in doc.Descendants(Srw + "record")) { var data = record.Element(Srw + "recordData"); if (data is null) { continue; } var titre = NettoyageIsbd.Titre(Premier(data, "title")); if (titre is null) { // Une notice sans titre exploitable n'a aucun intérêt pour un pré-remplissage. continue; } candidats.Add(new CandidatLivre { Titre = titre, Auteur = NettoyageIsbd.Auteur(Premier(data, "creator")), Editeur = NettoyageIsbd.Editeur(Premier(data, "publisher")), Annee = Premier(data, "date"), Langue = Premier(data, "language"), CoverUrl = urlCouverture, Source = SourceMetadonnees.Bnf, IsbnInterroge = isbnInterroge, IdentifiantSource = record.Element(Srw + "recordIdentifier")?.Value?.Trim(), }); } return candidats; } private static string? Premier(XElement recordData, string nomLocal) { var valeur = recordData.Descendants(Dc + nomLocal).FirstOrDefault()?.Value?.Trim(); return string.IsNullOrEmpty(valeur) ? null : valeur; } }