2009-12-18 10 views
5

Dato il seguente codice XML:Esecuzione di un "gruppo da" query in 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> 

Vorrei produrre questo 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> 

non riesco a pensare come fare questo in XSL soprattutto perché sto volendo gruppo per la numbericfield .. Tutto quello che posso venire in mente è questa:

<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> 

Tuttavia, questo non produce il bel gruppo Lista Ed invece ottengo questo:

<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> 

Se qualcuno mi può Stear nella giusta direzione .. Che sarebbe fantastico?

Grazie

risposta

11

Per fare questo in XSLT 1.0, si dovrà utilizzare una tecnica chiamata "muenchian grouping". In primo luogo creare una chiave dei nodi su cui si desidera gruppo

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

Avanti, di eseguire iterazioni attraverso tutti i nodi, ma selezionando solo quelli che si trovano ad essere primi nel girone in questione

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

Successivamente, è possibile iterare usare il tasto per iterare su tutti i nodi nel gruppo

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

Mettendo tutto insieme dà

012.
<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> 

Nel tuo esempio, "intfield" diventa "campo numerico". Ho mantenuto il nome come 'intfield' nell'esempio sopra.

  • errore di battitura fisso.
+0

È l'uomo .. evviva .. appena provato e funziona a meraviglia. Dovrò cercare questa cosa del "gruppo di meunchian" visto che al momento sembra tutto voodoo – CraftyFella

+0

Una domanda ... C'è un modo per limitare i campi int che crea .. come c'è un'altra lista di int's else dove e sta portando quelli nella chiave intfield? Spero che abbia senso – CraftyFella

+1

Sì, nell'attributo 'match' di xsl: key puoi inserire qualsiasi espressione completa di Xpath per essere più preciso su quali nodi richiedi. Ad esempio

3

Il raggruppamento di muenchiani è un'opera geniale. Non è facile da capire, ma vedi: http://www.jenitennison.com/xslt/grouping/muenchian.html

Per semplificare il processo, il W3C supportava specificamente il raggruppamento in XSLT2.0. Vedi, per esempio: http://www.xml.com/pub/a/2003/11/05/tr.html

Tuttavia, non tutti gli ambienti supportano XSLT2.0

+0

Utilizzando MS .NET quindi solo XSL 1.0 per me .. sei corretto però ... è un'opera geniale .. Darò a quel link una lettura. Grazie – CraftyFella

Problemi correlati