salto sacar recorrer nodos linea herramienta expresión evaluar ejemplos debe consultas conjunto con como xml xslt xslt-2.0

xml - sacar - Crear elementos padre-hijo a partir de jerarquía semántica en valores de elementos en XSLT 2



xpath salto de linea (1)

Tengo una serie de etiquetas P en contenido XML que tienen una jerarquía semántica dentro de sus valores iniciales, sin embargo, las etiquetas P son lineales. Buscando la transformación XSLT 2.

La jerarquía semántica es la siguiente:

(1) +-(a) +-(I) +-(A)

Con la secuencia de RegEx de la siguiente manera:

<xsl:param name="patternOrder" as="element(pattern)*" xmlns=""> <pattern level="1" value="^(/([0-9]+(/.[0-9]+)?/))" /> <pattern level="2" value="^(/([a-z]/))" /> <pattern level="3" value="^(/((IX|IV|V?I{{0,3}})/))" /> <pattern level="4" value="^(/([/w]+(/.[/w]+)?/))" /> </xsl>

Después de revisar mi conjunto de datos, tengo varias condiciones:

<?xml version="1.0" encoding="UTF-8"?> <test> <content> <p>(1) blah</p> <p>(2)(a) blah</p> <p>(b) blah</p> <p>(3)(a)(I) blah</p> <p>(II) blah</p> <p>(A) blah</p> <p>(B.1) blah</p> <p>(b) blah</p> <p>(4) blah</p> <p>(4.5) blah</p> <p>(5)(a)(I)(A) blah</p> <p>(B) blah</p> <p>(II) blah</p> <p>(III)(a) blah</p> <p>(bb.2) blah</p> <p>(6) blah</p> </content> <content> <p>blah</p> </content> <content> <p>blah</p> <p>(1) blah</p> <p>(a) blah</p> <p>(b) blah</p> <p>(2) blah </p> </content> </test>

... y los resultados finales deberían ser:

<?xml version="1.0" encoding="UTF-8"?> <test> <content> <p>(1) blah</p> <p>(2) <p>(a) blah</p> <p>(b) blah</p> </p> <p>(3) <p>(a) <p>(I) blah</p> <p>(II) blah <p>(A) blah</p> <p>(B) blah</p> </p> </p> <p>(b) blah</p> </p> <p>(4) blah</p> <p>(4.5) blah</p> <p>(5) <p>(a) <p>(I) <p>(A) blah</p> <p>(B.1) blah</p> </p> <p>(II) blah</p> <p>(III)</p> <p>(a) blah</p> <p>(bb.2) blah</p> </p> </p> <p>(6) blah</p> </content> <content> blah </content> <content> blah <p>(1) blah <p>(a) blah</p> <p>(b) blah</p> </p> <p>(2) blah </p> </content> </test>

Tenga en cuenta la condición si la jerarquía semántica no está presente en la etiqueta P; a continuación, se elimina la etiqueta P y es un valor de su elemento de contenido primario.

EDITAR:

Pude detectar todas las condiciones semánticas usando el siguiente RegEx:

^(/(([/w]+(/.[/w]+)?)/)){1,4}

* EDIT # 2 *

Con los atributos de nivelación:

<?xml version="1.0" encoding="UTF-8"?> <test> <content> <p level="1">(1) blah</p> <p level="1">(2)</p> <p level="2">(a) blah</p> <p level="2">(b) blah</p> <p level="1">(3)</p> <p level="2">(a)</p> <p level="3">(I) blah</p> <p level="3">(II) blah</p> <p level="4">(A) blah</p> <p level="4">(B.1) blah</p> <p level="2">(b) blah</p> <p level="1">(4) blah</p> <p level="1">(4.5) blah</p> <p level="1">(5)</p> <p level="2">(a)</p> <p level="3">(I)</p> <p level="4">(A) blah</p> <p level="4">(B) blah</p> <p level="3">(II) blah</p> <p level="3">(III)</p> <p level="2">(a) blah</p> <p level="2">(bb.2) blah</p> <p level="2">(6) blah</p> </content> <content> <p>blah</p> </content> <content> <p>blah</p> <p level="1">(1) blah</p> <p level="2">(a) blah</p> <p level="2">(b) blah</p> <p level="1">(2) blah </p> </content> </test>


Primera fase: transformar

<p>(2)(a) blah</p> <p>(b) blah</p>

dentro

<p>(2)</p> <p>(a) blah</p> <p>(b) blah</p>

usando algo como

<xsl:template match="p"> <xsl:for-each select="tokenize(., ''/('')"> <xsl:if test="normalize-space(.)"> <p>(<xsl:value-of select="."/></p> </xsl:if> </xsl:for-each> </xsl:template>

Segunda fase:

Primero escribe una función

<xsl:function name="f:level" as="xs:integer"> <xsl:param name="p" as="element(p)"/> .... </xsl:function>

que calcula el "nivel semántico" basado en la coincidencia de sus expresiones regulares. Parece que sabes cómo hacer esta parte.

Luego, escribe una función de agrupación recursiva:

<xsl:function name="f:group" as="element(p )*"> <xsl:param name="in" as="element(p )*"/> <xsl:param name="level" as="xs:integer"/> <xsl:for-each-group select="$in" group-starting-with="p[f:level(.)=$level]"> <p><xsl:value-of select="current-group()[1]"/> <xsl:sequence select="f:group(current-group()[position() gt 1], $level+1)"/> </p> </xsl:for-each-group> </xsl:function>

y llame a esta función de esta manera:

<xsl:template match="content"> <xsl:sequence select="f:group(p, 1)"/> </xsl:template>

No probado.