2011-11-25 12 views
40

Estoy intentando consultar un archivo xml generado por adium. xmlwf dice que está bien formado. Al utilizar la opción de depuración de xmllint, obtengo lo siguiente:xmllint no se pudo consultar correctamente con xpath

$ 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 

Todo parece analizar perfectamente. Sin embargo, cuando trato de consultar incluso las cosas más simples, no obtengo nada:

$ xmllint --xpath '/chat' doc.xml 
XPath set is empty 

¿Qué está pasando? Ejecutar exactamente la misma consulta utilizando xpath devuelve los resultados correctos (sin embargo, sin nueva línea entre los resultados). ¿Estoy haciendo algo mal o es que xmllint simplemente no funciona correctamente?

Aquí hay una versión más corta, anonimizados del XML que muestra el mismo comportamiento:

<?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> 
+0

puede compartir el archivo doc.xml – rpg

Respuesta

67

No consumo xmllint, pero creo que la razón de su XPath no está funcionando es porque su doc.xml el archivo está usando un espacio de nombre predeterminado (http://purl.org/net/ulf/ns/0.4-02).

Por lo que puedo ver, tienes 2 opciones.

A. Utilice xmllint en modo shell y declare el espacio de nombres con un prefijo. Luego puede usar ese prefijo en su XPath.

xmllint --shell doc.xml 
    /> setns x=http://purl.org/net/ulf/ns/0.4-02 
    /> xpath /x:chat

B. Uso local-name() para que coincida con los nombres de elementos.

xmllint --xpath /*[local-name()='chat']

También puede que quiera usar namespace-uri()='http://purl.org/net/ulf/ns/0.4-02' junto con local-name() lo que está seguro de volver exactamente lo que tiene la intención de volver.

+2

Observe que el ejemplo A. y B. fallarán si no está accediendo a una ruta raíz, en cuyo caso necesita una barra doble, por ejemplo xmllint --xpath "// * [local-name() = 'chat'] ". Ver http://stackoverflow.com/questions/27311314/how-to-get-the-tag-yweathercondition-from-yahoo-weather-rss-with-xmllint?noredirect=1#comment43085213_27311314 –

+0

@ Avt'W - Esta pregunta/answer es específicamente sobre espacios de nombres en xmllint; no cualquier otro tema XPath. Lo que '/' y '//' coinciden no están relacionados. –

+5

Oye, fue un comentario para el lector que tendría un caso de uso ligeramente diferente, no un crítico de su respuesta que responda el problema con precisión. Las personas que tienen problemas con los espacios de nombres probablemente sean novatos y, por lo tanto, pensé que valía la pena señalarlo. –

Cuestiones relacionadas