xsl transformar regulares recorrer programacion partir manejo expresiones ejemplos crear consultas con como armar xml xslt xslt-1.0

regulares - transformar xml a xslt



XSLT: ¿Cómo encontrar el recuento de hijos únicos de un nodo? (2)

Si todos los niños baz son iguales, entonces doSomething más. doSomething más. Mi nodo actual es foo .

Esto es confuso porque:

  • baz no son hijos de foo ;
  • su título dice " encuentre el recuento de niños únicos ", pero no es necesario encontrarlo para saber si son iguales.

Pruebe algo como:

<xsl:template match="foo"> <xsl:variable name="first-baz" select="(bar/baz)[1]" /> <xsl:choose> <xsl:when test="bar/baz[date!=$first-baz/date or time!=$first-baz/time]"> <!-- THEY ARE NOT ALL SAME --> </xsl:when> <xsl:otherwise> <!-- THEY ARE ALL SAME --> </xsl:otherwise> </xsl:choose> </xsl:template>

Tenga en cuenta que esto supone que cada baz tiene una date y una time . De lo contrario, debe probar not(date=$first-baz/date) etc.

Ver también: http://www.jenitennison.com/xslt/grouping/muenchian.html

Adicional:

Ahora, suponiendo que todos los elementos bar/baz tienen las mismas etiquetas (no necesariamente la date y la time sino que dicen a , b y c ), ¿cuál sería el atributo de prueba para ese caso?

Esto lo hace significativamente más complejo. Aún así puedes construir una clave:

<xsl:key name="first-baz" match="foo/bar[1]/baz[1]/*" use="name()" />

entonces haz tu prueba:

<xsl:when test="bar/baz/*[. != key(''first-baz'', name())]">

Esto devuelve verdadero si existe cualquier hijo de baz cuyo valor de cadena sea diferente de un nodo igualmente nombrado que sea hijo del primer baz .

Tenga en cuenta que la clave, tal como se define aquí, es para todo el documento. Si desea restringir la prueba al antecesor foo actual, debe incluir su identificación en la clave.

Mi XML se ve así:

<foo> <bar name="a"> <baz name="xyz"> <time>2</time> <date>3</date> </baz> </bar> <bar name="b"> <baz name="xyz"> <time>2</time> <date>3</date> </baz> </bar> <bar name="c"> <baz name="xyz"> <time>2</time> <date>3</date> </baz> </bar> </foo>

Estoy escribiendo un XSL que necesita funcionar así: Si todos los niños baz son iguales, entonces doSomething más. Mi nodo actual es foo .

Soy nuevo en XSLT y estoy al tanto de los condicionales en XSL. Se ve algo así a partir de ahora:

<xsl:template match="foo"> <xsl:choose> <xsl:when test="[My condition]"> doSomething() </xsl:when> <xsl:otherwise> doSomethingElse() </xsl:otherwise> </xsl:choose> </xsl:template>

En el ejemplo actual, debería hacer algo doSomething() ya que todos los elementos baz son iguales.

Si descubro la cantidad de elementos baz únicos, puedo probar si es igual a uno. Si es así, entonces haré algo doSomething() else doSomethingElse()

¿Cómo debo implementar esto? ¿Cuál debería ser MyCondition ?

PD: Mi versión XSL es 1.0


Si desea hacer esto de forma genérica, entonces realmente está ampliando la capacidad de XSLT 1.0 más allá de sus límites de diseño. Pero puede hacerse.

Escriba una plantilla con nombre llamada deep-equal que tome dos elementos como sus argumentos y devuelva una cadena que contenga el carácter "F" si y solo si no son iguales (para sus propósitos).

Puede verse así:

<xsl:template name="deep-equal"> <xsl:param name="a"/> <xsl:param name="b"/> <xsl:choose> <xsl:when test="local-name(a) != local-name(b)">F</xsl:when> <xsl:when test="namespace-uri(a) != namespace-uri(b)">F</xsl:when> <xsl:when test="normalize-space(a) != normalize-space(b)">F</xsl:when> <xsl:when test="count(a/*) != count(b/*)">F</xsl:when> <xsl:otherwise> <xsl:variable name="diffs"> <xsl:for-each select="*"> <xsl:variable name="position" select="position()"/> <xsl:call-template name="deep-equal"> <xsl:with-param name="a" select="."/> <xsl:with-param name="b" select="$b/*[$position]"/> </xsl:call-template> </xsl:for-each> </xsl:variable> </xsl:otherwise> </xsl:choose> </xsl:template>

Aplicar esto a todos los pares relevantes de elementos:

<xsl:variable name="comparison"> <xsl:for-each select="baz[position() &gt;= 2]"> <xsl:call-template name="deep-equal"> <xsl:with-param name="a" select="../baz[1]"/> <xsl:with-param name="b" select="."/> </xsl:call-template> </xsl:for-each> </xsl:variable>

Prueba si el resultado contiene una "F":

<xsl:if test="contains($comparison, ''F'')">...</xsl:if>