2011-05-12 7 views
5

dentro de un bucle foreach i desea utilizar-hermano anterior ::XSLT tipo en conjunción con-hermano anterior ::

<for-each..> 
    <xsl:sort select="type"/> 
    <xsl:when test="preceding-sibling::data[1]/type != type 

el problema es que "tipo" dentro del foreach se compara con un preceding- sin clasificar hermano por ej.

data1/type = 1 
data2/type = 2 
data3/type = 1 

sería comparar en el segundo silbling loop = 2 (original sin clasificar) y tipo = 1 (ya que está ordenada)

hay una manera alrededor de ella?

ACTUALIZACIÓN: mi intención es la siguiente

before    after 
data/type2   type1 value1 
data/type1   type1 value2 
data/type1   and speaking in HTML a spacer here (I compare type2:value to preceding-sibling value 
data/type2   type2 value1 
        type2 value2 

que tienen una lista desordenada de las direcciones donde el tipo es un pueblo y necesito una tabla HTML ordenado por la ciudad y hacer algunas cosas en función de los valores y otros campos (esa parte funciona, pero como la comparación con el hermano anterior no está funcionando en una ordenada para cada uno, tuve el problema

Respuesta

1

¿Está tratando de agrupar los elementos de datos por tipo? Háganos saber lo que está tratando de hacer y probablemente podamos ayudar (como dijo @Michael Kay).

Una opción (en XSLT 2.0 o con la extensión de conjunto de nodos) consiste en ordenar los elementos de datos en una nueva variable, luego ejecute xsl:for-each en el conjunto de nodos en esa nueva variable. Entonces la relación precedente-hermano reflejará el orden ordenado.

+0

Me gustaría ordenar los nodos por datos/tipo y usarlos después.¿Cómo haría una copia ordenada de ese nodo? –

1

Las relaciones de los nodos entre sí: padre, hijo, hermano, etc. no se cambian por clasificación. Puede ver a los empleados por orden de fecha de nacimiento, pero aún tienen los mismos padres, hijos y hermanos que Lo hicieron en el árbol original, porque todavía son nodos en el árbol original.

Has dicho cómo quieres resolver tu problema y no va a funcionar. El siguiente paso es decirnos cuál es el problema.

+0

Esto no proporciona una respuesta a la pregunta. Para criticar o solicitar aclaraciones de un autor, deje un comentario debajo de su publicación. – Dijkgraaf

+0

Yo diría que "su pregunta es incoherente y esta es la razón" es una respuesta. No es una solución al problema del PO, pero es una respuesta a su pregunta. –

0

Como las garantías XSLT que los elementos con claves iguales ordenar aparecerán en el orden del documento, puede reemplazar

<xsl:when test="preceding-sibling::data[1]/type != type"> 

con

<xsl:when test="not(preceding::data/type = type)"> 

para comprobar si el nodo actual es el primer nodo en el documento (y por lo tanto, en el conjunto ordenado) con su tipo. (Tenga en cuenta que estoy usando en lugar de precedingpreceding-sibling, ya que no sé si todos los elementos de datos serán hermanos en el documento original.)

Si el rendimiento es un problema, también se podría utilizar xsl:key. Otra solución es la agrupación (utilizando la agrupación de Muenchian en XSLT 1.0 y xsl:for-each-group en XSLT 2.0).

+0

El reemplazo no funcionó para mí. El primer grupo se genera como se esperaba ('') pero los grupos restantes están duplicados (' 'en lugar del esperado' '). –

4

Esta solución ahora trabaja para mí:

<xsl:variable name="sortedcopy"> 
     <xsl:for-each select="node1/node2/node3/data"> 
     <xsl:sort select="type" order="ascending"/> 
     <xsl:copy-of select="current()"/> 
     </xsl:for-each> 
    </xsl:variable> 
    <xsl:variable name="relItems" select="MSXML:node-set($sortedcopy)" /> 
    <xsl:for-each select="$relItems/data"> 
     <xsl:if test="not(preceding-sibling::data[1]/id = id)"> 
     <hr/> 
     </xsl:if> 
     <xsl:value-of select="val"/> 
    </xsl:for-each> 
+0

Me alegro de que la sugerencia haya ayudado. Creo que, como indicó cada uno de los contestadores, tendrías un mejor rendimiento si usaras las funciones de agrupamiento recomendadas, como Meunchian. – LarsH

+0

[node-set()] (https://msdn.microsoft.com/en-us/library/hz88kef0%28v=vs.110%29.aspx) es una función propietaria y no es parte de [XSL 1.0 estándar] (http://www.w3.org/TR/xslt), entonces esto no será portátil. – vallismortis