2011-12-07 17 views
10

tengo el siguiente variable XSLT:Comprobar si el nodo con el atributo es igual al valor existe

<xsl:variable name="superid" select="/contentdata/id"/> 

Además, tengo un nodo con subnodos:

<nodes> 
    <node name="foo" id="bar" /> 
    <node name="john" id="doe" /> 
    <node name="jane" id="tarzan" /> 
</nodes> 

Ahora, me gustaría comprobar si un nodo con un atributo id que es igual a superid existe.

He intentado lo siguiente (que obviamente no funciona):

<xsl:if test="/nodes/node[@id = $superid]">Yes, Sir!</xsl:if> 
+0

¿Cuál es el valor de la variable $ superid? – Vitaliy

+0

¿Cuál es el mensaje de error que está recibiendo? Creo que podría ser la versión .NET y si estás usando xslt v1 o v2. Por favor, danos esta información. Crea un violín mientras lo haces :) –

Respuesta

15

Uso:

boolean(/nodes/node/@id = $superid) 

Aquí es una transformación completa, mostrando esto en acción:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="text"/> 
<xsl:strip-space elements="*"/> 

<xsl:variable name="vDoe" select="'doe'"/> 
<xsl:variable name="vXyz" select="'xyz'"/> 

<xsl:template match="/"> 
    id attribute with value "doe' exists: <xsl:text/> 
    <xsl:value-of select="boolean(/nodes/node/@id = $vDoe)"/> 
========== 
    id attribute with value "xyz' exists: <xsl:text/> 
    <xsl:value-of select="boolean(/nodes/node/@id = $vXyz)"/> 
</xsl:template> 
</xsl:stylesheet> 

cuando se aplica esta transformación en el documento XML proporcionado:

<nodes> 
    <node name="foo" id="bar" /> 
    <node name="john" id="doe" /> 
    <node name="jane" id="tarzan" /> 
</nodes> 

el, resultado correcto querido se produce:

 id attribute with value "doe' exists: true 
========== 
    id attribute with value "xyz' exists: false 
4

Lo que tienes parece funcionar para mí (Net 3.5) - según here.

he tratado de recrear su xslt:

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
       version="1.0" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       > 
    <xsl:output omit-xml-declaration="yes" method="xml" version="1.0" indent="yes" /> 

    <xsl:template match="/xml"> 
     <xml> 
      <xsl:apply-templates select="contentdata/id" /> 
     </xml> 
    </xsl:template> 

    <xsl:template match="id"> 
     <Result> 
     <xsl:variable name="superid" select="."/> 
     <SearchFor> 
      <xsl:value-of select="$superid"/> 
     </SearchFor> 
     <IsPresent> 
      <xsl:if test="/xml/nodes/node[@id = $superid]">Node is present</xsl:if> 
     </IsPresent> 
    </Result> 
    </xsl:template> 

</xsl:stylesheet> 

Dado el xml:

<xml> 
    <contentdata> 
     <id>doe</id> 
     <id>unobtanium</id> 
    </contentdata> 
    <nodes> 
     <node name='foo' id='bar' /> 
     <node name='john' id='doe' /> 
     <node name='jane' id='tarzan' /> 
    </nodes> 
</xml> 

de salida:

<xml xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
    <Result> 
     <SearchFor>doe</SearchFor> 
     <IsPresent>Node is present</IsPresent> 
    </Result> 
    <Result> 
     <SearchFor>unobtanium</SearchFor> 
     <IsPresent /> 
    </Result> 
</xml> 
3

Si está utilizando la expresión XPath /nodos/node [@id = $ superid] "> luego esto sería looki ng para un nodo raíz de nodos en su documento XML. Sin embargo, en su pregunta parece implicar que nodos es solo un nodo dentro de su documento, no necesariamente el elemento raíz. Prueba este lugar

<xsl:if test="//nodes/node[@id = $superid]">Yes, Sir!</xsl:if> 

La doble barra inclinada selecciona los nodos en el documento dondequiera que se encuentren en la jerarquía, no sólo el nodo de nivel superior.

1

Esto debería funcionar como se espera. Una de sus expresiones (ya sea en la variable select o en el atributo test) no debe seleccionar lo que usted cree que es. (No ha proporcionado toda su información, por lo que es difícil ayudar allí.)

Nota algunas cosas sobre xsl:if:

  • En primer lugar, ver this part of the XSLT spec (el subrayado es mío):

    el XSL: si el elemento tiene un atributo de la prueba, que especifica una expresión . El contenido es una plantilla. La expresión se evalúa y el objeto resultante se convierte en booleano como si fuera una llamada a la función booleana . Si el resultado es verdadero, la plantilla de contenido es instanciada; de lo contrario, no se crea nada.

  • Entonces, ¿cómo funcionaría una llamada a la función boolean en su entrada? Ver this part of the XPath spec (de nuevo, énfasis mío):

    la función booleana convierte su argumento para un booleano como sigue:

    • un número es verdadero si y sólo si no es ni positiva o negativa cero ni NaN

    • un conjunto de nodos es verdadero si y sólo si no está vacío

    • una cadena es cierto si y sólo si su longitud no es cero

    • un objeto de un tipo distinto a los cuatro tipos básicos se convierte en un valor booleano de una manera que depende de ese tipo

lo tanto, si en realidad /contentdata/id selecciona un id para los que /nodes/node[@id = $superid] devuelve un conjunto de nodos que no está vacía, entonces el cuerpo de la xsl:if debe ejecutar.

Cuestiones relacionadas