[XSLT] node attributen in csv

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • ronjon
  • Registratie: Oktober 2001
  • Laatst online: 24-08 23:00
ik ben bezig om uit een groot xml bestand specifieke informatie te halen dmv XSL voor export naar csv
waar ik nu tegenaanloop is dat ik in mijn export waarden meekrijg die niet ge-exporteerd moeten worden en ook moet ik terugkomende waarden niet dubbel tonen.

de xml:
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
<?xml version="1.0" encoding="utf-8" ?>
<transport titel="vervoer">
    <inleiding naam="inleiding">textinleiding</inleiding>
    <type titel="car">
        <brand titel="volvo">
            <color titel="kleur">red</color>
        </brand>
    </type>
    <type titel="car">
        <brand titel="volvo">
            <color titel="kleur">green</color>
        </brand>
    </type>
    <type titel="car">
        <brand titel="ford">
            <color titel="kleur">red</color>
        </brand>
    </type>
    <type titel="bike">
        <brand titel="trek">
            <color titel="kleur">blue</color>
        </brand>
    </type>
    <type titel="trike">
        <brand titel="foo" />
    </type>
    <type>
        <brand titel="porsche">
            <color titel="kleur">black</color>
        </brand>
    </type>
    </transport>


de xsl
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
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" indent="no" />
    <xsl:strip-space elements="*" />

    <xsl:template match="/">
        <xsl:apply-templates />
    </xsl:template>
    
    <xsl:template match="transport">
        <xsl:apply-templates />
    </xsl:template>
    
    <xsl:template match="type">
        <xsl:value-of select="@titel"/>
        <xsl:text>,</xsl:text>
        <xsl:apply-templates select="brand" />
        <xsl:text>
</xsl:text>
    </xsl:template>
    
    <xsl:template match="brand">
        <xsl:value-of select="@titel"/>
        <xsl:text>,</xsl:text>
        <xsl:apply-templates select="color" />
    </xsl:template>
    
    <xsl:template match="color">
        <xsl:value-of select="@titel"/>-<xsl:value-of select="."/>
    </xsl:template>
</xsl:stylesheet>


dit geeft als output
textinleiding carvolvokleur-red
carvolvokleur-green
carfordkleur-red
biketrekkleur-blue
trikefoo
porschekleur-black


de output is niet helemaal wat ik nodig heb, de inleiding moet worden overgeslagen en waarden die in de vorige regel al bekend waren moeten niet worden getoond:
carvolvokleur-red
kleur-green
fordkleur-red
biketrekkleur-blue
trikefoo
porschekleur-black


hoe kan ik mijn xsl aanpassen om te zorgen dat mijn output het gewenste format krijgt?

Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Je inleiding wordt niet overgeslagen omdat je vanaf je transport-element alles apply't. Standaard gedrag is dat textnodes doorgepasst worden als je een apply-templates doet op elementen die geen specifiekere template hebben. Als je dus de inleiding wilt overslaan moet je de apply-templates selecteren op type
XML:
1
2
3
<xsl:template match="transport"> 
    <xsl:apply-templates select="type" /> 
</xsl:template>

óf een template maken voor inleiding die niks output.

Voor het negeren van waardes die je eerder voorbij hebt laten komen kun je vergelijken met het vorige 'type' element (binnen je type template) m.b.v. de preceding-sibling axis.

[ Voor 12% gewijzigd door drm op 18-03-2011 15:56 ]

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

  • ronjon
  • Registratie: Oktober 2001
  • Laatst online: 24-08 23:00
drm schreef op vrijdag 18 maart 2011 @ 15:54:
Voor het negeren van waardes die je eerder voorbij hebt laten komen kun je vergelijken met het vorige 'type' element (binnen je type template) m.b.v. de preceding-sibling axis.
hoe maak ik dit vergelijk? ik kan het type element niet als een variabele opslaan, omdat deze statisch blijft?

Acties:
  • 0 Henk 'm!

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06 13:31

drm

f0pc0dert

Je hoeft de waarde toch niet op te slaan om ermee te vergelijken? Stel dat van het tweede en het derde element een waarde hetzelfde is als het eerste, is de derde ook automatisch hetzelfde als de tweede. Je hoeft dus alleen maar met de vorige te vergelijken om te weten of je 'm moet outputten of niet.

Music is the pleasure the human mind experiences from counting without being aware that it is counting
~ Gottfried Leibniz


Acties:
  • 0 Henk 'm!

  • ronjon
  • Registratie: Oktober 2001
  • Laatst online: 24-08 23:00
ik ben 1 stapje verder: het car element wordt niet meer herhaald, maar brand en color dus nog wel :? :

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
<?xml version="1.0" encoding="utf-8" ?>
<transport titel="vervoer">
    <inleiding naam="blaat">blaat </inleiding>
    <type titel="car">
        <brand titel="volvo">
            <color titel="kleur">red</color>
        </brand>
    </type>
    <type titel="car">
        <brand titel="volvo">
            <color titel="kleur">green</color>
        </brand>
    </type>
    <type titel="car">
        <brand titel="ford">
            <color titel="kleur">red</color>
        </brand>
    </type>
    <type titel="bike">
        <brand titel="trek">
            <color titel="kleur">blue</color>
        </brand>
    </type>
    <type titel="bike">
        <brand titel="foo">
            <color titel="kleur">blue</color>
        </brand>
    </type>
    <type titel="plane">
        <brand titel="boeing">
            <color titel="kleur">black</color>
        </brand>
    </type>
    </transport>


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
40
41
42
43
44
45
46
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text" indent="no" />
    <xsl:strip-space elements="*" />

    <xsl:template match="/">
        <xsl:apply-templates />
    </xsl:template>
 
     <xsl:template match="transport">
        <xsl:apply-templates select="type"/>
    </xsl:template>
    
    <xsl:template match="type">
        <xsl:choose>
            <xsl:when test="not(@titel = preceding-sibling::node()/@titel)">
                <xsl:value-of select="@titel"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:text></xsl:text>
            </xsl:otherwise>
        </xsl:choose>
        <xsl:text>,</xsl:text>
        <xsl:apply-templates select="brand" />
        <xsl:text>
</xsl:text>
    </xsl:template>
    
    <xsl:template match="brand">
        <xsl:choose>
            <xsl:when test="not(@titel = preceding-sibling::node()/@titel)">
                <xsl:value-of select="@titel"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:text></xsl:text>
            </xsl:otherwise>
        </xsl:choose>
        <xsl:text>,</xsl:text>
        <xsl:apply-templates select="color" />
    </xsl:template>
    
    <xsl:template match="color">
        <xsl:value-of select="@titel"/>-<xsl:value-of select="."/>
    </xsl:template>
    <xsl:template match="inleiding" />
</xsl:stylesheet>\


met als resultaat
carvolvokleur-red
volvokleur-green
fordkleur-red
biketrekkleur-blue
fookleur-blue
planeboeingkleur-black

Acties:
  • 0 Henk 'm!

  • foliant
  • Registratie: Juli 2007
  • Laatst online: 19-01-2022
Dit lijkt een mooi voorbeeld om de for-each-group van XSLT 2 te gebruiken:

Kan uit je post echter niet opmaken of je een processor gebruikt die XSLT 2 ondersteunt.
Zo niet, dan moet je even verder puzzelen met hetgeen je totnogtoe hebt...
(Hint: Voor de brand nodes is preceding-sibling niet voldoende, je hebt iets meer navigatie nodig.)

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
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

  <xsl:output method="text"/>

  <xsl:template match="/">
   <xsl:apply-templates/>
  </xsl:template>
    
  <xsl:template match="transport">
    <!-- groepeer op titel -->
    <xsl:for-each-group select="type" group-adjacent="@titel">
      <xsl:value-of select="current-grouping-key()"/>
      <!-- en vervolgens op merk-->
      <xsl:for-each-group select="current-group()" group-by="brand/@titel">
        <xsl:for-each select="current-group()">
      <xsl:choose>
        <xsl:when test="position()=1">
          <xsl:text>,</xsl:text><xsl:value-of select="current-grouping-key()"/>
        </xsl:when>
        <xsl:otherwise><xsl:text>,</xsl:text></xsl:otherwise>
      </xsl:choose>
      <xsl:text>,</xsl:text>
          <xsl:value-of select="brand/color/@titel"/><xsl:text>-</xsl:text><xsl:value-of select="brand/color"/>
      <xsl:text>
</xsl:text>
    </xsl:for-each>
      </xsl:for-each-group>
    </xsl:for-each-group>
  </xsl:template>

</xsl:stylesheet>
Pagina: 1