[XSLT] Raar opgezette XML transformeren

Pagina: 1
Acties:

  • Rickets
  • Registratie: Augustus 2001
  • Niet online

Rickets

Finger and a shift

Topicstarter
Ik heb hier een vreselijk mooi XML-bestandje dat een representatie is van
een RichText-veld. Dit wil ik transformeren naar HTML.
Affijn, ik heb even een voorbeeld gemaakt.
In het RichText-veld staat een lijstje, een regel tekst en nog een lijstje (zie screenshot hieronder).
Afbeeldingslocatie: http://www.joeteren.nl/etc/got/richtext.gif
De relevante XML-uitvoer ziet er dan zo uit (het is misschien wat lang, maar wel belangrijk bij het weergeven van het probleem):

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
47
48
49
50
51
52
53
54
55
<richtext>
    <pardef id='2' leftmargin='1.2500in' list='bullet'/>
    <par def='2'>
        <run>
            <font style='bold' color='red'/>
            List-item 1
        </run>
    </par>
    <par>
        <run>
            <font style='bold' color='red'/>
            List-item 2
        </run>
    </par>
    <par>
        <run>
            <font style='bold' color='red'/>
            List-item 3
        </run>
    </par>
    <pardef id='3' leftmargin='1in'/>
    <par def='3'>
        <run>
            <font style='bold' color='red'/>
        </run>
    </par>
    <par>
        <run>
            <font style='bold' color='red'/>
        </run>
    </par>
    <par>
        <run>
            <font style='bold' color='red'/>
            melp
        </run>
    </par>
    <par>
        <run>
            <font style='bold' color='red'/>
        </run>
    </par>
    <par def='2'>
        <run>
            <font style='bold' color='red'/>
            List-item 1
        </run>
    </par>
    <par>
        <run>
            <font style='bold' color='red'/>
            List-item 2
        </run>
    </par>
</richtext>


Even wat uitleg erbij. Als eerste wordt een pardef gedefinieerd als een lijst (dmv list='bullets'), met het id 2. Hierna volgen er een aantal par elementen. Iedere sibling van een pardef hoort bij diezelfde pardef (het lijstje), totdat er een nieuwe pardef gedefinieerd wordt. Het lijstje wordt onderbroken door een nieuwe pardef, die de regel tekst + wat enters voorstelt.
Op regel 43 begint het 2e lijstje. Dit is te zien doordat er verwezen wordt naar de pardef met het id 2.

Zoals te zien is, is er tussen het 1e list-item en de pardef een relatie middels het def-attribute.
Echter, tussen de overige list-items en de bijbehorende pardef is er geen enkele relatie, behalve dat het een sibling is.
Tot zover de uitleg van de brakke XML :P

Het lukt me nog wel om het eerste lijstje in HTML te krijgen, door middel van de volgende XSLT:
XSLT:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<xsl:template match="richtext">     
    <xsl:for-each select="*">
        <xsl:choose>
            <xsl:when test="name()='pardef' and @list='bullet'">
                <xsl:variable name="id" select="@id" />
                <ul>
                    <xsl:for-each select="following-sibling::
par[preceding-sibling::pardef[position()=1 and @id=$id]]">
                        <li><xsl:value-of select="run" /></li>
                    </xsl:for-each>
                </ul>
            </xsl:when>
        </xsl:choose>
    </xsl:for-each>
</xsl:template>

Misschien is mijn gedachtengang verkeerd (en de XSLT is misschien wat omslachtig), maar met deze opzet zie ik geen manier om het 2e lijstje om te zetten naar HTML.
Dat is dus mijn vraag: hoe kan ik met XSLT de XML van het 2e lijstje omzetten naar een HTML-lijst?

Even een toevoeging, ik heb geen invloed op de XML, die komt van Notes :+

[ Voor 53% gewijzigd door Rickets op 14-01-2004 21:15 ]

If some cunt can fuck something up, that cunt will pick the worst possible time to fucking fuck it up, because that cunt’s a cunt.


  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
heb je al een oplossing? ik heb een tijdje lopen pielen maar ik kom er niet uit...

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Ik heb wel een idee voor een opzet. Ik denk dat je de par met een def attribuut (verder par@def genoemd) moet gaan ransformeren. In die par met def kan je de pardef bereiken via een simpele xpath expressie (zonder bijzonder axes). Ook kan je de pars selecteren die na deze par@def komen, door te kijken of de eerste par@def gelijk is aan je huidige par@def.

Blog, Stratego/XT: Program Transformation, SDF: Syntax Definition, Nix: Software Deployment


  • Genoil
  • Registratie: Maart 2000
  • Laatst online: 12-11-2023
mbravenboer schreef op 15 januari 2004 @ 09:15:
Ik heb wel een idee voor een opzet. Ik denk dat je de par met een def attribuut (verder par@def genoemd) moet gaan ransformeren. In die par met def kan je de pardef bereiken via een simpele xpath expressie (zonder bijzonder axes).
zover was ik idd...
Ook kan je de pars selecteren die na deze par@def komen, door te kijken of de eerste par@def gelijk is aan je huidige par@def.
dit had ik ook bedacht, maar heb nog niet kunnen bedenken hoe je net zolang door par's moet itereren totdat je er 1 tegenkomt die een nieuwe def heeft...

heb het sheet hier helaas ff niet bij de hand...

  • bramseltje
  • Registratie: September 2001
  • Laatst online: 23-05 10:13
Zou je niet iets met <xsl-if test="test"> kunnen doen?

Bijvoorbeeld met for-each door elke pardef lopen, en dan met een tweede for-each in combinatie met een xsl-if alle andere nodes testen op de id?

zoiets dus:
code:
1
2
3
4
5
6
7
<xsl:for-each select="richtext/pardef">
    <xsl:for-each select="richtext/par">
          <xsl:if test="par/@def = pardef/@ID">
                <xsl:value-of select="@run" />
          </xsl:if>
    </xsl:for-each>
</xsl:for-each>


Het is misschien een beetje bruteforce oplossing, maar het zou ongeveer moeten kunnen werken...

  • Rickets
  • Registratie: Augustus 2001
  • Niet online

Rickets

Finger and a shift

Topicstarter
Bramseltje schreef op 15 januari 2004 @ 09:54:
Zou je niet iets met <xsl-if test="test"> kunnen doen?

Bijvoorbeeld met for-each door elke pardef lopen, en dan met een tweede for-each in combinatie met een xsl-if alle andere nodes testen op de id?
Ik denk dat dat niet gaat werken, want niet iedere par heeft een def.

Ik ben nu aan met het idee van mbravenboer bezig, met name dit stuk:
Ook kan je de pars selecteren die na deze par@def komen, door te kijken of de eerste par@def gelijk is aan je huidige par@def.

[ Voor 37% gewijzigd door Rickets op 15-01-2004 10:31 ]

If some cunt can fuck something up, that cunt will pick the worst possible time to fucking fuck it up, because that cunt’s a cunt.


  • djc
  • Registratie: December 2001
  • Laatst online: 08-09-2025

djc

Ik heb een werkende, maar hijs wel leluq. Gevalletje van GIGO.

Rustacean


  • Rickets
  • Registratie: Augustus 2001
  • Niet online

Rickets

Finger and a shift

Topicstarter
Manuzhai schreef op 15 januari 2004 @ 12:53:
Ik heb een werkende, maar hijs wel leluq. Gevalletje van GIGO.
Bedankt, ik zal er eens mee spelen :)
Ik heb zelf ook nog wat gemaakt. Er zit nog wel een foutje in, er komt een item teveel in het eerste lijstje.

[edit]
Ik weet in middels dat het komt omdat het 2e en opvolgende items van het laatste lijstje vallen onder de voorwaarde van het laatste if-statement. Hoe zorg ik ervoor dat alleen hij alleen de items pakt die bij dat lijstje horen, dus de items tot de eerstvolgende pardef?

XSLT:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<xsl:variable name="bullet" select="//*/pardef[@list='bullet']/@id" />

<xsl:template match="richtext">
    <xsl:apply-templates select="par[@def]" />      
</xsl:template>

<xsl:template match="par[@def]">
    <xsl:if test="@def=$bullet">        
        <ul>
            <li><xsl:value-of select="run" /></li>
            <xsl:apply-templates select="following-sibling::par[not(@def)]" />
        </ul>
    </xsl:if>
</xsl:template>
    
<xsl:template match="par[not(@def)]">
    <xsl:if test="preceding-sibling::par[@def][position()=1 and @def=$bullet]">     
        <li><xsl:value-of select="run" /></li>
    </xsl:if>
</xsl:template>

[ Voor 116% gewijzigd door Rickets op 15-01-2004 16:49 ]

If some cunt can fuck something up, that cunt will pick the worst possible time to fucking fuck it up, because that cunt’s a cunt.

Pagina: 1