2 votes

Problème d'accès aux attributs XML via xpath

J'ai du XML qui se compose de nombreuses répétitions de la structure XML suivante :

oai:dnb.de/dnb:reiheO/12546456082022-04-01T23:49:32Z
dnb:reiheO

Avantages de la détection simultanée in situ de plusieurs espèces pour les applications de mesure des émissions portables / Luigi Biondo, Henrik Gerken, Lars Illmann, Tim Steinhaus, Christian Beidl, Andreas Dreizler, Steven Wagner
Biondo, Luigi Verfasser]
Gerken, Henrik [Verfasser]
[Illmann, Lars [Verfasser]
Steinhaus, Tim [Verfasser]
Beidl, Christian [Verfasser]
Dreizler, Andreas [Verfasser]
Wagner, Steven [Verfasser]
Darmstadt : Universitäts- und Landesbibliothek
2022
eng
urn:nbn:de:tuda-tuprints-210508
http://nbn-resolving.de/urn:nbn:de:tuda-tuprints-210508
http://d-nb.info/1254645608/34
http://tuprints.ulb.tu-darmstadt.de/21050/
1254645608
670 Industrielle und handwerkliche Fertigung
lizenzfrei
Online-Ressource

Capable d'adresser la plupart des éléments et d'extraire les informations à l'intérieur, mais ayant du mal à accéder aux éléments spécifiques où je dois définir l'attribut également. Je pense avoir du mal avec xpath, mais je n'arrive pas vraiment à comprendre pourquoi.

Si j'essaie ce code, j'obtiens bien une liste d'éléments, mais elle est vide :

urn = xml.find_all('.//dc:identifier[@xsi:type="tel:URN"]', namespaces=ns)

Il se passe la même chose pour la version moins spécifique :

urn = xml.find_all('.//dc:identifier', namespaces=ns)  

Cependant, ce code : test1 = xml.find_all("dc:identifier") fonctionne et renvoie une belle liste d'éléments, mais évidemment pas seulement des identifiants spécifiés comme urn.

Mais celui-ci : urn = xml.find_all('dc:identifier[@xsi:type="tel:URN"]', namespaces=ns) renvoie de nouveau une liste vide. Et quelle que soit la combinaison que j'essaie, j'obtiens soit une liste vide, soit rien ne fonctionne du tout.

Quelqu'un a-t-il une idée de pourquoi c'est le cas ou que pourrais-je essayer d'autre ? C'est tellement frustrant d'obtenir cette liste de tous les identifiants mais de ne pas réussir à sélectionner celui dont j'ai besoin à partir du xsi:type...

MISE À JOUR :

Je récupère les données via OAI et j'utilise les bibliothèques suivantes et j'utilise requests et BeautifulSoup. J'ai également essayé ElementTree et lxml.

Je stocke littéralement la réponse de l'API dans une variable appelée "xml" et ensuite j'essaie le code suivant, dont une partie fonctionne et une autre non :

ids = xml.find_all("identifier")[0].text
print(ids)

urn1 = xml.find_all("dc:identifier")
urn1 = urn1[0].text
print(urn1)

test1 = xml.find_all("dc:identifier")
print(test1)

urn2 = xml.find_all(".//dc:identifier")
print(urn2)

urn3 = xml.find_all("dc:identifier[@xsi:type='tel:URN']")
print(urn3)

Les deux premiers renvoient le texte de l'élément comme prévu (je sais que le premier est l'élément isolé dans l'en-tête, pas le premier objet dc:identifier, cela servait juste à des fins de test), la troisième partie renvoie la liste de tous les éléments. Les deux derniers, en revanche, renvoient une liste vide, et c'est le problème (car j'ai besoin de l'élément xsi:type spécifique spécifié dans la dernière tentative).

1voto

Mads Hansen Points 24537

Si vous utilisez BeautifulSoup, la méthode find_all() accepte le nom de l'élément, et non un chemin XPath, pour le premier paramètre.

Signature de la méthode : find_all(nom, attrs, recursive, string, limit, **kwargs)

Si vous souhaitez utiliser XPath, vous devrez peut-être regarder d'autres bibliothèques.

Voir : peut-on utiliser XPath avec BeautifulSoup?

1voto

Jack Fleeting Points 4393

Tout d'abord, votre xml n'est toujours pas bien formé car le préfixe xsi n'a pas été déclaré. J'ai fait une déclaration ci-dessous juste pour faire fonctionner la réponse.

Deuxièmement, vous devez utiliser un analyseur xml comme lxml pour utiliser xpath.

Donc, en résumé :

rec = """[votre xml ci-dessus, mais avec le premier élément dc maintenant qui lit :

`

et cela devrait fonctionner

`

1voto

HedgeHog Points 2934

Comme mentionné travailler avec un XML valide rendrait les choses beaucoup plus faciles, mais il y a aussi un moyen d'utiliser BeautifulSoup et son analyseur standard lxml - Eh bien, cela ne fonctionne pas avec xpath mais est très proche de vos tentatives.

En utilisant find() / find_all():

soup.find_all('dc:identifier' , {'xsi:type':'tel:URN'})

pour obtenir une liste de textes:

[e.text for e in soup.find_all('dc:identifier' , {'xsi:type':'tel:URN'})]

Lors de l'utilisation des sélecteurs CSS avec select() / select_one() au lieu de find() / find_all() vous devez échapper les ::

soup.select('dc\:identifier[xsi\:type="tel:URN"]')

pour obtenir une liste des textes combinée avec la compréhension de liste:

[e.text for e in soup.select('dc\:identifier[xsi\:type="tel:URN"]')]
Exemple
from bs4 import BeautifulSoup

xml='''

oai:dnb.de/dnb:reiheO/12546456082022-04-01T23:49:32Z
dnb:reiheO

Advantages of Simultaneous In Situ Multispecies Detection for Portable Emission Measurement Applications / Luigi Biondo, Henrik Gerken, Lars Illmann, Tim Steinhaus, Christian Beidl, Andreas Dreizler, Steven Wagner
urn:nbn:de:tuda-tuprints-210508#fromFirstRecord
http://nbn-resolving.de/urn:nbn:de:tuda-tuprints-210508
http://d-nb.info/1254645608/34
http://tuprints.ulb.tu-darmstadt.de/21050/
1254645608
670 Industrielle und handwerkliche Fertigung
lizenzfrei
Online-Ressource

oai:dnb.de/dnb:reiheO/12546456082022-04-01T23:49:32Z
dnb:reiheO

Advantages of Simultaneous In Situ Multispecies Detection for Portable Emission Measurement Applications / Luigi Biondo, Henrik Gerken, Lars Illmann, Tim Steinhaus, Christian Beidl, Andreas Dreizler, Steven Wagner
urn:nbn:de:tuda-tuprints-210508#fromSecondRecord
http://nbn-resolving.de/urn:nbn:de:tuda-tuprints-210508
http://d-nb.info/1254645608/34
http://tuprints.ulb.tu-darmstadt.de/21050/
1254645608
670 Industrielle und handwerkliche Fertigung
lizenzfrei
Online-Ressource

'''

soup = BeautifulSoup(xml)

[e.text for e in soup.select('dc\:identifier[xsi\:type="tel:URN"]')]
Sortie
['urn:nbn:de:tuda-tuprints-210508#fromFirstRecord',
 'urn:nbn:de:tuda-tuprints-210508#fromSecondRecord']

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X