Trip – Trick – XSL – Comparar el valor del nodo actual con el valor del nodo anterior

A veces tenemos la necesidad de comparar el valor del nodo actual con el valor del nodo anterior. Por ejemplo si tenemos un XML:


<?xml version="1.0" encoding="iso-8859-1"?>
<raiz>
    <hijos>
        <hijo>
            <codigo>1</codigo>
            <nombre>uno</nombre>
        </hijo>
        <hijo>
            <codigo>1</codigo>
            <nombre>uno</nombre>
        </hijo>
        <hijo>
            <codigo>2</codigo>
            <nombre>dos</nombre>
        </hijo>
        <hijo>
            <codigo>2</codigo>
            <nombre>dos</nombre>
        </hijo>
        <hijo>
            <codigo>3</codigo>
            <nombre>tres</nombre>
        </hijo>
        <hijo>
            <codigo>3</codigo>
            <nombre>tres</nombre>
        </hijo>
        <hijo>
            <codigo>3</codigo>
            <nombre>tres</nombre>
        </hijo>
        <hijo>
            <codigo>4</codigo>
            <nombre>cuatro</nombre>
        </hijo>
        <hijo>
            <codigo>4</codigo>
            <nombre>cuatro</nombre>
        </hijo>
        <hijo>
            <codigo>4</codigo>
            <nombre>cuatro</nombre>
        </hijo>
        <hijo>
            <codigo>4</codigo>
            <nombre>cuatro</nombre>
        </hijo>
    </hijos>
</raiz>

Tenemos nuestro XSLT que recuperara los valores diferentes del nodo hijo:


<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html"/>
<xsl:template match="raiz">
    <html>
        <body>
        <xsl:for-each select="hijos/hijo">
        <xsl:choose>
            <xsl:when test="position()=1">
                <p><xsl:value-of select="nombre"/></p>
            </xsl:when>
            <xsl:otherwise>
                <xsl:if test="codigo!=preceding-sibling::hijo[1]/codigo">
                    <p><xsl:value-of select="nombre"/></p>
                </xsl:if>
            </xsl:otherwise>
        </xsl:choose>
        </xsl:for-each>
        </body>
    </html>
</xsl:template>
</xsl:stylesheet>

EL preceding-sibling recupera todos los nodos que son anteriores al nodo actual, pero como nos interesa el anterior y adyacente por eso recuperamos el de la primera posición. Al transformar el XML con la hoja de estilo nos deberia retornar:


    <html>
        <body>
            <p>uno</p>
            <p>dos</p>
            <p>tres</p>
            <p>cuatro</p>
        </body>
    </html>

Referencia:
http://www.zvon.org/xxl/XSLTreference/Output/index.html

3 comentarios para “Trip – Trick – XSL – Comparar el valor del nodo actual con el valor del nodo anterior”

  1. Alex Pérez Dice:

    Interesante!

    Yo estoy haciendo mis primeros pasos con XSLT y es algo muy potente para tratar XML. Normalmente tengo que procesar mensajes de aplicaciones que vienen como XML, y con XSLT es mucho más eficiente que con JS.

    Una pregunta, los bloques XML que has insertado en el post: estan dentro de un “< code >” ? estoy buscando la combinación para que puedan ser mínimamente legibles en el mío, pero muchas veces wordpress se “come” los tags XML dejandomelo inservible. o quizas tienes los CSS cusstomizados?

    Saludos!

  2. Eduardo Sanchez Vera Dice:

    Hola, para ver código en wordpress puedes utilizar [ sourcecode ] y definir el estilo como xml. Via: http://faq.wordpress.com/2007/09/03/how-do-i-post-source-code/

  3. Diego Dice:

    Excelente artículo!
    Era precisamente lo que estaba necesitando y fue en el único sitio en el que lo encontré.
    Muchas gracias.

Escribe un comentario