2009-12-18 10 views
5

Dado el siguiente código XML:Realización de un "Grupo A" en la consulta XPath XSL

<results name="queryResults"> 
    <int name="intfield1:[* TO 10]">11</int> 
    <int name="intfield2:[10 TO 20]">9</int> 
    <int name="intfield1:[10 TO 20]">12</int> 
</results> 

me gustaría producir este XML:

<results> 
    <field name="numberfield1"> 
     <value name="[* TO 10]">11</value> 
     <value name="[10 TO 10]">12</value> 
    </field> 
    <field name="numberfield2"> 
     <value name="[10 TO 20]">9</value> 
    </field> 
</results> 

no se me ocurre cómo hacer esto en XSL principalmente porque estoy queriendo por el grupo numbericfield .. Todo lo que puedo llegar a es la siguiente:

<xsl:if test="count(results/int) &gt; 0"> 
    <results> 
    <xsl:for-each select="results/int"> 
     <field> 
      <xsl:attribute name="name"> 
       <xsl:value-of select="substring-before(@name, ':')"/></xsl:attribute> 
      <value> 
       <xsl:attribute name="name"> 
        <xsl:value-of select="substring-after(@name, ':') "/> 
       </xsl:attribute> 
       <xsl:value-of select="."/> 
      </value> 
     </field> 
    </xsl:for-each> 
    </results> 
</xsl:if> 

sin embargo, esto no produce el buen grupo lista ed vez me sale esto:

<results> 
    <field name="numberfield1"> 
     <value name="[* TO 10]">11</value> 
    </field> 
    <field name="numberfield2"> 
     <value name="[10 TO 20]">9</value> 
    </field> 
    <field name="numberfield1"> 
     <value name="[10 TO 10]">12</value> 
    </field> 
</results> 

Si alguien me puede stear en la dirección correcta .. Eso sería genial?

Gracias

Respuesta

11

Para hacer esto en XSLT 1.0, tendrá que utilizar una técnica llamada "muenchian grouping". En primer lugar crear una clave de los nodos en los que se desea agrupar

<xsl:key name="intfield" match="int" use="substring-before(@name, ':')" /> 

A continuación, iterar a través de todos los nodos, pero sólo la selección de los que pasan a ser los primeros en el grupo correspondiente

<xsl:for-each select="int[generate-id() = generate-id(key('intfield', substring-before(@name, ':'))[1])]"> 

a continuación, se puede iterar utilizar la clave para iterar sobre todos los nodos en el grupo

<xsl:variable name="intfieldname" select="substring-before(@name, ':')"/> 
<xsl:for-each select="key('intfield', $intfieldname)"> 

Poniendo todo esto junto da

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:output method="xml"/> 
    <xsl:key name="intfield" match="int" use="substring-before(@name, ':')"/> 
    <xsl:template match="/results"> 
     <results> 
     <xsl:for-each select="int[generate-id() = generate-id(key('intfield', substring-before(@name, ':'))[1])]"> 
      <xsl:variable name="intfieldname" select="substring-before(@name, ':')"/> 
      <field> 
       <xsl:attribute name="name"> 
        <xsl:value-of select="$intfieldname"/> 
       </xsl:attribute> 
       <xsl:for-each select="key('intfield', $intfieldname)"> 
        <value> 
        <xsl:attribute name="name"> 
         <xsl:value-of select="substring-after(@name, ':')"/> 
        </xsl:attribute> 
        <xsl:value-of select="."/> 
        </value> 
       </xsl:for-each> 
      </field> 
     </xsl:for-each> 
     </results> 
    </xsl:template> 
</xsl:stylesheet> 

En su ejemplo, 'intField' se convierte en 'NumberField' sin embargo. He mantenido el nombre como 'intfield' en el ejemplo anterior.

  • error fijo.
+0

Es el hombre .. aplausos .. sólo probado y funciona un convite. Voy a tener que buscar esta cosa "agrupación meunchian", como en el momento en que todo parece como el vudú – CraftyFella

+0

Una pregunta ... ¿Hay una manera de limitar los campos int que crea .. ya que no hay otra lista de los demás int dónde y está trayendo ésos en la tecla intfield? Esperar que tiene sentido – CraftyFella

+1

Sí, en el atributo 'partido' de XSL: clave puede introducir cualquier expresión completa XPath para ser más precisos acerca de lo que los nodos que necesite. Por ejemplo

3

agrupación Muenchian es obra de un genio. No es fácil de entender, pero vea: http://www.jenitennison.com/xslt/grouping/muenchian.html

Para simplificar el proceso, el W3C específicamente admite la agrupación en XSLT2.0. Véase, por ejemplo: http://www.xml.com/pub/a/2003/11/05/tr.html

Sin embargo, no todos los entornos de apoyo XSLT2.0

+0

Utilizando MS .NET por lo que sólo XSL 1.0 para mí .. estás en lo correcto, aunque .. se es una obra de genio ... Daré un enlace a ese enlace. Gracias – CraftyFella

Cuestiones relacionadas