uso sacar online herramienta ejemplos como xml xslt xpath

xml - sacar - conjunto de nodos en xpath



xpath uso (1)

Estoy escribiendo una hoja de estilo xslt para transformar un xml en otro xml.

Aquí está la versión simplificada de xml original:

<eml> <datatable> <physical> <distribution id="100"/> </physical> </datatable> <software> <implementation> <distribution id="200"/> </implementation> </software> <additionalMetadata> <describes>100</describes> <describes>200</describes> <describes>300</describes> <describes>400</describes> </additionalMetadata> </eml>

Intento usar un Xpath para seleccionar el conjunto de nodos de "describe" que no tiene el valor que iguala el valor id de //physical/distribution o software/implementation/distribution . En el caso anterior, quiero obtener el conjunto de nodos:

<deseribes>300</describes> <deseribes>400</describes>

(100 y 200 son valores de identificación de atributo de //physical/distribution o software/implementation/distribution ).

Escribí algo como:

<xsl:with-param name="describes-list" select="./describes[//physical/distribution/@id !=. and //software/implementation/distribution/@id != .] "/>

Funciona en el ejemplo anterior. Sin embargo, el elemento de la tabla de datos y el software son repetibles. Entonces este xml es válido:

<eml> <datatable> <physical> <distribution id="100"/> </physical> </datatable> <datatable> <physical> <distribution id="300"/> </physical> </datatable> <software> <implementation> <distribution id="200"/> </implementation> </software> <additionalMetadata> <describes>100</describes> <describes>200</describes> <describes>300</describes> <describes>400</describes> </additionalMetadata> </eml>

Pero mi xslt no funciona en el ejemplo anterior :(

¿Te importaría arrojar algo de luz sobre esto? ¡Gracias de antemano!

Jing


Este es un error que a menudo se comete. Nunca use el operador "! =" De XPath cuando uno o ambos operandos son / son establecidos por nodo.

value != node-set

por definición, es verdadero si existe un nodo n en el conjunto de nodos, de modo que

value no es igual a la string(n)

Lo que quieres es eso

value no es igual a ningún nodo en el conjunto de nodos.

Esto se puede expresar de la siguiente manera:

value = node-set

es verdadero si existe al menos un nodo n en el conjunto de nodos, de modo que:

value = string(n)

Entonces

not(value = node-set)

es verdadero si no existe ningún nodo n en el conjunto de nodos, de modo que

value = string(n)

Por lo tanto, la siguiente expresión XPath seleccionará los nodos deseados :

/*/*/describes[not(. = ../../*/physical/distribution/@id) and not(. = ../../*/implementation/distribution/@id)]

Personalmente preferiría tener solo una comparación del nodo de contexto con la unión de los dos conjuntos de nodos:

/*/*/describes [not(. = (../../*/physical/distribution/@id | ../../*/implementation/distribution/@id ) ) ]

Tenga en cuenta que evito usar la abreviatura "//" . Por lo general, es muy costoso (ineficiente) y debe usarse solo si no conocemos la estructura del documento XML.

Y, por supuesto, las expresiones XPath anteriores deben ser evaluadas contra el siguiente documento XML (el segundo proporcionado en la pregunta):

<eml> <datatable> <physical> <distribution id="100"/> </physical> </datatable> <datatable> <physical> <distribution id="300"/> </physical> </datatable> <software> <implementation> <distribution id="200"/> </implementation> </software> <additionalMetadata> <describes>100</describes> <describes>200</describes> <describes>300</describes> <describes>400</describes> </additionalMetadata> </eml>