[XSLT] child-tags wel laten zien maar niet parsen

Pagina: 1
Acties:

  • snoopy
  • Registratie: December 2000
  • Laatst online: 08-05 13:36
Ik zit met een probleempje, ik ben bezig met het schrijven van een XSLT-template om postings met XML-code te parsen. Ik wil ook mensen de beschikking geven over een <code/> en een <normal/> tag, maar loop hierbij tegen het probleem aan dat OF de onderliggende tags geparsed worden naar HTML OF dat de onderliggende tags niet weergegeven worden en de content hiervan wel.

Om alles even duidelijker te maken:

XML-bestand (het bericht dus)...
code:
1
2
3
4
<posting>
<code language="BOE!">Dit is da bomb!!!111<br/>
<b>BOE!</b></code>
</posting>


Het gaat er dus om dat de tags binnen de <code>...</code> tag wel weergegeven worden, maar niet geparsed, < en > moeten dus omgezet worden in < en >

XSLT-bestand...
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<xsl:template match="code">
        <blockquote>
                <small><xsl:choose><xsl:when test="string-length(@language) = 0">code: </xsl:when><xsl:otherwise><xsl:value-of select="@language"/>: </xsl:otherwise></xsl:choose></small>
                <hr/>
                        <pre><code><xsl:apply-templates/></code></pre>
                <hr/>
        </blockquote>
</xsl:template>

<xsl:template match="br">
        <br/>
</xsl:template>

<xsl:template match="b|i|u|em|strong">
        <xsl:element name="{name(.)}">
                <xsl:apply-templates/>
        </xsl:element>
</xsl:template>


Hier zie je dus dat de code-tag gebruikt maakt van <xsl:apply-templates/>, die zorgt er dus voor dat alle tags die zich hierin bevinden OOK geparsed worden, maar dit wil ik niet. Maar als ik dan gebruik maak van <xsl:value-of select="."/> wordt wel de content weergegeven, maar niet de tags. Dus ik zou dan als output krijgen:
code:
1
2
3
4
5
<blockquote xmlns="">
<small>BOE!: </small><hr>
<pre><code>Dit is da bomb!!!111

BOE!</code></pre></blockquote>


Ik hoop dat het zo duidelijk is wat ik bedoel.

[ Voor 17% gewijzigd door snoopy op 05-01-2005 08:25 ]


  • snoopy
  • Registratie: December 2000
  • Laatst online: 08-05 13:36
Ik heb het probleem nu na wat zoeken en prutsen getackled, maar ben er nog niet helemaal tevreden over, eventuele suggesties zijn nog steeds welkom...

Ik heb in het XSLT-bestand een template toegevoegd die alle childs van code matcht en ge-escaped weergeeft.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<xsl:template match="code/*">
        <xsl:choose>
            <xsl:when test="name(.) = 'br'">
                <xsl:text>&lt;br /&gt;</xsl:text>
            </xsl:when>
            <xsl:otherwise>
                    <xsl:text>&lt;</xsl:text>
                    <xsl:value-of select="name(.)"/>
                    <xsl:for-each select="@*">
                            <xsl:text> </xsl:text><xsl:value-of select="name(.)"/><xsl:text>="</xsl:text><xsl:value-of select="."/><xsl:text>"</xsl:text>
                    </xsl:for-each>
                            <xsl:text>&gt;</xsl:text><xsl:value-of select="."/>&lt;/<xsl:value-of select="name(.)"/><xsl:text>&gt;</xsl:text>
            </xsl:otherwise>
        </xsl:choose>
</xsl:template>


Het enige probleem is dat als ik in binnen het code-block een <b/> plaats dat mijn code er een <b></b> van maakt. Is niet heel erg, maar is gewoon niet netjes...

[ Voor 58% gewijzigd door snoopy op 05-01-2005 09:44 ]


  • Michali
  • Registratie: Juli 2002
  • Laatst online: 22-03 18:12
<b/> is toch geen geldige HTML tag? Volgens mij zijn de meeste parser zo ingesteld dat ze hier wel rekening mee houden. Als je XSLT 2.0 gebruikt met xhtml als method, dan zorgt ie vanzelf dat tags op een valid manier worden ge-output.

En zo'n choose direct binnen de template vind ik ook niet zo netjes. Je kunt dan beter een extra template toevoegen:

<xsl:template match="code/br">

naast de template die ze allemaal pakt.

[ Voor 32% gewijzigd door Michali op 05-01-2005 12:15 ]

Noushka's Magnificent Dream | Unity


  • snoopy
  • Registratie: December 2000
  • Laatst online: 08-05 13:36
het was even een ideetje, maar de template code/* wil ik eigenlijk niet behouden tenzij het niet anders kan, aangezien deze niet netjes werkt.

Die <b/> hoeft geen geldige HTML-tag te zijn, het gaat erom dat net zoals hier op GoT alle tags binnen een code-block niet geparsed worden. Of het een geldige tag is doet er dus niet toe.

Kleine toevoeging:

De bedoeling is dus dat binnen code-blokken alle <..> of <../> omgezet worden naar &lt;..&gt; of &lt;../&gt; en dus niet geparsed worden.

[ Voor 29% gewijzigd door snoopy op 05-01-2005 12:20 ]


  • Michali
  • Registratie: Juli 2002
  • Laatst online: 22-03 18:12
Je zou dan voor dat soort tags een extra conditie template kunnen toevoegen. Bijvoorbeeld:
code:
1
<xsl:template match="code/*[count(child) = 0 and self::text() = '']">

Maar je hebt dan nog steeds kans dat je ook elementen als <b></b> dan <b/> maakt, wat niet goed is natuurlijk. Even denken nog.

[ Voor 17% gewijzigd door Michali op 05-01-2005 12:32 ]

Noushka's Magnificent Dream | Unity


  • snoopy
  • Registratie: December 2000
  • Laatst online: 08-05 13:36
Zou het mogelijk zijn met behulp van een DTD of een XML-schema aan te geven dat <code>..</code> in zijn geheel als tekst aangemerkt moet worden, aangeven dat het een string betreft o.i.d.

Ik zal zometeen eens XMLSpy installeren en even kijken wat ik ervan kan maken...

  • Michali
  • Registratie: Juli 2002
  • Laatst online: 22-03 18:12
Dat zou mischien kunnen ja, ik weet niet. Volgens mijn moet je dan echt <![CDATA[ ]]> er om heen zetten. Als dat mogelijk is, ben je er snel uit denk ik.

Noushka's Magnificent Dream | Unity


  • snoopy
  • Registratie: December 2000
  • Laatst online: 08-05 13:36
Inderdaad, ik zal er straks even naar kijken. Ik moet even kijken of ik XMLspy nog ergens kan vinden, die kan makkelijk een DTD of XML Schema genereren, dan kan ik er even wat makkelijker een beginnetje mee maken.

Je kan er idd een CDATA element omheen zetten, maar om dat voor elkaar te krijgen moet ik weer aan de gang met PHP, en dat is juist wat ik niet wil, ik wil er zo min mogelijk dingen bij betrekken, het liefst puur XML + XSLT.

Edit:

Niets kunnen vinden helaas, weet niet zo heel veel af van XML DTD's en W3C Schema's. Ik hoop nog steeds op iemand met een goede oplossing...

[ Voor 58% gewijzigd door snoopy op 05-01-2005 14:14 ]


  • Michali
  • Registratie: Juli 2002
  • Laatst online: 22-03 18:12
Ik denk eerlijk gezegd dat er geen andere oplossing is. Je moet toch echt gaan werken met CDATA om aan te geven dat het niet geparsed moet worden, daar is het voor bedoeld. Hoe kom je uberhaubt aan dat stukje XML? Genereer je dat zelf of krijg je het ergens van aangerijkt?

Noushka's Magnificent Dream | Unity


  • .Johnny
  • Registratie: September 2002
  • Laatst online: 19-03 12:22
Wat dacht je van xsl:copy en xsl:copy-of ?
als je dan een template maakt voor "code" en daarin de copy zet zou 't volgens mij moeten werken. Heb 't nu niet getest, maar heb zoiets zelf wel eerder gedaan.

  • drm
  • Registratie: Februari 2001
  • Laatst online: 09-06-2025

drm

f0pc0dert

GIJoke:
Wat dacht je van xsl:copy en xsl:copy-of ?
als je dan een template maakt voor "code" en daarin de copy zet zou 't volgens mij moeten werken. Heb 't nu niet getest, maar heb zoiets zelf wel eerder gedaan.
Dat klopt. Verder lijkt het mij niet onverstandig als de TS zich even inleest in namespaces.

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


  • snoopy
  • Registratie: December 2000
  • Laatst online: 08-05 13:36
Ik zal eens even gaan zoeken en lezen...

Bedankt voor de tips iig.

[ Voor 27% gewijzigd door snoopy op 07-01-2005 11:04 ]

Pagina: 1