online attribute xslt xpath

xslt - attribute - Profundidad de salida del nodo actual en la jerarquía



xpath selenium (3)

Usando XSLT / XPATH 1.0, quiero crear HTML donde el atributo de class de un elemento span indica la profundidad en la jerarquía XML original.

Por ejemplo, con este fragmento XML:

<text> <div type="Book" n="3"> <div type="Chapter" n="6"> <div type="Verse" n="12"> </div> </div> </div> </text>

Quiero este HTML:

<span class="level1">Book 3</span> <span class="level2">Chapter 6</span> <span class="level3">Verse 12</span>

No se sabe a priori qué tan profundo podrían ir estos elementos div . Los div s podrían ser Libro -> Capítulo. Podrían ser Volumen -> Libro -> Capítulo -> Párrafo -> Línea.

No puedo confiar en los valores de @type. Algunos o todos podrían ser NULL.


Como usualmente con XSL, usa recursión.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html" indent="yes"/> <xsl:template match="/text"> <html> <xsl:apply-templates> <xsl:with-param name="level" select="1"/> </xsl:apply-templates> </html> </xsl:template> <xsl:template match="div"> <xsl:param name="level"/> <span class="{concat(''level'',$level)}"><xsl:value-of select="@type"/> <xsl:value-of select="@n"/></span> <xsl:apply-templates> <xsl:with-param name="level" select="$level+1"/> </xsl:apply-templates> </xsl:template> </xsl:stylesheet>


O sin usar recursión, pero la respuesta de Dimitre es mejor que la mía

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/text"> <html> <body> <xsl:apply-templates/> </body> </html> </xsl:template> <xsl:template match="//div"> <xsl:variable name="depth" select="count(ancestor::*)"/> <xsl:if test="$depth > 0"> <xsl:element name="span"> <xsl:attribute name="class"> <xsl:value-of select="concat(''level'',$depth)"/> </xsl:attribute> <xsl:value-of select="concat(@type, '' '' , @n)"/> </xsl:element> </xsl:if> <xsl:apply-templates/> </xsl:template> </xsl:stylesheet>


Esto tiene una solución muy simple y corta: sin recurrencia, sin parámetros, sin xsl:element , sin xsl:attribute :

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="div"> <span class="level{count(ancestor::*)}"> <xsl:value-of select="concat(@type, '' '', @n)"/> </span> <xsl:apply-templates/> </xsl:template> </xsl:stylesheet>

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

<text> <div type="Book" n="3"> <div type="Chapter" n="6"> <div type="Verse" n="12"></div></div></div> </text>

el resultado deseado y correcto se produce :

<span class="level1">Book 3</span> <span class="level2">Chapter 6</span> <span class="level3">Verse 12</span>

Explicación : uso adecuado de plantillas, AVT y la función count() .