xsl:apply templates klappt nicht
szsoftware
- xsl
0 Skeeve0 Thomas J.S.
Hallo liebe Gemeinde,
ich doktore schon ne Weile am folgenden Problem rum:
Ich habe eine xml-Datei mit Daten. Die Struktur ist so:
<root>
<toc>
<top id="1">
<ueberschrift>Top 1</ueberschrift>
</top>
<top id="2">
<ueberschrift>Top 2</ueberschrift>
</top>
</toc>
<data>
<top id="1">
Bla Fasel <div>hervorgehoben</div> <span>sonstwas</span>
<ul>
<li>Foo</li>
<li>Bar</li>
</ul>
Ende der Beispieldaten
</top>
<top id="2">
Daten des Topic 2
</top>
</data>
</root>
Nun habe ich eine XSL-Datei die in etwa so funktioniert:
<xsl:template match="/">
<html>
<head>
<title>Foobar</title>
</head>
<body>
<xsl:foreach select="/root/toc/top">
<!-- hier ist eigentlich noch ein xsl:sort -->
<xsl:value-of select="ueberschrift" />
</xsl:foreach>
<hr noshade>
<xsl:foreach select="/root/toc/top">
<!-- hier ist eigentlich noch ein xsl:sort -->
<!-- Das mache ich hier so, damit die Reihenfolge der Daten mit dem TOC
korreliert-->
<xsl:variable name="id" select="@id" />
<xsl:value-of select="/protokoll/data/top[@id=$id]" />
<!-- wie kann jetzt das ul-, li-, div- oder span-Tag formatiert werden, das in der xml in der entsprechenden Data-Sektion vorhanden ist? -->
</xsl:foreach>
</body>
</html>
</xsl:template>
<xsl:template match="*">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="div">
<span style="border:1px solid red"><xsl:value-of select="."/></span>
</xsl:template>
Also, ich denke vielleicht, dass ich die Logik der ganzen Sache nicht so richtig gewählt habe. Vielleicht genügt ja aber doch nur ne kleine Änderung.
Über Eure Hilfe würde ich mich sehr freuen.
Ach ja, die Originaldatei ist eine xsl:fo Formatierung. Ich habe hier eine einfache HTML-Transformation gewählt.
CU,
Sven
Moin!
<xsl:template match="/">
<html>
<head>
<title>Foobar</title>
</head><body>
<xsl:foreach select="/root/toc/top">
select="toc/toop" sollte schon reichen, da Du ja bereits in root bist.
<!-- hier ist eigentlich noch ein xsl:sort -->
<xsl:value-of select="ueberschrift" />
</xsl:foreach><hr noshade>
<xsl:foreach select="/root/toc/top">
und wieder.
<!-- hier ist eigentlich noch ein xsl:sort -->
<!-- Das mache ich hier so, damit die Reihenfolge der Daten mit dem TOC
korreliert-->
<xsl:variable name="id" select="@id" />
<xsl:value-of select="/protokoll/data/top[@id=$id]" />
/protokoll existiert nicht. select="data/top[...
Anmerkung: Du solltest Deine XML-Daten umstellen. Die Überschrift packst Du am Besten zu den Daten. Damit sparst Du Dir das zusammenführen über die @id.
-- Skeeve
Hi Skeeve,
select="toc/toop" sollte schon reichen, da Du ja bereits in root
ja, ich glaube ich wollte nur ausschließen, dass ich mich mit den Pfaden vertue, weil was anderes nicht geklappt hat. Da bin ich zur Sicherheit auf absolut gegangen.
/protokoll existiert nicht. select="data/top[...
Tja, copy-and-paste wenn man sich schnell ein vereinfachtest Beispiel zusammenklickt
Anmerkung: Du solltest Deine XML-Daten umstellen. Die Überschrift packst Du am Besten zu den Daten. Damit sparst Du Dir das zusammenführen über die @id.
Stimmt, für die Vereinfachung der xsl schon. Ich wollte aber die Datengrundlage strukturell der Transformation anpassen. D.h. wenn ich eine protokoll.xml schreibe, dann soll man oben schon schnell einen Überblick über die Topics haben. Bzw. wenn ich eine Protokoll-XML mal schnell from-scratch schreibe, fängt das bei uns immer erst mal mit der Zusammenstellung der Tops an.
Danke soweit und CU,
Sven
hallo,
ich doktore schon ne Weile am folgenden Problem rum:
Nun habe ich eine XSL-Datei die in etwa so funktioniert:<hr noshade>
korrekt wäre:<hr noshade="noshade">
<xsl:foreach select="/root/toc/top">
<!-- hier ist eigentlich noch ein xsl:sort -->
<!-- Das mache ich hier so, damit die Reihenfolge der Daten mit dem TOC
korreliert-->
<xsl:variable name="id" select="@id" />
das kommt mir bekannt vor, wenn ich mich recht erinnere habe ich dir schon damals den Tipp gegeben:
<xsl:copy-of select="/protokoll/data/top[@id=$id]//child::node()" />
<!-- wie kann jetzt das ul-, li-, div- oder span-Tag formatiert werden, das in der xml in der entsprechenden Data-Sektion vorhanden ist? -->
</xsl:foreach>
</body>
</html>
</xsl:template>
<xsl:template match="*">
<xsl:apply-templates />
</xsl:template>
das ist relativ nutzlos, es bildet nur das Verhalten des build-in-Templates für Elemente nach.
<xsl:template match="div">
<span style="border:1px solid red"><xsl:value-of select="."/></span>
</xsl:template>
Das sollte über CSS passieren.
Grüße
Thomas
Hi Thomas,
danke für Deine Hilfe.
Ja ich kann mich erinnern, dass Du mal copy-of empfohlen hast, statt value-of. Ich glaub, durch die ganze Probiererei ist mir das wieder entfallen.
Ich füge jetzt mal die lauffähige xsl ein. Immerhin werden mir die html-Tags jetzt in der transformierten xml, sprich in der html angezeigt. Wie aber wende ich darauf die templates an?
Und was bedeutet das child::node()? Denn soweit geht das ja auch ohne.
Ach ja, manche Formatierschritte, die mit CSS gemacht werden sollten sind nur dämliche Beispiele, weil das Problem eigentlich bei einer fo-Transformation besteht, die ist nur zu komplex, für das kleine Problem.
Also, hier der nächste Anlauf und vielen Dank schonmal und nochmal :-) :
<?xml version = '1.0' encoding = 'utf-8' standalone = 'no'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" >
<xsl:template match="/">
<html>
<head>
<title>Foobar</title>
</head>
<body>
<xsl:for-each select="/root/toc/top">
<!-- hier ist eigentlich noch ein xsl:sort -->
<xsl:value-of select="ueberschrift" /><br />
</xsl:for-each>
<hr noshade="noshade" />
<xsl:for-each select="/root/toc/top">
<!-- hier ist eigentlich noch ein xsl:sort -->
<!-- Das mache ich hier so, damit die Reihenfolge der Daten mit dem TOC
korreliert-->
<xsl:variable name="id" select="@id" />
<p>
<!-- <xsl:value-of select="/root/data/top[@id=$id]" /> -->
<xsl:copy-of select="/root/data/top[@id=$id]" />
<!-- offensichtlich wird das match-div-template garnicht erreicht, welches unten definiert ist,
muss ich hier apply-templates einbauen und wenn ja, wie? -->
</p>
</xsl:for-each>
</body>
</html>
</xsl:template>
<xsl:template match="div">
<span style="border:1px solid red"><xsl:value-of select="."/></span>
</xsl:template>
</xsl:stylesheet>
Hallo,
danke für Deine Hilfe.
Ja ich kann mich erinnern, dass Du mal copy-of empfohlen hast, statt value-of. Ich glaub, durch die ganze Probiererei ist mir das wieder entfallen.Ich füge jetzt mal die lauffähige xsl ein. Immerhin werden mir die html-Tags jetzt in der transformierten xml, sprich in der html angezeigt. Wie aber wende ich darauf die templates an?
Und was bedeutet das child::node()?
Dass nur die Kind-Knoten vom <top> kopiert werden, weil ...
Denn soweit geht das ja auch ohne.
... du in diesem Fall auch das entsprchende <top>-Element kopierst, d.h. im HTML hast du es dann auch drinn.
Ach ja, manche Formatierschritte, die mit CSS gemacht werden sollten sind nur dämliche Beispiele, weil das Problem eigentlich bei einer fo-Transformation besteht, die ist nur zu komplex, für das kleine Problem.
Also, hier der nächste Anlauf und vielen Dank schonmal und nochmal :-) :
<xsl:for-each select="/root/toc/top">
<!-- hier ist eigentlich noch ein xsl:sort -->
<!-- Das mache ich hier so, damit die Reihenfolge der Daten mit dem TOC
korreliert-->
<xsl:variable name="id" select="@id" />
<p>
<!-- <xsl:value-of select="/root/data/top[@id=$id]" /> -->
<xsl:copy-of select="/root/data/top[@id=$id]" />
<!-- offensichtlich wird das match-div-template garnicht erreicht, welches unten definiert ist,
muss ich hier apply-templates einbauen und wenn ja, wie? -->
</p>
Deshalb habe ich gesagt, dass diese Formatirung über CSS erfolgen soll. Wenn du apply-templates verwenden möchtest, muss du für die HTML-Elemente entsprechende Templates schreiben und auf copy-of verzichten.
Also:
<xsl:template match="div">
...
</xsl:template>
<xsl:template match="ul">
<ul>
<xsl:for-each select="li">
<li>
<xsl:apply-templates />
...
</xsl:template>
etc.
Grüße
Thomas