Toon posts:

[XSL-T] Transformatie & Stylesheet: Problemen

Pagina: 1
Acties:
  • 216 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
Ik probeer mijn probleem zo duidelijk mogelijk uit te leggen :)

Ik heb een project XML opgekregen met als bedoeling SlideML op te stellen, een taal om eenvoudige slides voor te stellen. Te doen:
1. XML Schema opstellen (done)
2. XSL-T script opstellen om een opgegeven XML-bestand te converteren naar mijn formaat (almost done, klein probleem, zie verder)
3. XSL-T script opstellen dat XML-documenten in mijn formaat converteert naar XHTML met daaraan een CSS-file vast (hopelijk vast)

De problemen:

a) De transformatie van het opgegeven XML-document lukt, tot op één elementje. Normaal bestaan bulletlists uit tekst, links of andere lijsten. In de opgegeven file staat er echter bij drie list items het volgende:

code:
1
2
3
4
5
6
<ul>
       <li>Filter<br/>
             filter out uninteresting items,<br/>
             reduce size of search
       </li>
</ul>


Uiteraard dienen die <br/>-tags voor de opmaak van de tekst en heeft dat niets met de XML-structuur te maken, maar zo denken de parser en mijn XSLT-script er niet over natuurlijk.
Wat ik wil doen is het volgende: <li></li> omzetten naar <listitem></listitem> (dit lukt al) en dan de child nodes ervan omzetten naar <text> en <br/>. Het omzetten van <br/> levert geen problemen op, daar heb ik gewoon een template voor aangemaakt. Het omzetten van die tekst lukt mij echter maar niet, aangezien die in die XML-file niet tussen eigen tags staat. Mijn vraag is nu: wat moet ik hiervoor doen? Ik heb al vanalles geprobeer met <xsl:template select="text()">-dingen maar dat lukt allemaal niet, of genereert foute code.

De code van mijn li-template tot nu toe:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<xsl:template match="li">
    <listitem>
        <xsl:choose>
            <xsl:when test="count(child::*) = 0">
                
                <text><xsl:value-of select="."/></text>
                
            </xsl:when>
            <xsl:otherwise>
                <xsl:apply-templates/>
            </xsl:otherwise>
        </xsl:choose>
    </listitem>
</xsl:template>


(ziehier het volledige script)

2. Het tweede probleem ligt in de opmaak van mijn naar XHTML-getransformeerde documenten. Ik heb een kleine CSS-file opgesteld en een test-document gemaakt en dat werkt perfect (hier te bekijken). Als ik deze in mijn XSLT-script verwerk, negeert het spul mijn stylesheet half (hier te bekijken). Inderdaad, half, vanaf ik een <xsl:apply-templates/> gebruik, wordt mijn stylesheet niet meer gebruikt.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<xsl:template match="/">
    <html>
        <head>
            <title>Multimedia Practicum 2: SlideML</title>
            <link rel="stylesheet" type="text/css" href="slide.css"/>
        </head>
        <body>
            <xsl:apply-templates/>
        </body>
    </html>
</xsl:template>

<xsl:template match="slide">
    <div class="slide">
        <xsl:apply-templates/>
    </div>
</xsl:template>


Wat is hier fout aan?

[ Voor 11% gewijzigd door Verwijderd op 24-11-2004 23:10 ]


  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
Ik heb even zitten spelen met je XML en ben er achter gekomen dat als je in je voorbeeld XML file test.xml het volgende attribuut:
xmlns="http://sloefke.studentenweb.org/xml"
uit het element presentation sloopt, dan doet hij het wel. Ik vermoedt dat je die dus niet nodig hebt.

[ Voor 3% gewijzigd door bigbeng op 25-11-2004 11:01 ]


Verwijderd

Topicstarter
bigbeng schreef op donderdag 25 november 2004 @ 11:01:
Ik heb even zitten spelen met je XML en ben er achter gekomen dat als je in je voorbeeld XML file test.xml het volgende attribuut:
xmlns="http://sloefke.studentenweb.org/xml"
uit het element presentation sloopt, dan doet hij het wel. Ik vermoedt dat je die dus niet nodig hebt.
Alrighty! :)
Dat werkt inderdaad dan, hartelijk bedankt! Mijn referentie naar mijn stylesheet was ook nog gebaseerd op een lokale referentie, hoe dom van mij :)

Nu nog dat eerste probleem ...

  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
Nou heb ik ook je eerste vraag maar eens doorgelezen, ik had hem eerst overgeslagen omdat ik dacht dat het een vrij eenvoudig probleem is. Met w3schools.org erbij ben ik eens gaan kijken hoe eenvoudig het probleem werkelijk is, maar ik vrees dat het niet zo eenvoudig is als ik dacht.

Wat je zou kunnen doen is kijken of mensen al een generieke split functie hebben geschreven voor xsl. Je kunt dat eventueel ook zelf doen. Kijk bij bovenstaande links bij de XSLT tutorial maar eens naar de XPath functies contains en substr. Hiermee zou je zelf een functie kunnen schrijven. Een functie is niets anders dan een named template. Hier kun je ook parameters aan meegeven. Kijk anders eens hier voor een voorbeeld van zo'n template.

Zoals je merkt is mijn niveau op XSL ook nog niet superhoog, gelukkig heb ik meer verstand van programmeren ;)

Verwijderd

Topicstarter
Pfoe, dat klinkt toch vrij ingewikkeld voor een projectje zelfstudie-XML. Nu goed, straks uw voorbeeld eens bezien.

  • hlz
  • Registratie: Juni 2003
  • Laatst online: 26-08-2025

hlz

Zomaar ff snel iets uit m'n hoofd...

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<xsl:template match="li">
    <listitem>
        <xsl:choose>
            <xsl:when test="count(child::*) = 0">
                
                <text><xsl:apply-templates select="node()"/></text>
                
            </xsl:when>
            <xsl:otherwise>
                <xsl:apply-templates/>
            </xsl:otherwise>
        </xsl:choose>
    </listitem>
</xsl:template>

<xsl:template match="text()">
    <xsl:value-of select="."/>
</xsl:template>

<xsl:template match="br">
    <xsl:text>[char voor linebreak]</xsl:text>
</xsl:template>

Tis maar een idee...

<xsl:apply-templates select="."/> ipv <xsl:apply-templates select="node()"/> zou ook moeten werken.. en misschien moet je een beetje met mode="" spelen als er iets anders in je uitvoer wordt gefokked.

[ Voor 20% gewijzigd door hlz op 25-11-2004 17:45 ]


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

djc

Wat code van mij. Misschien is het handig als je wat voorbeeld-output geeft van hoe het moet worden (na XSL-transformatie), dat is nu volgens mij niet helemaal duidelijk.


code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?xml version="1.0"?>
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="xml" indent="yes" encoding="ISO-8859-1" />

    <xsl:template match="/ul">
        <page><xsl:apply-templates select="li" /></page>
    </xsl:template>
    
    <xsl:template match="li">
        <listitem><xsl:apply-templates /></listitem>
    </xsl:template>

    <xsl:template match="text()">
        <text><xsl:value-of select="." /></text>
    </xsl:template>

    <xsl:template match="*">
        <xsl:copy-of select="." />
    </xsl:template>

</xsl:transform>

[ Voor 23% gewijzigd door djc op 25-11-2004 17:45 ]

Rustacean


  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
Verwijderd schreef op donderdag 25 november 2004 @ 17:34:
Pfoe, dat klinkt toch vrij ingewikkeld voor een projectje zelfstudie-XML. Nu goed, straks uw voorbeeld eens bezien.
Valt wel mee hoor, je moet het probleem gewoon algoritmisch benaderen. Waar ik aan dacht is dmv een teller een steeds grotere substring te nemen van de gegeven tekst. Met contains kun je controleren of er een BR tag in voor komt. Zodra dat het geval is neem je de substring tot aan de teller minus de grootte van de BR tag (5 tekens als ik mij niet vergis).
Hierna neem je als beginpunt je laatste eindpunt + 1 en je teller is je nieuwe beginpunt + 1. Weer substringen totdat het een BR tag bevat. Repeat until fade.

Als je dus niks op internet kunt vinden van iemand die deze briljante functie ;) al heeft geschreven, dan kun je met w3schools en wat uithoudingsvermogen een aardig eind komen. Succes!
En als je hem af hebt, dan wil ik die functie ook graag hebben. Altijd goed voor later :P

  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
Ik ben weer eens te programmatisch aan het denken geweest. Ik zag net een ander topic waar ingegaan wordt op variabelen en ik zag dat het toekennen van een nieuwe waarde aan een variabele in XSL niet zo simpel is.

Maar gelukkig voor jou ben ik gelijk op zoek gegaan naar een andere oplossing en jawel, ik heb er een. En hij is nog simpel ook. Je kunt namelijk met substring-before() en substring-after() heel eenvoudig door de string lopen en de teksten rondom de BR tags eruit filteren. Kijk hier maar eens:
http://www.w3schools.com/xpath/xpath_functions.asp

Lang leve luiheid, kom naar... :P (hoezo reclamecampagnes beinvloeden mij)
Nogmaals succes!

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

djc

bigbeng schreef op donderdag 25 november 2004 @ 21:10:
Ik ben weer eens te programmatisch aan het denken geweest. Ik zag net een ander topic waar ingegaan wordt op variabelen en ik zag dat het toekennen van een nieuwe waarde aan een variabele in XSL niet zo simpel is.
Heb je mijn oplossing al bekeken? Het schijnt mij toe dat die simpeler en eleganter is dan jouw voorstellen, ik weet alleen niet zeker of ie hetzelfde doet (maar volgens mij wel).

Rustacean


  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
Ja die heb ik al wel bekeken, maar volgens mij zet jouw oplossing bijvoorbeeld de volgende snippet
code:
1
2
3
4
5
6
7
8
9
...
<li>
    hallo<br/>
    dit<br/>
    is<br/>
   een<br/>
   test
</li>
...

niet om naar

code:
1
2
3
4
5
<listitem>
   <text>hallo</text><br>
   <text>dit</text><br>
  ... etc
</listitem>


Dat is hoe ik het probleem van de TS heb geïnterpreteerd.
Zitten we op een lijn? :)

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

djc

bigbeng schreef op donderdag 25 november 2004 @ 23:14:
code:
1
2
3
4
5
6
7
8
9
...
<li>
    hallo<br/>
    dit<br/>
    is<br/>
   een<br/>
   test
</li>
...
We zitten volgens mij redelijk op een lijn, maar mijn stylesheet maakt dit van jouw voorbeeldje:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="ISO-8859-1"?>
<page>
  <listitem>
    <text>
    hallo</text>
    <br/>
    <text>
    dit</text>
    <br/>
    <text>
    is</text>
    <br/>
    <text>
   een</text>
    <br/>
    <text>
   test
</text>
  </listitem>
</page>


Volgens mij is dat toch wat we bedoelen? Er zit wat extra whitespace in, maar die zit ook in de source (misschien is er een optie die je mee kan geven aan de XSLT processor om die te negeren).

Rustacean


  • bigbeng
  • Registratie: Augustus 2000
  • Laatst online: 26-11-2021
Ik wist wel dat ik niet de XSL parser in mn hoofd moest gebruiken :) Die is nog niet helemaal conform W3C normen :+

Het resultaat is inderdaad wat ik (wij) denk(en) dat de TS wil. De bal ligt nu bij hem.

Verwijderd

Topicstarter
De uitkomst die Manuzhai geeft is inderdaad zoals het zou moeten zijn, direct eens proberen zie :)

[ Voor 5% gewijzigd door Verwijderd op 27-11-2004 11:55 ]


Verwijderd

Topicstarter
Nope, het werkt niet.

Zoals het nu is:

code:
1
2
3
4
5
6
<ul>
       <li>Filter<br/>
             filter out uninteresting items,<br/>
             reduce size of search
       </li>
</ul>


Zoals ik het wil:

code:
1
2
3
4
5
6
7
8
9
<bulletlist>
       <listitem>
             <text>Filter</text>
             <br/>
             <text>filter out uninteresting items,</text>
             <br/>
             <text>reduce size of search</text
       </li>
</ul>


Nu, die code werkt wel gedeeltelijk, ik krijg nu de code voor die bulletlists zoals het zou moeten op die plaats, maar voor de rest staan er nu overal tussen mijn code door van die vieze <text />-tags.

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<presentation>
  <text /> 
- <slide>
  <text /> 
  <title>Visualiseren van Informatie</title> 
  <text /> 
  <text>Auteur:Erik Duval</text> 
  <text /> 
  <text>Departement:Dept. Computerwetenschappen, K.U.Leuven</text> 
  <text /> 
- <link url="http://www.cs.kuleuven.ac.be/~erikd">
  <text>http://www.cs.kuleuven.ac.be/~erikd</text> 
  </link>
  <text /> 
  </slide>
  <text />


-mod-: aha, ik snap het denk ik. Die <text/>-tags staan daar door whitespace, dus ik moet die zien te strippen. Dan zou het moeten werken. Iemand een idee hoe ik dat doe, dus <text>-tags alleen plaatsen als er minstens 1 niet-whitespace character aanwezig is?
NVM: <xsl:strip-space elements="*"/> :)

Nu alleen dit nog:
Ik zit nu nog met een ander probleempje. In mijn XML-files zit ik met <link url="http://">-tags, hoe zet ik die om naar HTML? Ik heb al een template voor die links, maar ik weet niet hoe ik die attribuutwaardes in mijn html-attributen moet krijgen. In dit geval dus <a href="http://"></a>.
<a href="<xsl:value-of select"@url">"> werkt uiteraard niet, < en > en " zijn ongeldige chars, maar als ik die vervang door > enzo, dan krijg ik gewoon die string als url en niet de waarde die die string zou moeten voorstellen.
NVM: fixed! Met <a href="{@url}"> moet het dus. Vind het maar eens snel terug =)

En nóg maar een probleempje:
als ik die XML's getransformeerd heb enzo, moet ik die uiteraard nog valideren tegen mijn XML-schema. Als ik probeer te valideren, geeft mijn editor de error "cvc-elt.1: Cannot find the declaration of element 'presentation'.", dus ik voer dan "xmlns="http://sloefke.studentenweb.org/xml"" in bij mijn referentie naar de XSD, maar als ik dat doe, werkt mijn transformatie naar HTML niet meer omdat dat xmlns-attribuut daar staat. Om lichtjes zot van te worden.
En oh ja, als dat xmlns-attribuut laat toevoegen aan getransformeerde XML's, dan is elke <slide>-tag veranderd naar <slide xmlns="">.

[ Voor 119% gewijzigd door Verwijderd op 27-11-2004 15:13 ]


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

djc

Met namespaces heb ik niet zoveel ervaring, maar volgens mij kan je in je xsl:transform de default xmlns opgeven. Het zou kunnen dat je dan voor de elementen ook moet aangeven dat ze daar in horen (anders weet ie niet in welke ns ze thuishoren).

Rustacean


Verwijderd

Topicstarter
Manuzhai schreef op zaterdag 27 november 2004 @ 16:43:
Met namespaces heb ik niet zoveel ervaring, maar volgens mij kan je in je xsl:transform de default xmlns opgeven. Het zou kunnen dat je dan voor de elementen ook moet aangeven dat ze daar in horen (anders weet ie niet in welke ns ze thuishoren).
Welja, als ik dit doe, dan werkt mijn transformatie naar html maar half meer (de helft van mijn CSS-code wordt gewoon vlakaf genegeerd).
Pagina: 1