2011-02-10 22 views
6

La sintaxis agnóstica del espacio de nombres que he visto me confunde.Espacio de nombres agnóstico Consulta XPath con contenido de elementos

Decir que tengo:

<root> 
    <parent attribute="A">A<child>A</child></parent> 
    <parent attribute="B">B<child>B</child></parent> 
</root> 

Hasta ahora veo cómo:

/root/parent/child/text() 

se traduce en:

/*[local-name()='root']/*[local-name()='parent']/*[local-name()='child']/text() 

pero yo estoy luchando con cosas como esta:

/root/parent[@attribute="A"]/child/text() 

o:

/root/parent[text()="B"]/child/text() 

o:

/root/parent[1]/child/text() 

¿Cómo se traducen?

Gracias,

EDIT: Una más :-)

<root> 
     <parent> 
      <childName>serverName</childName> 
      <childValue>MyServer</childValue> 
     </parent> 
     <parent> 
      <childName>ServerLocation</childName> 
      <childValue>Somewhere</childValue> 
     </parent> 
</root> 

¿Cómo se traduce esto?

/root/parent[childName="serverName"]/childValue/text() 
+0

Buena pregunta, 1. Vea mi respuesta para una recomendación, advertencia y traducciones completas de todas las expresiones XPath provistas. –

Respuesta

10

El espacio de nombres de sintaxis agnóstico que he visto por ahí me está confundiendo.

En primer lugar, yo le aconsejaría no utilizar esta sintaxis, especialmente si es confuso. También puede provocar errores. Para obtener detalles, consulte el final de mi respuesta.

La forma estándar de especificar en una expresión XPath los nombres que están en un espacio de nombres es registrar un espacio de nombres con su motor XPath (consulte la respectiva documentación específica del proveedor) y luego usar el prefijo vinculado al espacio de nombres registrado (diga "x") con nombres como x:someName

Hay muchas buenas respuestas sobre este tema - no use una de ellas.

Ahora, si debido a alguna razón aún así decide utilizar la sintaxis confusa, entonces:

pero estoy luchando con cosas como esta :

/root/parent[@attribute="A"]/child/text()

Uso:

/*[local-name()='root']/*[local-name()='parent' and @attribute='A'] 

a continuación:

o:

/root/parent[text()="B"]/child/text()

Uso:

/*[local-name()='root']/*[local-name()='parent' and text()='B'] 
            /*[local-name()='child']/text() 

a continuación:

o:

/root/parent[1]/child/text() 

Uso:

/*[local-name()='root']/*[local-name()='parent'][1] 
           /*[local-name()='child']/text() 

a continuación:

Uno Más :-)

<root> 
    <parent> 
     <childName>serverName</childName> 
     <childValue>MyServer</childValue> 
    </parent> 
    <parent> 
     <childName>ServerLocation</childName> 
     <childValue>Somewhere</childValue> 
    </parent> 
</root> 

¿Cómo se traduce esto?

/root/parent[childName="serverName"]/childValue/text() 

Uso:

/*[local-name()='root'] 
     /*[local-name()='parent'][*[local-name()='childName"]='serverName'] 
              /*[local-name()='childValue']/text() 

hacer la nota:

Tales expresiones no pueden seleccionar los nodos deseados si en los documentos XML existen elementos con el mismo local, -name que pertenece a dos espacios de nombres diferentes.

+0

+1 me ganó por 53 segundos. :-) – LarsH

+0

+1 para los dos. – Flack

+0

Gracias Dimitre, ten en cuenta tu advertencia :-) Lamentablemente me veo obligado a utilizar este tipo de xpath porque necesito usarlo en InstallShield en la función de búsqueda del sistema. Lamentablemente, la característica no proporciona ninguna forma de definir un espacio de nombres. Los archivos XML que estoy buscando solo tienen 1 espacio de nombres, así que estoy a salvo. Por cierto, son archivos de configuración de web.xml de Tomcat. ¡Gracias! –

4

Entiendo su pregunta en el sentido de ¿cómo puedo hacer que estas expresiones XPath sean agnósticas? (No es una sintaxis especial, sólo un uso típico del local-name() función.)

/root/parent[@attribute="A"]/child/text() 

se convertiría en

/*[local-name()='root']/*[local-name()='parent'][@attribute='A']/*[local-name()='child']/text() 

(usted podría utilizar comillas dobles para el valor de atributo si querer, pero eso haría más difícil incrustar en XSLT o lo que sea que sea su entorno.)

/root/parent[text()="B"]/child/text() 

se convertiría en

/*[local-name()='root']/*[local-name()='parent'][text() = 'B']/*[local-name()='child']/text() 

Y

/root/parent[1]/child/text() 

se convertiría en

/*[local-name()='root']/*[local-name()='parent'][1]/*[local-name()='child']/text() 
+0

+1 por ser casi tan rápido como yo :) –

+0

Largo sin ver :) ¿Dónde has estado? Creo que esto podría serle interesante: http://dnovatchev.wordpress.com/2011/02/08/the-binary-search-tree-data-structurehaving-fun-with-xpath-3-0/ –

+0

+1 para ambos. – Flack

Cuestiones relacionadas