Rektal
Here to stay
|
Ich spiele mich gerade mit XSLT herum. Tutorials habe ich zur Hand, nur komme ich trotzdem nicht ganz weiter (und ich will auch nicht vorgeben alles zu verstehen ...). Jedenfalls. XML sieht so aus: <root>
<a>
<b>
<!-- Quasi alle Elemente flat aufgezehlt, wie Hash -->
<key>text..</key>
<value>text...</value>
<key>text..</key>
<value>text...</value>
</b>
<!-- ab hier dann angabe der verschachtelung der obrigen keys -->
<a>
<key>text...</key>
<a>
<key>text...</key>
<key>text...</key>
</a>
</a>
<a>
<key>text...</key>
<a>
<key>text...</key>
<key>text...</key>
<key>text...</key>
</a>
</a>
</a>
</root>
Es werden unter /root/a/b/ zuerst wie in einem hash keys und values definiert. Danach ist unter /root/a/a/ quasi durch verschachtelung eine Baumstruktur definiert, wie die Keys eben verschachtelt sind. Key/Value ist auch zu sehen als Ueberschrift/Inhalt. Grundgedanke ist es, nach HTML zu konvertieren, vorerst einmal reicht es. Es ist kein Problem ein Template zu schreiben das mir die erste Liste der keys und values mit <h1> und <p> usw. umformatiert. Ich moechte aber die Angabe des Baumes, der im XML-Dokument am Ende definiert ist, am Anfang des Dokumentes stellen und (!) verlinken auf den eigentlich Text (key/value == heading/paragraph). Ich hab schon ein Problem, den Baum als solchen in HTML darzustellen (ul, li ist OK), und wie ichs dann verlinke wage ich gar nicht nachzudenken. Hat vielleicht jemand einen kleinen Anstoss fuer mich? XML-Dokument ist vorgegeben, ist ein Apple PLISt format, dazu gibts ein wenig unter http://developer.apple.com/document...oc/uid/20001011 , wobei ich denke das ist hier jetzt nicht wirklich relevant. Soll halt unterstreichen das ich am XML-Inputformat nix aendern kann
Bearbeitet von Rektal am 15.03.2004, 23:56
|
that
ModeratorHoffnungsloser Optimist
|
OK wo ist jetzt die Frage?
|
Rektal
Here to stay
|
OK wo ist jetzt die Frage? Jaja "Submit-klick-warte-mist!-cancel-anpostarbeite-damn-dochschongepostet-oigen-browsersucken"
|
that
ModeratorHoffnungsloser Optimist
|
Aus der Beschreibung kann ich leider nicht genau genug ableiten, was du vor hast. Hast du ein konkretes Input-Dokument und ein Muster, wie du dir die Ausgabe vorstellst?
Lösungsansätze könnten Templates mit verschiedenen Modes sein (einmal fürs Inhaltsverzeichnis und einmal für den Inhalt selbst), sowie die Nutzung von following-sibling für die Inhalte.
Sind die Keys eh eindeutig? Gibt es garantiert nur ein <b> Element?
|
Rektal
Here to stay
|
Following-sibling klingt schon mal gut. Koenntest du mir ein Beispiel-Template schreiben wie ich das verwenden wuerde um nur den zweiten Teil (ab dem zweiten Kommentar) des Dokumentes zu bearbeiten?
Keys sind eindeutig, ja. D.h. ein Key der oben definiert ist, ist unten auch vorhanden, 1:1-Beziehung.
|
that
ModeratorHoffnungsloser Optimist
|
Following-sibling klingt schon mal gut. Koenntest du mir ein Beispiel-Template schreiben wie ich das verwenden wuerde Kann ich gern machen, aber nur wenn ich ein Inputfile hab, mit dem ich testen kann.
|
Rektal
Here to stay
|
<?xml version="1.0" encoding="UTF-8"?>
<root>
<a>
<b>
<key>key 1</key>
<value>value 1</value>
<key>key 2</key>
<value>value 2</value>
</b>
<a>
<key>key 1</key>
<a>
<key>key 2</key>
</a>
</a>
</a>
</root>
Wobei es nicht zufaellig ist, das das 'a' direkt unter Root auch als Nachfolger nach dem '</b>' zu finden ist.
|
that
ModeratorHoffnungsloser Optimist
|
Ich hab da mal schnell was zusammengeschustert... <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="html"/>
<xsl:template match="/">
<html>
<head>
<title>bla</title>
</head>
<body>
<xsl:apply-templates select="/root/a/*[not(ancestor-or-self::b)]" mode="toc"/>
<hr/>
<xsl:apply-templates select="/root/a/b" mode="body"/>
</body>
</html>
</xsl:template>
<xsl:template match="a" mode="toc">
<h3><xsl:value-of select="text()"/></h3>
<ul>
<xsl:apply-templates mode="toc"/>
</ul>
</xsl:template>
<xsl:template match="key" mode="toc">
<li><a href="#{text()}"><xsl:value-of select="text()"/></a></li>
</xsl:template>
<xsl:template match="key" mode="body">
<a name="{text()}"/>
<h3><xsl:value-of select="text()"/></h3>
<p>
<xsl:value-of select="following-sibling::text()"/>
</p>
</xsl:template>
</xsl:stylesheet>
|
Rektal
Here to stay
|
So ein Schuster moecht' ich auch sein ... Ganz funktioniert hats bei mir nicht, aber ich habs weiterbearbeitet und dann zum gewuenschten Ergebnis gebracht. Folgendes ging nicht: - der Inhalt von <p></p> war immer leer - dafuer wurde danach der Inhalt der value-Nodes ausgegeben Mein fix: - value-of-Expression auf select="following-sibling::value[position()=1]" abgeaendert, da laut http://www.w3.org/TR/xpath "following-sibling" mehrere Nodes und nicht eine einzelne zurueckgibt - ein Dummy-Template gebaucht, das die noch nicht verarbeiteten value-Nodes "erledigt", quasi ohne Ausgabe: <xsl:template match="value" mode="body"/> Thx auf alle Faelle, hat mir schwer geholfen einen besseren Einblick zu bekommen. Wenn mir vielleicht noch jemand sagen kann, warum die value-Nodes doppelt ausgegeben werden, obwohl sie ja im Template <xsl:template match="key" mode="body"> verarbeitet werden (vermutlich "gilt" das nicht fuer die value-Nodes und desshalb die Ausgabe?).
|
Rektal
Here to stay
|
|
that
ModeratorHoffnungsloser Optimist
|
Wenn mir vielleicht noch jemand sagen kann, warum die value-Nodes doppelt ausgegeben werden, obwohl sie ja im Template <xsl:template match="key" mode="body"> verarbeitet werden (vermutlich "gilt" das nicht fuer die value-Nodes und desshalb die Ausgabe?). Templates wissen nichts voneinander, außer eine ruft die andere auf. Es ist ja gerade ein Vorteil von XSLT, dass du die gleichen Input-Elemente mit mehreren Templates verarbeiten kannst. Aber es gibt implizite Default-Templates, die einfach nur ihren Textinhalt ausgeben, und die schlagen hier zu (siehe 5.8 Built-in Template Rules). Die vermutlich einfachste Lösung dazu ist, den select-Ausdruck beim apply-templates anzupassen: <xsl:apply-templates select="/root/a/b/key" mode="body"/> Das selektiert nur die Keys, und die Values dazu kriegst du ja vom Key aus mit dem select="following-sibling::value[1]".
|
that
ModeratorHoffnungsloser Optimist
|
|
Rektal
Here to stay
|
Also so gelernt wie's heutzutage sein sollte Vier Jahre is lang. Hast du seit dem immer wieder damit gearbeitet?
|
that
ModeratorHoffnungsloser Optimist
|
Immer wieder, aber nicht ständig.
Meine erste Anwendung war XSLT als Template-Mechanismus für Webseiten.
Weitere Anwendungen: - Sourcecode aus Datenmodellen und in XML umgewandelten Datenstrukturen generieren - Dokumentationen im HTML-Format aus diesen XMLs generieren - div. Reports aus XML-Dateien (wieder HTML) - XML an neue Version von DTD/Schema anpassen (sowas wie "dieses Attribut ist in Zukunft ein Element") - Zusammenführen mehrerer XMLs zu einem (praktisch ein XML-Join)
|