2011-09-16 64 views
5

Considere el siguiente código XML:XPath: es posible combinar consultas

<root> 
    <steps> 
    <step>1</step> 
    <step>2</step> 
    <step>3</step> 
    <step>4</step> 
    </steps> 
    <stepDetails step="1">Details</stepDetails> 
    <stepDetails step="2">Details</stepDetails> 
    <stepDetails step="3">Details</stepDetails> 
</root> 

Lo que necesito hacer es encontrar todos los pasos que no tienen stepDetails correspondientes. En el ejemplo anterior, solo se devolverá el nodo "<paso/paso>".

Ahora, sé que puedo hacer eso consultando todos los pasos, recorriendo la colección y realizando otra consulta para cada iteración. Espero que haya una forma de hacerlo con una sola consulta. Tal vez usando algo como la declaración IN de SQL y una subconsulta.

Cualquier idea o sugerencia sería muy apreciada.

thnx, Christoph

Respuesta

14

Prueba esto:

/root/steps/step[not(. = /root/stepDetails/@step)] 
+0

+1 para una respuesta correcta. –

+0

La consulta inversa sería: /root/stepDetails/@ step [no (. =/Root/steps/step)] ? Si comento alguno de los pasos (por ejemplo, el paso 3), esa consulta XPath lo encontrará. ¿Hay alguna forma de incluir el paso 4 en un resultado de consulta? – Christoph

+0

No estoy seguro de lo que quiere decir con una consulta inversa, pero si está tratando de encontrar stepDetails sin el paso correspondiente lo haría:/root/stepDetails [not (@step =/root/steps/step)] - como para incluir el paso 4 creo que está incluido en los resultados de la consulta que di en la respuesta? –

0

algo como esto?

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl" 
> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:key name="steps" match="//root/stepDetails" use="@step" /> 

    <xsl:template match="//root"> 
    <root> 
     <steps> 
     <xsl:for-each select="steps/step[not(key('steps',text()))]"> 
     <xsl:copy> 
      <xsl:apply-templates select="@* | node()" /> 
     </xsl:copy> 
     </xsl:for-each> 
     </steps> 
    </root> 
    </xsl:template> 



    <xsl:template match="@* | node()"> 
    <xsl:copy> 
     <xsl:apply-templates select="@* | node()" /> 
    </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 
Cuestiones relacionadas