[XSLT] Group & merge

Pagina: 1
Acties:

  • Deddiekoel
  • Registratie: Maart 2000
  • Laatst online: 12-11 10:27

Deddiekoel

Gadget nerd

Topicstarter
** WAARSCHUWING: XSLT-N00B POST **
Dit is mijn eerste ervaring met XSLT en ik kom er niet uit. Heb hier al redelijk wat topics over gezien maar heb nog geen topic gevonden waarmee mijn group probleem wordt aangepakt.
Ik wil het volgende doen. Ik heb een XML waarin meerdere malen een enkele parent-child tree in zit:
XML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<records>
    <record>
        <key1>123</key1>
        <key2>456</key2>
        <intvalue>1000</intvalue>
        <stringvalue>text1</stringvalue>
        <tobecopied>copy</tobecopied>
    </record>
    <record>
        <key1>234</key1>
        <key2>567</key2>
        <intvalue>5000</intvalue>
        <stringvalue>text2</stringvalue>
        <tobecopied>copy</tobecopied>
    </record>
    <record>
        <key1>123</key1>
        <key2>456</key2>
        <intvalue>1000</intvalue>
        <stringvalue>text3</stringvalue>
        <tobecopied>copy</tobecopied>
    </record>
</records>

Het is nu de bedoeling dat er een zelfde structuur uit komt waarbij wordt gegroepeerd op velden key1 & key2. Daarnaast moeten ook bepaalde int- & stringvelden ook worden samengevoegd en andere gewoon gekopieerd worden.
Uitgaande van de bovenstaande input zou er uit moeten komen:
XML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<records>
    <record>
        <key1>123</key1>
        <key2>456</key2>
        <intvalue>2000</intvalue>
        <stringvalue>text1 + text3</stringvalue>
        <tobecopied>copy</tobecopied>
    </record>
    <record>
        <key1>234</key1>
        <key2>567</key2>
        <intvalue>5000</intvalue>
        <stringvalue>text2</stringvalue>
        <tobecopied>copy</tobecopied>
    </record>
</records>

Het groeperen op zich wil al wel lukken middels de volgende for-each select:
XML:
1
<xsl:for-each select="records/record[not(key1= preceding-sibling::record/key1)][not(key2= preceding-sibling::record/key2)]">

Wat me nu dus nog niet lukt is om inhoud van deze selectie opgeteld te krijgen. Ook moet ik nog testen of bovenstaande group helemaal goed werkt. Ik denk dat ik voor de sum of concat gebruik moet maken van de current key1 & key2 velden, ik weet alleen niet hoe...

Als additionele info, ik wil een dergelijke transform doen vanuit een Java 1.3 applicatie. Ik denk hierom dat ik me moet beperken tot XSLT 1.0...

Verlanglijstje: Switch 2, PS5 Pro Most wanted: Switch 2


  • Deddiekoel
  • Registratie: Maart 2000
  • Laatst online: 12-11 10:27

Deddiekoel

Gadget nerd

Topicstarter
Grrr, ik kom er maar niet uit. Heb verschillende mappingtools gebruikt maar dat helpt voor geen meter...

Verlanglijstje: Switch 2, PS5 Pro Most wanted: Switch 2


Verwijderd

Ga even naar de website van Jeni Tennison en lees het hoofdstuk over de Muenchian method.

  • Deddiekoel
  • Registratie: Maart 2000
  • Laatst online: 12-11 10:27

Deddiekoel

Gadget nerd

Topicstarter
Ik heb die pagina al meerdere keren bekeken en heb hem nu eens geduldig ddorgewerkt en nu werkt het groupen en sum'en iig wel. Nu moet ik nog uitvogelen hoe ik de concat goed krijg... En hoe ik het groupen op meerdere items lekker kan laten werken.

[ Voor 15% gewijzigd door Deddiekoel op 13-11-2006 15:35 ]

Verlanglijstje: Switch 2, PS5 Pro Most wanted: Switch 2


  • Deddiekoel
  • Registratie: Maart 2000
  • Laatst online: 12-11 10:27

Deddiekoel

Gadget nerd

Topicstarter
Ok, ik heb het allemaal bijna werkende. Dit is wat ik tot nu toe heb:
XML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
                xmlns:bpws="http://schemas.xmlsoap.org/ws/2003/03/business-process/"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:ehdr="http://www.oracle.com/XSL/Transform/java/oracle.tip.esb.server.headers.ESBHeaderFunctions"
                xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                exclude-result-prefixes="xsl xsd xp20 bpws ora ehdr orcl ids hwf">
  <xsl:key name="record-by-key1" match="record" use="key1" />
  <xsl:key name="record-by-key2" match="record" use="key2" />
  <xsl:template match="records">
    <records>
        <xsl:apply-templates select="record[generate-id(.) = generate-id(key('record-by-key1', key1)[1])]" />
    </records>
  </xsl:template>
  <xsl:template  match="record">
    <record>
      <intvalue>
        <xsl:value-of select="sum(/records/record[key1 = current()/key1]/intvalue)"/>
      </intvalue>
      <key2>
        <xsl:value-of select="key2"/>
      </key2>
      <stringvalue>
            <xsl:for-each select="/records/record[key1 = current()/key1][not(stringvalue = preceding-sibling::record[key1 = current()/key1]/stringvalue)]">
        <xsl:value-of select="concat(stringvalue, ' + ')"/>
            </xsl:for-each>
      </stringvalue>
      <tobecopied>
        <xsl:value-of select="tobecopied"/>
      </tobecopied>
    </record>
  </xsl:template>
</xsl:stylesheet>

Wat er nu nog ontbreekt is het groupen op key2.
Ook moet ik nog voorzorgen dat bij de string concatenation de "+" op het einde verdwijnt.

[ Voor 4% gewijzigd door Deddiekoel op 14-11-2006 15:19 ]

Verlanglijstje: Switch 2, PS5 Pro Most wanted: Switch 2


  • Deddiekoel
  • Registratie: Maart 2000
  • Laatst online: 12-11 10:27

Deddiekoel

Gadget nerd

Topicstarter
Ok, het opruimen van de concat heb ik gedaan met een choose statement. Hiermee bepaal ik wat de eerste statement is en laat die geen plus hebben. De andere statement krijgen in de concat de + er voor:
XML:
1
2
3
4
5
6
7
8
9
10
11
12
<stringvalue>
    <xsl:for-each select="/records/record[key1 = current()/key1][not(stringvalue = preceding-sibling::record[key1 = current()/key1]/stringvalue)]">
        <xsl:choose>
            <xsl:when test="generate-id(.) = generate-id(key('record-by-key1', key1)[1])">
                <xsl:value-of select="stringvalue"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="concat(' + ', stringvalue)"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:for-each>
</stringvalue>

Rest alleen nog het groupen op meerdere keys

[ Voor 3% gewijzigd door Deddiekoel op 14-11-2006 15:33 ]

Verlanglijstje: Switch 2, PS5 Pro Most wanted: Switch 2


  • Deddiekoel
  • Registratie: Maart 2000
  • Laatst online: 12-11 10:27

Deddiekoel

Gadget nerd

Topicstarter
Ik ben er eindelijk helemaal uit. Door een concat te gebruiken kon ik meerdere velden in de key gebruiken. Bij de sum & concat verder op heb ik daarna wel keys aan de xpath toe moeten voegen. Het resultaat:
XML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="1.0"
                xmlns:bpws="http://schemas.xmlsoap.org/ws/2003/03/business-process/"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:ehdr="http://www.oracle.com/XSL/Transform/java/oracle.tip.esb.server.headers.ESBHeaderFunctions"
                xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                exclude-result-prefixes="xsl xsd xp20 bpws ora ehdr orcl ids hwf">
  <xsl:key name="record-by-key12" match="record" use="concat(key1,'-', key2)" />
  <xsl:template match="records">
    <records>
        <xsl:apply-templates select="record[generate-id(.) = generate-id(key('record-by-key12', concat(key1,'-', key2))[1])]" />
    </records>
  </xsl:template>
  <xsl:template  match="record">
    <record>
      <intvalue>
        <xsl:value-of select="sum(/records/record[key1 = current()/key1][key2 = current()/key2]/intvalue)"/>
      </intvalue>
      <key2>
        <xsl:value-of select="key2"/>
      </key2>
    <stringvalue>
        <xsl:for-each select="/records/record[key1 = current()/key1][key2 = current()/key2][not(stringvalue = preceding-sibling::record[key1 = current()/key1][key2 = current()/key2]/stringvalue)]">
            <xsl:choose>
                <xsl:when test="generate-id(.) = generate-id(key('record-by-key12', concat(key1,'-', key2))[1])">
                    <xsl:value-of select="stringvalue"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="concat(' + ', stringvalue)"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each>
    </stringvalue>
      <tobecopied>
        <xsl:value-of select="tobecopied"/>
      </tobecopied>
    </record>
  </xsl:template>
</xsl:stylesheet>

Zo, dit was een mooi solo-topic maar ben toch blij dat ik er uit ben...

Verlanglijstje: Switch 2, PS5 Pro Most wanted: Switch 2

Pagina: 1