XML-XSL generieke XLS is dat mogelijk?

Pagina: 1
Acties:

  • paragon
  • Registratie: April 2000
  • Laatst online: 04-09 18:58
Ik wil een XLS toekennen aan XML dat gegenereerd wordt door een java servlet. Alleen zijn de tagnamen m=niet van te voren vast te stellen. Maar de structuur is wel bekend. DIe ziet er zo uit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="UTF-8" ?> 
- <root_tag>
 - <class>
   <attr1>value1</attr1> 
   <attr2>value2</attr2> 
   <..> ... </..> 
   <attrN>valueN</attrN> 
   </class>
 - <class>
   <attr1>value1</attr1> 
   <attr2>value2</attr2> 
   <..> ... </..> 
   <attrN>valueN</attrN> 
   </class>
   enz...
- </root_tag>

Is het dus mogelijk om hieer een XSL voor te maken?

  • HunterPro
  • Registratie: Juni 2001
  • Niet online
De bedoeling van een XSL is gegevens uit je XML op een gedefinieerde manier weergeven. Dus als jij bevoorbeeld een kookboek in XML hebt, dat jij een XSL hebt die het recept van koekjes er uitfiltert, of, nog leuker, alle ingredienten voor een avondvullend voedselprogramma.

Het enige nadeel is: Je moet wel weten wat je wilt gaan uitvoeren. En als je niet weet wat er in je tags gaat zitten, hoe wil je dan in hemelsnaam weten hoe je dat wilt uitvoeren naar de eindgebruiker? Of wil je gewoon de hele XML file weergeven? In dat geval zou ik 'm door een XML-parser heenhalen (zelf te schrijven in, say, Perl oid), en aan de hand daarvan een geschikte XSL genereren die alle data kan bevatten die in de XML voorkomen en dit met jouw opmaak netjes op een pagina dumpt.

Zo? :)

Verwijderd

Op donderdag 20 juni 2002 13:54 schreef |HunterPro| het volgende:
Het enige nadeel is: Je moet wel weten wat je wilt gaan uitvoeren. En als je niet weet wat er in je tags gaat zitten, hoe wil je dan in hemelsnaam weten hoe je dat wilt uitvoeren naar de eindgebruiker?
In dit geval zou je op node-nivo kunnen filteren, volgens mij, omdat je de preciese structuur van de XML kunt voorspellen. Hoe dat moet weet ik trouwens niet :)

Verwijderd

Ik geloof ook niet dat het verstandig is om variabele namen te gebruiken voor je tags, maar ik move dit topic even naar [forum=14], omdat ik denk dat er daar meer mensen zijn die hier verstand van hebben :)

  • brammetje
  • Registratie: Oktober 2000
  • Laatst online: 12-01-2025
zijn die namen belangrijk?? anders kan je ook gewoon <attr id="1"> gebruiken.. of zelfs dat id weglaten..

  • paragon
  • Registratie: April 2000
  • Laatst online: 04-09 18:58
Attr1 - AttrN zijn de colomnamen van een database.

Ik denk niet dat het gaat lukken want het moet gewoon gebeuren aan de hand van een XSL, dus ik kan geen externe parsers gebruiken.

kan er niet zoiets als :
<xsl: select="*"/>
<xsl:value-of select="*"/>

  • brammetje
  • Registratie: Oktober 2000
  • Laatst online: 12-01-2025
doe dan gewoon
code:
1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="UTF-8" ?> 
- <root_tag>
 - <class>
   <column name="kolom1">value1</column> 
   <column name="kolom2">value2</column> 
   <column name="kolomN">valueN</column> 
   </class>
- </root_tag>

dan doe je gewoon
<xsl:template match="column">
<xsl:value-of select="@name"/> heeft waarde <xsl:value-of select="."/>

Verwijderd

Het kan wel mbv xsl, maar brammetjes voorstel is beter m.i.
Wanneer je XML-tree meer takjes gaat krijgen, ben je met deze aanpak de l*l.

Door de eis van generiek zijn van je xsl gaan de stylesheets er heel erg eng uitzien, met nauwelijks ruimte voor aanpassing:
code:
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
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="html"/>
  <xsl:template match="/">
    <html>
      <head>
      </head>
      <body>
      <table border="1">
      <xsl:apply-templates select="/*"/>
      </table>
    </body>
    </html>
  </xsl:template>

  <xsl:template match="/*/*">
      <tr><xsl:apply-templates select="./*"/></tr>
  </xsl:template>

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

</xsl:stylesheet>

  • paragon
  • Registratie: April 2000
  • Laatst online: 04-09 18:58
Ik heb die van brammetje geprobeerd en ik krijg nu alle column names met value, maar alles word in 1 regel getoont ik gebruik de volgende xsl:
code:
1
2
3
4
5
6
7
8
9
10
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:template match="columns">
<html>
<body style="background-color:#e5e5e5;">
<xsl:value-of select="@name"/>
<xsl:value-of select="."/><br />
</body>
</html>
</xsl:template>
</xsl:stylesheet>

Verwijderd

Probeer het eens met een aparte column template:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:template match="/">
  <html>
    <body style="background-color:#e5e5e5;">
    <xsl:apply-templates select="columns"/>
    </body>
  </html>
</xsl:template>

<xsl:template match="columns">
  <xsl:value-of select="@name"/>
  <xsl:value-of select="."/><br />
</xsl:template>

</xsl:stylesheet>

waarom columns in meervoud?

  • paragon
  • Registratie: April 2000
  • Laatst online: 04-09 18:58
Op donderdag 20 juni 2002 18:10 schreef peidor het volgende:
Probeer het eens met een aparte column template:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:template match="/">
  <html>
    <body style="background-color:#e5e5e5;">
    <xsl:apply-templates select="columns"/>
    </body>
  </html>
</xsl:template>

<xsl:template match="columns">
  <xsl:value-of select="@name"/>
  <xsl:value-of select="."/><br />
</xsl:template>

</xsl:stylesheet>

waarom columns in meervoud?
Ja die meervoud is natuurlijk verkeerd kwam dus doordat ik een columns template had gemaakt en daar had ik het fout gespeld en toen copy/paste etc.

Dit topic kan volens mij toch beter in W&G?

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
XSLT is denk ik wel het best op z'n plaats in P&W. Als je het probleem wat je nu nog hebt even omschrijft (geef bijvoorbeeld een input en gewenste output) wil ik er wel even naar kijken, maar ik heb geen zin om een hele beschouwing te schrijven over alle mogelijk structuren die je kunt kiezen, daarom had ik nog niet gereageerd ;) .

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


  • paragon
  • Registratie: April 2000
  • Laatst online: 04-09 18:58
Ok input is bijvoorbeeld zoiets:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="UTF-8" ?> 
- <root_tag>
- <Songs>
  <column name="SongID">0Sx010002</column> 
  <column name="SongTitle">Beat It</column> 
  <column name="SongArtist">Michael Jackson</column> 
  <column name="SongDate">1984</column> 
  </Songs>
- <Songs>
  <column name="SongID">0Sx010003</column> 
  <column name="SongTitle">Thriller</column> 
  <column name="SongArtist">Michael Jackson</column> 
  <column name="SongDate">1984</column> 
  </Songs>
- <Songs>
  <column name="SongID">0Sx010004</column> 
  <column name="SongTitle">BAD</column> 
  <column name="SongArtist">Michael jackson</column> 
  <column name="SongDate">1990</column> 
  </Songs>
  </root_tag>

En dan zou ik als output iets willen dat per SOngs gegroepeerd is. nu heb ik wel een output maar loopt alles aan een stuk door.

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Per Songs :? Bedoel je niet per artiest ofzo? Je hebt nu al keurig alle informatie voor 1 Song in 1 tag, dus wat is dan precies je probleem? Dat is een hele eenvoudige 1 op 1 transformatie en als je daar niet uitkomt kan je misschien toch beter eerst eens een goede XSLT tutorial doornemen. Ik kan wel snel een voorbeeldje maken, maar je leert er meer van als je dat zelf uitvogelt.

Overigens vind ik de XML werkelijk afschuwelijk en zou ik liever dit zien:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<songs>
  <song id="0Sx010002">
    <title>Beat It</title>
    <artist>Michael Jackson</artist>
    <date>1984</date>
  </song>

  <song id="0Sx010003">
    <title>Thriller</title>
    <artist>Michael Jackson</artist>
    <date>1984</date>
  </song>

  <song id="0Sx010004">
    <title>BAD</title>
    <artist>Michael Jackson</artist>
    <date>1990</date>
  </song>
</songs>

Als dat lastig te bereiken is (om wat voor reden dan ook), moet je je probleem verdelen in twee delen: (1) transformatie naar een beschaafde XML structuur en (2) transformatie naar een output. Deze opdeling zorgt ervoor dat de complexiteit laag blijft en je een goede overzicht hebt over je transformatie.

Als je echt aan het groeperen moet zoals in bijvoorbeeld SQL heb je overigens een probleem, want de huidige versie van XSLT is erg slecht in groepering (eigenlijk onmogelijk). In XSLT 2.0 zal daar een hele hoop aan verbeteren en neemt de kracht van XSLT echt enorm toe.

Omschrijf dus nog even wat je wilt, want als je simpelweg elke song in een table row oid wilt is de transformatie echt zo eenvoudig dat je hem makkelijk zelf moet kunnen.

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


  • paragon
  • Registratie: April 2000
  • Laatst online: 04-09 18:58
Ik heb ze nu dus al in een table row, maar ik wil eigenlijk per song een table met dus tagname en value, maar dat gaat dus waarschijnlijkn iet lukken omdat de xml er qua inhoud ook anders uit kan zien, alleen blijft de structuur het zelfde. Die structtur van de XML heb ik niet echt op gelet maar ik zal die even aanpassen, aleen word mijn probleem dan weer wat lastiger denk ik.

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Nou ja, toch nog maar even een voorbeeldje dan ;) .

Dit is voor de XML hierboven:
code:
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
<?xml version="1.0"?>

<xsl:transform version="1.0"
            xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xmlns="http://www.w3.org/1999/xhtml">

  <xsl:output   method="xml" indent="yes" encoding="UTF-8"
      doctype-public="-//W3C//DTD XHTML 1.1//EN"
                doctype-system="http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"/>

  <xsl:template match="/">
    <html>
    <head>
      <title>Songs</title>
    </head>

    <body>
      <xsl:apply-templates select="songs"/>
    </body>
    </html>
  </xsl:template>

  <xsl:template match="/songs">
    <table>
    <thead>
      <tr>
        <th>title</th>
        <th>artist</th>
        <th>year</th>
      </tr>
    </thead>
    <tbody>
      <xsl:apply-templates select="song"/>
    </tbody>
    </table>
  </xsl:template>

  <xsl:template match="song">
    <tr>
    <td>
      <xsl:apply-templates select="title"/>
    </td>
    <td>
      <xsl:apply-templates select="artist"/>
    </td>
    <td>
      <xsl:apply-templates select="date"/>
    </td>
    </tr>
  </xsl:template>
</xsl:transform>

Resultaat:
code:
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
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title>Songs</title>
  </head>
  <body>
    <table>
    <thead>
      <tr>
        <th>title</th>
        <th>artist</th>
        <th>year</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Beat It</td>
        <td>Michael Jackson</td>
        <td>1984</td>
      </tr>
      <tr>
        <td>Thriller</td>
        <td>Michael Jackson</td>
        <td>1984</td>
      </tr>
      <tr>
        <td>BAD</td>
        <td>Michael Jackson</td>
        <td>1990</td>
      </tr>
    </tbody>
    </table>
  </body>
</html>

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


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
paragon: Ik heb ze nu dus al in een table row, maar ik wil eigenlijk per song een table
Per song een table? Das wel vreemd, maar geen probleem: dit is eenvoudig aan te passen in mijn voorbeeld en wellicht ook in jouw werk...
omdat de xml er qua inhoud ook anders uit kan zien, alleen blijft de structuur het zelfde.
Hum, wat bedoel je hiermee? Als de tags vastliggen zoals hierboven in mijn voorbeeld is er geen enkel probleem. Uiteraard mogen daar gewoon andere 'songs' instaan. Als de structuur zelf ook echt kan varieren heb je een groter probleem en moet je daar rekening mee houden.

Heb je al eens naar de XSLT tutorial op http://www.xfront.com gekeken? Dat is erg goed materiaal, waarmee je eigenlijk alles wel op kan lossen :) .

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


  • paragon
  • Registratie: April 2000
  • Laatst online: 04-09 18:58
Het is dus zo dat er een Servlet is aan de hand van deze Servlet wordt er XML gegenereerd vanuit een DataBase. De structuur van de XML blijft dus het zelfde alleen veranderen de tags. Dit is dan ook het probleem. Als de tags bekend zijn was ik er niet over begonnen. Want dan kon ik met een simpele XML+XSL tutorial zoals op w3schools staat wel ver genoeg komen.

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
paragon: Het is dus zo dat er een Servlet is aan de hand van deze Servlet wordt er XML gegenereerd vanuit een DataBase.
Wat is dat voor Servlet dan? Neemt hij een tabel en output hij dat als een soort relationele XML?

In principe is er dan nog geen enkel probleem: je kunt de kolomnamen gebruiken als tags om de velden en de tabelnaam als verzameling van deze velden (records dus). Als dit geen fraai resultaat oplevert haal je er gewoon even een XSLT overheen die wat mooiers oplevert zoals bijvoorbeeld hierboven.
De structuur van de XML blijft dus het zelfde alleen veranderen de tags.
Structuur is tags imho, maar goed ;) .
Als de tags bekend zijn was ik er niet over begonnen.
Uiteindelijk moet je toch kennis hebben over de structuur en de betekenis van elementen als je iets wilt presenteren in XHTML. Als je eigenlijk alleen maar weet dat het een tabel met records is, is dat geen probleem: dan gebruik je dus alleen deze kennis om iets te presenteren. Je kan nooit iets presenteren op een specifieke manier als je er geen kennis over hebt.

Dus bepaal eerst wat alle mogelijk input is, stel desnoods een DTD, XML Schema of Relax NG schema op. Daarna bekijk je hoe je dit wilt presenteren. De stylesheet zelf is in dit hele verhaal eigenlijk slecht een detail wat je met een beetje XSLT kennis zo uit je mouw schud.

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


  • paragon
  • Registratie: April 2000
  • Laatst online: 04-09 18:58
Je hebt helemaal gelij. Ik bedoelde met structuur dat de nesting alsmaar hetzelfde is, maar tags steeds anders bv

-<root_tag>
-<class1>
<class1_id>001</class1_id>
<class1_name>name1</class1_name>
-/class1>
-<class1>
<class1_id>002</class1_id>
<class1_name>name2</class1_name>
-/class1>
-</root-tag>

-<root_tag>
-<class2>
<class2_id>001</class2_id>
<class2_name>name1</class2_name>
<class2_email>b@a.nl</class2_email>
-/class2>
-<class2>
<class2_id>002</class2_id>
<class2_name>name2</class2_name>
<class2_email>b@b.nl</class2_email>
-/class1>
-</root-tag>

  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Ik vind het verschrikkelijk lelijke XML, maar ik zal wel even een voorbeeld maken...

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


  • mbravenboer
  • Registratie: Januari 2000
  • Laatst online: 06-11-2025
Ok, dit is het voorbeeld waar je het mee moet doen. Als je dit niet snapt moet je dieper in XSLT duiken of specifieke servlets gaan schrijven ;) . Ik heb een voorbeeld gemaakt om de XML die je gaf mooier te maken. Je kunt dit voorbeeld makkelijk aanpassen naar een presentatie (XHTML) of als basis van een 2e transformatie zoals ik al eerder beschreef.

Ik heb deze twee inputs:
code:
1
2
3
4
5
6
7
8
9
10
<root_tag>
  <class1>
    <class1_id>001</class1_id>
    <class1_name>name1</class1_name>
  </class1>
  <class1>
    <class1_id>002</class1_id>
    <class1_name>name2</class1_name>
  </class1>
</root_tag>


code:
1
2
3
4
5
6
7
8
9
10
11
12
<root_tag>
  <class2>
    <class2_id>001</class2_id>
    <class2_name>name1</class2_name>
    <class2_email>b@a.nl</class2_email>
  </class2>
  <class2>
    <class2_id>002</class2_id>
    <class2_name>name2</class2_name>
    <class2_email>b@b.nl</class2_email>
  </class2>
</root_tag>

Hier komen dus goed de verschillen naar voren in het aantal fields van een records.

Dan nu de hele enge transformatie:
code:
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"?>

<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output   method="xml" indent="yes" encoding="UTF-8"/>

  <!-- this is the root -->
  <xsl:template match="/">
    <xsl:apply-templates select="*" mode="root"/>
  </xsl:template>

  <!-- this is the root tag -->
  <xsl:template match="*" mode="root">
    <xsl:element name="{name()}">
    <xsl:apply-templates select="*" mode="record"/>
    </xsl:element>
  </xsl:template>

  <!-- this is a record -->
  <xsl:template match="*" mode="record">
    <xsl:element name="{name()}">
    <xsl:apply-templates select="*" mode="field"/>
    </xsl:element>
  </xsl:template>

  <!-- this is a field -->
  <xsl:template match="*[substring-after(name(), concat(name(..), '_')) = 'id']" mode="field">
    <xsl:attribute name="id">
    <xsl:value-of select="text()"/>
    </xsl:attribute>
  </xsl:template>

  <xsl:template match="*" mode="field">
    <xsl:element name="{substring-after(name(), concat(name(..), '_'))}">
    <xsl:value-of select="text()"/>
    </xsl:element>
  </xsl:template>

</xsl:transform>

Merk op hoe ik handig de modes gebruik en hoe ik flink aan het goochelen sla met substrings om mooie XML te krijgen. Ook neem ik het id geval apart omdat ik dat graag als attribuut wil zien.

Resultaat:
code:
1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="UTF-8"?>

<root_tag>
  <class1 id="001">
    <name>name1</name>
  </class1>
  <class1 id="002">
    <name>name2</name>
  </class1>
</root_tag>


code:
1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8"?>

<root_tag>
  <class2 id="001">
    <name>name1</name>
    <email>b@a.nl</email>
  </class2>
  <class2 id="002">
    <name>name2</name>
    <email>b@b.nl</email>
  </class2>
</root_tag>

Niet onaardig he? ;) .

Nu moet je het prima zelf af kunnen maken denk ik.

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


  • paragon
  • Registratie: April 2000
  • Laatst online: 04-09 18:58
Bedankt voor de hulp. Ok dat doen we niet maar ik vond het wel op z'n plaats :)

  • Rense Klinkenberg
  • Registratie: November 2000
  • Laatst online: 09-08 19:19
Het matchen van een template op attr1, attr2, attr3 had trouwens waarschijnlijk wel gekund door gebruik te maken van de starts-with functie van XPath.
Pagina: 1