Komme mit Namspace net klar - HELP!
Andreas
- xsl
Hallo zusammen!
Ich bin per google auf dieses Forum gestossen, nachdem ich mich seit Tagen durch Suchergebnisse durchwühle. Die Suchfunktion hier habe ich auch schon genutzt und nichts gefunden, dass mir geholfen hat.
Ich versuche folgende XML-Datei(die ich nicht verändern kann) auszulesen und mit anderen Dateien gleichen Formates zusammen in einer Tabelle (HTML) auszugeben.
<?xml version="1.0" encoding="utf-16"?>
<Data xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://abc.com/abc/Data" Fach1ID="d0aea575-3dca-403a-b14c-33df3b515e07" Fach2ID="4bb6e2a0-0574-4324-a935-0b4ccd95831a" Fach3ID="2ebc264a-df30-4fa1-836a-e352cb2eb82b" Fach4ID="2df3806b-f173-4e43-929b-7945a7dc7aea">
<AblageInfo xmlns="http://blabla.com/blabla">
<AttributA>Blau</AttributA>
<AttributB>adaf6407-b35d-4143</AttributB>
</AblageInfo>
<Einstellung>
<Datum>2007-08-22</Datum>
<Zahl>001</Zahl>
</Einstellung>
<Data123>
<dummdidumm>123456789</dummdidumm>
</Data123>
</Data>
Ich bin neu im Thema XML/XSL/XSLT und komme nicht weiter. Leider scheitere ich schon beim Testen der Tabellenausgabe:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Edited with XML Spy v2007 (http://www.altova.com) -->
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method='html' version='1.0' encoding='UTF-8' indent='yes'/>
<xsl:template match="/">
<html>
<body>
<h2>Uebersicht</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th align="left">Einstellung</th>
<th align="left">Zahl</th>
</tr>
<xsl:for-each select="//Einstellung">
<tr>
<td><xsl:value-of select="Datum"/></td>
<td><xsl:value-of select="Zahl"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Das ganz wird nicht angezeigt. Soweit ich das Thema bisher überblicken kann, kann ich "//Einstellung" nicht verwenden - wegen diesem Namespace-Zeugs im "parent".
Denn, wenn ich die XML modifiziere und die Zeile
<Data xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://abc.com/abc/Data" Fach1ID="d0aea575-3dca-403a-b14c-33df3b515e07" Fach2ID="4bb6e2a0-0574-4324-a935-0b4ccd95831a" Fach3ID="2ebc264a-df30-4fa1-836a-e352cb2eb82b" Fach4ID="2df3806b-f173-4e43-929b-7945a7dc7aea">
abändere in
<Data>
dann wird alles genau so angezeigt, wie ich das haben will. Kann mir einer helfen, wie ich das anspechen muss?
Die Dateien wurden leicht abgeändert, die originale kann ich leider hier nicht posten.
VIELEN DANK im Voraus für eure Hilfe.
mfg
Andreas
Hallo Andreas,
Das ganz wird nicht angezeigt. Soweit ich das Thema bisher überblicken kann, kann ich "//Einstellung" nicht verwenden - wegen diesem Namespace-Zeugs im "parent".
Denn, wenn ich die XML modifiziere und die Zeile<Data xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://abc.com/abc/Data" Fach1ID="d0aea575-3dca-403a-b14c-33df3b515e07" Fach2ID="4bb6e2a0-0574-4324-a935-0b4ccd95831a" Fach3ID="2ebc264a-df30-4fa1-836a-e352cb2eb82b" Fach4ID="2df3806b-f173-4e43-929b-7945a7dc7aea">
abändere in
<Data>
dann wird alles genau so angezeigt, wie ich das haben will. Kann mir einer helfen, wie ich das anspechen muss?
Dein Problem ist folgendes:
<Data xmlns="http://abc.com/abc/Data">
legt fest, dass der Default-Namespace für alle Elemente "http://abc.com/abc/Data" ist (NICHT jedoch für alle Attribute, das ist das IMHO ziemlich verwirrende an der XML-Namespace-Spec). XSLT verwendet nun XPath, um auf Elemente zuzugreifen. Bei XPath musst Du dann aber explizit den Namespace angeben, damit er das ganze erkennt.
Du hast zwei Möglichkeiten:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:data="http://abc.com/abc/Data">
Dann kannst Du das Präfix "data" in XPath-Ausdrücken verwenden z.B. so:
<xsl:for-each select="//data:Einstellung">
Genauso musst Du natürlich auch alle anderen Elemente ansprechen:
<td><xsl:value-of select="data:Datum"/></td>
<td><xsl:value-of select="data:Zahl"/></td>
Wenn Du kein Präfix definieren willst, kannst Du (umständlicher) auch über Qualifikatoren arbeiten, d.h.
<xsl:for-each select="//*[local-name() = 'Einstellung']">
sowie
<td><xsl:value-of select="*[local-name() = 'Datum']"/></td>
<td><xsl:value-of select="*[local-name() = 'Zahl']"/></td>
(In dem Fall wäre sogar der Namespace komplett egal, ich würde diese Lösung dennoch nicht empfehlen)
Zudem kannst Du je nach XSLT-Prozessor meist noch die Syntax select="//{http://abc.com/abc/Data}Einstellung" nutzen, wenn Du den Namespacenamen direkt angeben willst.
Beachte bitte, dass das nur für Elementnamen gibt, bei Attributnamen (z.B. @data:Fach1-ID) wird das nicht funktionieren, da musst Du weiterhin nur den Namen schreiben (@Fach1-ID) - AUSSER vor dem Attribut steht explizit schon in der XML-Datei ein Namespace-Präfix, dann musst Du mit dem gleichen Namespace matchen (was in Deiner XML-Datei nicht zwangsläufig das gleiche Präfix sein muss!).
Viele Grüße,
Christian
Hi Christian,
die erste Möglichkeit üder den definierten Präfix hat nicht funktioniert, die ausgegebene Tabelle war wiederum leer.
Die zweite Möglichkeit über die Qualifikatoren hat erfolgreich funktioniert. Vielen Dank dafür! *g*
Wo ich grad so eine kompetente Person an der Strippe habe, evtl. kannst du mir ja nochmal weiterhelfen...
Ich habe zum Testen das Quell-XML-File modifiziert und die Zeile
<?xml-stylesheet type="text/xsl" href="test.xsl"?>
eingefügt. In dieser .XSL steht der oben genannte Code drinnen. Wie kann ich das Ganze nun ausgeben lassen, ohne das Quell-XML zu verändern?
Danke.
mfg
Andreas
Hallo Andreas,
die erste Möglichkeit üder den definierten Präfix hat nicht funktioniert, die ausgegebene Tabelle war wiederum leer.
Das sollte aber. Welchen XSLT-Prozessor verwendest Du denn?
Bei mir funktioniert's mit der angegebenen Testdatei (zugehöriges Stylesheet).
Was mir allerdings auffällt: In Deiner XML-Datei taucht folgende Zeile oberhalb von <Einstellungen> auf:
<AblageInfo xmlns="http://blabla.com/blabla">
Hier wird also für das Element AblageInfo ein neuer, ANDERER Default-Namespace definiert. Falls dies auch beim Element Einstellungen der Fall sein soll, Du das beim Kürzen des Quellcodes jedoch aus Versehen weggelassen hast, dann musst Du natürlich den anderen Namespace mit angeben - das macht die Sache zumindest in meinen Augen VIEL übersichtlicher.
Wo ich grad so eine kompetente Person an der Strippe habe, evtl. kannst du mir ja nochmal weiterhelfen...
Ich habe zum Testen das Quell-XML-File modifiziert und die Zeile<?xml-stylesheet type="text/xsl" href="test.xsl"?>
eingefügt. In dieser .XSL steht der oben genannte Code drinnen. Wie kann ich das Ganze nun ausgeben lassen, ohne das Quell-XML zu verändern?
Klar. Aber auch das hängt von Deinem XSLT-Prozessor ab und wie Du ihn aufrufst. Wenn Du z.B. xsltproc verwendest (ist bei libxml2 dabei), dann würdest Du das z.B. so machen (auf der Kommandozeile aufrufen):
xsltproc test-xsl-ns-1.xsl test-xsl-ns-1.xml > test-xsl-ns-1.html
Oder allgemein:
xsltproc Stylesheet Eingabedatei > Ausgabedatei
Wenn Du dagegen z.B. Saxon verwendest, dann würdest Du folgendes nutzen:
java net.sf.saxon.Transform -o test-xsl-ns-1.html test-xsl-ns-1.xml test-xsl-ns-1.xsl
Oder allgemein:
java net.sf.saxon.Transform -o Ausgabedatei Eingabedatei Stylesheet
Wenn Dir das nicht weiterhilft, musst Du schon erklären, wie Du Dein XSLT denn bisher anwendest.
Viele Grüße,
Christian