xsl validaciones transformador test plantillas manejo generar ejemplos archivo xslt xslt-2.0

validaciones - xslt editor



contar los nodos ignorando los nodos en blanco (1)

Qué tal si ....

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0"> <xsl:output method="html" doctype-public="XSLT-compat" encoding="UTF-8" indent="yes" /> <xsl:strip-space elements="*" /> <xsl:variable name="FinalChap"> <xsl:value-of select="format-number( xs:integer( substring-before((/body/nd/pnn)[1],''.'')), ''00'')"/> </xsl:variable> <xsl:template match="/"> <html> <head><title>New Version from Sean!</title></head> <xsl:apply-templates /> </html> </xsl:template> <xsl:template match="*"> <xsl:apply-templates /> </xsl:template> <xsl:template match="text()|processing-instruction()|comment()|@*" /> <xsl:template match="body"> <xsl:for-each-group select="nd" group-adjacent="h2/text()"> <xsl:variable name="group-position" select="position()" /> <xsl:for-each select="current-group()"> <xsl:call-template name="nd"> <xsl:with-param name="group-position" select="$group-position" /> <xsl:with-param name="is-head" select="position() eq 1" as="xs:boolean" /> </xsl:call-template> </xsl:for-each> </xsl:for-each-group> </xsl:template> <xsl:template name="nd"> <xsl:param name="group-position" select="1" as="xs:integer" /> <xsl:param name="is-head" select="true()" as="xs:boolean" /> <div class="section-sect1"> <xsl:if test="$is-head"> <xsl:call-template name="a-link"> <xsl:with-param name="group-position" select="$group-position" /> <xsl:with-param name="delta" select="0" as="xs:integer" /> </xsl:call-template> <div class="section-title"> <div class="section-title"><xsl:value-of select="h2" /></div> </div> </xsl:if> <div class="section-sect3"> <xsl:call-template name="a-link"> <xsl:with-param name="group-position" select="$group-position" /> <xsl:with-param name="delta" select="1" as="xs:integer" /> </xsl:call-template> <div class="section-title"><xsl:value-of select="ti" /></div> </div> </div> </xsl:template> <xsl:template name="a-link"> <xsl:param name="group-position" select="1" as="xs:integer" /> <xsl:param name="delta" select="0" as="xs:integer" /> <a name="CH_{$FinalChap}-SEC-{$group-position + count(preceding-sibling::nd) + $delta}" /> </xsl:template> </xsl:transform>

La transformación anterior, cuando se aplica al documento de entrada ...

<body> <nd> <pnn>1.1</pnn> <h1>PART 54</h1> <h2>I INTRODUCT</h2> <ti>Construction</ti> </nd> <nd> <h1>PART 54</h1> <h2>I INTRODUCT</h2> <ti>Time</ti> </nd> <nd> <h1>PART 54</h1> <h2>I INTRODUCT</h2> <ti>Power</ti> </nd> <nd> <h1>PART 54</h1> <h2>II APPLICATIONS</h2> <ti>Filing</ti> </nd> </body>

... produce el documento de salida ...

<html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>New Version from Sean!</title> </head> <div class="section-sect1"> <a name="CH_01-SEC-1"/> <div class="section-title"> <div class="section-title">I INTRODUCT</div> </div> <div class="section-sect3"> <a name="CH_01-SEC-2"/> <div class="section-title">Construction</div> </div> </div> <div class="section-sect1"> <div class="section-sect3"> <a name="CH_01-SEC-3"/> <div class="section-title">Time</div> </div> </div> <div class="section-sect1"> <div class="section-sect3"> <a name="CH_01-SEC-4"/> <div class="section-title">Power</div> </div> </div> <div class="section-sect1"> <a name="CH_01-SEC-5"/> <div class="section-title"> <div class="section-title">II APPLICATIONS</div> </div> <div class="section-sect3"> <a name="CH_01-SEC-6"/> <div class="section-title">Filing</div> </div> </div> </html>

Explicación

La plantilla del body usa xsl: for-each-group para agrupar los elementos nd por h2 adyacente común (encabezados h2). El constructor de secuencia xsl: for-each-group invoca la plantilla nd para procesar cada elemento nd en orden, pasandole el número de grupo, y si este nd es el primero (el ''head'') nd del grupo.

De su salida de muestra deduje que el head nd de cada grupo produce contenido adicional sobre el grupo, incluido un extra a-link.

El número del enlace a (por ejemplo 4 en CH_01-SEC-4 ) es igual al recuento de nd''s anteriores, más el número de grupo, más un 1 adicional si no somos un nd de cabeza.

Soluciones alternativas

Así como hay muchas maneras de despellejar a un gato, hay algunas soluciones alternativas que serían igualmente válidas. En lugar de agrupar, puede usar un diseño de inserción completa. El contenido extra para los nodos de cabeza ( <div class="section-title"> ) podría lograrse usando un predicado en el patrón de plantilla, comparando este h2 con el h2 anterior. Y el número de corrección de los enlaces a podría lograrse mediante microencaminamiento.

Tengo el siguiente XML.

Caso 1

<body> <nd> <pnn>1.1</pnn> <h1>PART 54</h1> <ti>Construction</ti> </nd> <nd> <h1>PART 54</h1> <h2>I INTRODUCT</h2> <ti>Time</ti> </nd> <nd> <h1>PART 54</h1> <h2>I INTRODUCT</h2> <ti>Power</ti> </nd> <nd> <h1>PART 54</h1> <h2>II APPLICATIONS</h2> <ti>Filing</ti> </nd> </body>

Caso 2

<body> <nd> <pnn>1.1</pnn> <h1>PART 54</h1> <h2>I INTRODUCT</h2> <ti>Construction</ti> </nd> <nd> <h1>PART 54</h1> <h2>I INTRODUCT</h2> <ti>Time</ti> </nd> <nd> <h1>PART 54</h1> <h2>II APPLICATIONS</h2> <ti>Filing</ti> </nd> </body>

y el siguiente XSLT

<?xml version="1.0" encoding="UTF-8" ?> <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0"> <xsl:output method="html" doctype-public="XSLT-compat" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" /> <xsl:template match="/"> <hmtl> <head> <title>New Version!</title> </head> <xsl:apply-templates select="body"></xsl:apply-templates> </hmtl> </xsl:template> <xsl:template match="body"> <xsl:for-each select="nd"> <xsl:apply-templates select = "."/> </xsl:for-each> </xsl:template> <xsl:template match="pnn"/> <xsl:template match="h1"/> <xsl:template match="h2"/> <xsl:template match="ti"/> <xsl:variable name="FinalChap"> <xsl:value-of select="substring-before((//pnn)[1],''.'')"/> </xsl:variable> <xsl:variable name="FinalChn"> <xsl:value-of select="$FinalChap"/> </xsl:variable> <xsl:variable name="Finalchapternumber"> <xsl:value-of select="format-number($FinalChn,''00'')"/> </xsl:variable> <xsl:template name="section" match="nd"> <xsl:variable name="count"> <xsl:number count="nd" level="any"/> </xsl:variable> <xsl:variable name="classname"> <!--Get name attribute of current node --> <xsl:value-of select="concat(''section-sect'',''1'')"/> </xsl:variable> <xsl:variable name="classname1"> <!--Get name attribute of current node --> <xsl:value-of select="concat(''section-sect'',''2'')"/> </xsl:variable> <xsl:variable name="classname2"> <!--Get name attribute of current node --> <xsl:value-of select="concat(''section-sect'',''3'')"/> </xsl:variable> <!--Create a string variable by concat string method --> <xsl:variable name="sectionname"> <xsl:value-of select="concat(''CH_'',$Finalchapternumber,''-SEC-'', $count)"/> </xsl:variable> <div class="{$classname}"> <xsl:if test="./h2 and not(preceding::h2[1]/text() = ./h2/text())"> <a name="{$sectionname}"> </a> <div class="section-title"> <xsl:if test="not(preceding::h2[1]/text() = ./h2/text())"> <xsl:apply-templates select="h2" mode="section"/> </xsl:if> </div> </xsl:if> <xsl:if test="not(lower-case(./ti/text()) = lower-case(./h2/text()))"> <xsl:if test="./ti"> <div class="{$classname2}"> <xsl:apply-templates select="ti" mode="section"/> </div> </xsl:if> </xsl:if> <xsl:apply-templates select="child::node()[not(self::h2|self::ti)]"/> </div> </xsl:template> <xsl:template match="ti" mode="section"> <xsl:apply-templates select="./node()[1][self::page]" mode="first"/> <xsl:variable name="sectionnum"> <xsl:number count="nd" level="any"/> </xsl:variable> <a name="CH_{$Finalchapternumber}-SEC-{$sectionnum}"/> <div class="section-title"> <xsl:apply-templates/> </div> </xsl:template> <xsl:template match="h2" mode="section"> <div class="section-title"> <xsl:apply-templates select="child::node()[not(self::fnt)]"/> </div> </xsl:template> </xsl:transform>

aquí estoy tratando de incrementar el número de sección en función de una condición. El conteo debe hacerse, si no hay un nodo (aquí h2 ) debe ignorarse <a name="CH_01-SEC-XX"></a> Puedo hacerlo usando <xsl:if test="./h2 and not(preceding::h2[1]/text() = ./h2/text())"> , pero el desafío al que me enfrento es el count no lo estoy ignorando.

Salida de corriente. Caso 1

<div class="section-sect1"> <a name="CH_01-SEC-1"/> <div class="section-title"> <div class="section-title">I INTRODUCT</div> </div> <div class="section-sect3"> <a name="CH_01-SEC-1"/> <div class="section-title">Construction</div> </div> </div> <div class="section-sect1"> <div class="section-sect3"> <a name="CH_01-SEC-2"/> <div class="section-title">Time</div> </div> </div> <div class="section-sect1"> <div class="section-sect3"> <a name="CH_01-SEC-3"/> <div class="section-title">Power</div> </div> </div> <div class="section-sect1"> <a name="CH_01-SEC-4"/> <div class="section-title"> <div class="section-title">II APPLICATIONS</div> </div> <div class="section-sect3"> <a name="CH_01-SEC-4"/> <div class="section-title">Filing</div> </div> </div>

Salida esperada Caso 1

<div class="section-sect1"> <a name="CH_01-SEC-1"/> <div class="section-title"> <div class="section-title">I INTRODUCT</div> </div> <div class="section-sect3"> <a name="CH_01-SEC-2"/> <div class="section-title">Construction</div> </div> </div> <div class="section-sect1"> <div class="section-sect3"> <a name="CH_01-SEC-3"/> <div class="section-title">Time</div> </div> </div> <div class="section-sect1"> <div class="section-sect3"> <a name="CH_01-SEC-4"/> <div class="section-title">Power</div> </div> </div> <div class="section-sect1"> <a name="CH_01-SEC-5"/> <div class="section-title"> <div class="section-title">II APPLICATIONS</div> </div> <div class="section-sect3"> <a name="CH_01-SEC-6"/> <div class="section-title">Filing</div> </div> </div>

Caso de salida actual 2

<div class="section-sect1"><a name="CH_01-SEC-1"></a><div class="section-title"> <div class="section-title">I INTRODUCT</div> </div> <div class="section-sect3"><a name="CH_01-SEC-1"></a><div class="section-title">Construction</div> </div> </div> <div class="section-sect1"> <div class="section-sect3"><a name="CH_01-SEC-2"></a><div class="section-title">Time</div> </div> </div> <div class="section-sect1"><a name="CH_01-SEC-3"></a><div class="section-title"> <div class="section-title">II APPLICATIONS</div> </div> <div class="section-sect3"><a name="CH_01-SEC-3"></a><div class="section-title">Filing</div> </div> </div>

Salida esperada Caso 2

<div class="section-sect1"> <a name="CH_01-SEC-1"/> <div class="section-title"> <div class="section-title">I INTRODUCT</div> </div> <div class="section-sect3"> <a name="CH_01-SEC-2"/> <div class="section-title">Construction</div> </div> </div> <div class="section-sect1"> <div class="section-sect3"> <a name="CH_01-SEC-3"/> <div class="section-title">Time</div> </div> </div> <div class="section-sect1"> <a name="CH_01-SEC-4"/> <div class="section-title"> <div class="section-title">II APPLICATIONS</div> </div> <div class="section-sect3"> <a name="CH_01-SEC-5"/> <div class="section-title">Filing</div> </div> </div>

en la salida actual hay un duplicado CH_01-SEC-1 ¿Puede alguien decirme cómo convertirlo en una serie de 1...n

Aquí hay un DEmo activo

Gracias