J'essaie d'interroger un fichier xml généré par adium. xmlwf dit qu'il est bien formé. En utilisant l'option de débogage de xmllint, j'obtiens ce qui suit:
$ xmllint --debug doc.xml
DOCUMENT
version=1.0
encoding=UTF-8
URL=doc.xml
standalone=true
ELEMENT chat
default namespace href=http://purl.org/net/ulf/ns/0.4-02
ATTRIBUTE account
TEXT
[email protected]
ATTRIBUTE service
TEXT compact
content=MSN
TEXT compact
content=
ELEMENT event
ATTRIBUTE type
Tout semble bien analyser. Cependant, lorsque j'essaie d'interroger même les choses les plus simples, je n'obtiens rien:
$ xmllint --xpath '/chat' doc.xml
XPath set is empty
Que ce passe-t-il? L'exécution de cette même requête exacte à l'aide de xpath renvoie les résultats corrects (mais sans nouvelle ligne entre les résultats). Suis-je en train de faire quelque chose de mal ou est-ce que xmllint ne fonctionne pas correctement?
Voici une version plus courte et anonymisée du xml qui montre le même comportement:
<?xml version="1.0" encoding="UTF-8" ?>
<chat xmlns="http://purl.org/net/ulf/ns/0.4-02" account="[email protected]" service="MSN">
<event type="windowOpened" sender="[email protected]" time="2011-11-22T00:34:43-03:00"></event>
<message sender="[email protected]" time="2011-11-22T00:34:43-03:00" alias="foo"><div><span style="color: #000000; font-family: Helvetica; font-size: 12pt;">hi</span></div></message>
</chat>
Je n'utilise pas xmllint, mais je pense que la raison pour laquelle votre XPath ne fonctionne pas est que votre fichier doc.xml utilise un espace de noms par défaut (http://purl.org/net/ulf/ns/0.4-02
).
D'après ce que je peux voir, vous avez 2 options.
A. Utilisez xmllint en mode Shell et déclarez l'espace de noms avec un préfixe. Vous pouvez ensuite utiliser ce préfixe dans votre XPath.
xmllint --Shell doc.xml
/ > setns x=http://purl.org/net/ulf/ns/0.4-02
/ > xpath /x:chat
B. Utilisez local-name()
pour faire correspondre les noms des éléments.
xmllint --xpath /*[local-name()='chat']
Vous pouvez également utiliser namespace-uri()='http://purl.org/net/ulf/ns/0.4-02'
avec local-name()
afin d'être sûr de retourner exactement ce que vous avez l'intention de retourner.
Je me rends compte que cette question est très ancienne maintenant, mais au cas où cela aiderait quelqu'un ...
J'ai eu le même problème et cela était dû au fait que XML avait un espace de noms (et parfois il était dupliqué à divers endroits dans XML). J'ai trouvé plus simple de supprimer simplement l'espace de noms avant d'utiliser xmllint:
sed -e 's/xmlns=".*"//g' file.xml | xmllint --xpath "..." -
Dans mon cas, le XML était UTF-16, j'ai donc dû d'abord convertir en UTF-8 (pour sed):
iconv -f utf16 -t utf8 file.xml | sed -e 's/encoding="UTF-16"?>/encoding="UTF-8"?>/' | sed -e 's/xmlns=".*"//g' | xmllint --xpath "..." -