Mit XSL XML Attribute ändern
joh.w
- xsl
Hi,
ich suche schon über einen Tag danach ein vorhandenes XML-file mit XSL so zu bearbeiten, dass bestimmte Inhalte von Attributen ersetzt werden. So schwierig kann der XSL Code dazu ja nicht sein. Aber wie geht das?
Quelle:
<root>
<Element attr="Anytext"/>
</root>
Das soll das Ziel sein:
<root>
<Element attr="Sometext"/>
</root>
Kann mir da jemand nen passenden XSL Code dazu posten?
Gruß
joh.w
Hello out there!
ich suche schon über einen Tag danach ein vorhandenes XML-file mit XSL so zu bearbeiten, dass bestimmte Inhalte von Attributen ersetzt werden.
Die da wären? Meinst du sowas?
<xsl:if test="Element/@attr = 'Anytext'">
<xsl:attribute name="attr">Sometext</xsl:attribute>
</xsl:if>
Kann mir da jemand nen passenden XSL Code dazu posten?
Kannst du mal ne passende Problembeschreibung zu dem erwarteten Code posten?
See ya up the road,
Gunnar
Kannst du mal ne passende Problembeschreibung zu dem erwarteten Code posten?
Ich wollte den Sachverhalt kurz halten...
Ich bekomme eine XML-Datei von einem anderem Fremdprogramm ausgeliefert. Dort drin stehen in Attributen von XML-Elementen servernamen (server="localhost"). Diese XML-Datei kann ich dann einem anderen Fremdprogramm geben, der die Information grafisch darstellt. Dieses Programm ist in der Lage bevor die Informationen grafisch ausgegeben werden die Input-XML mit einem XSLT nochmals aufzubereiten. Und dort an der Stelle möchte ich nun die Rechnernamen geändert haben. Unter anderem. Gibt noch ein paar Ecken mehr... letztlich sinds aber immer Attribute.
Ich habe deinen Code ausprobiert. Bekomme leider ein leeres XML-Dokument :-(
Bin leider vollkommen neu im Gebiet XSLT und versteh fast nur Bahnhof.
Hello,
Bin leider vollkommen neu im Gebiet XSLT und versteh fast nur Bahnhof.
geh ich dann jetzt Recht in der Annahme, dass du _genau_ das in deiner Datei stehen hast, was Gunnar geschrieben hat? Wenn ja, dann kann das nichts werden...
Schau dir am Besten mal das XSLT-Tutorial von W3Schools an, damit solltest du die Grundlagen schnell erfassen können.
MfG
Rouven
geh ich dann jetzt Recht in der Annahme, dass du _genau_ das in deiner Datei stehen hast, was Gunnar geschrieben hat? Wenn ja, dann kann das nichts werden...
Naja, natürlich nicht. Aber die Elementnamen kann ich schon noch austauschen.
Zudem hab ich selbstverständlich _genau_ die Beispieldatei erstellt, die ich auch hier im Forum gebracht habe. Da probiere ich erst aus und dann wird auf dieser Basis weitergemacht.
Hallo joh.w,
ich suche schon über einen Tag danach ein vorhandenes XML-file mit XSL so zu bearbeiten, dass bestimmte Inhalte von Attributen ersetzt werden. So schwierig kann der XSL Code dazu ja nicht sein. Aber wie geht das?
Quelle:
<root>
<Element attr="Anytext"/>
</root>Das soll das Ziel sein:
<root>
<Element attr="Sometext"/>
</root>
Hier bietet sich eine so genannte Identitäts-Transformation an, welche alle Inhalte in eine neue XML-Struktur umformt, ggf. unter Berücksichtigung spezieller Änderungen (hier im zweiten Template enthalten):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="root[Element/@attr='Anytext']">
<root>
<Element attr="Sometext"/>
</root>
</xsl:template>
</xsl:stylesheet>
Grüße,
Thomas
Hier bietet sich eine so genannte Identitäts-Transformation an, welche alle Inhalte in eine neue XML-Struktur umformt, ggf. unter Berücksichtigung spezieller Änderungen (hier im zweiten Template enthalten):
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0"/><xsl:template match="@* | node()">
xsl:copy
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template><xsl:template match="root[Element/@attr='Anytext']">
<root>
<Element attr="Sometext"/>
</root>
</xsl:template></xsl:stylesheet>
Hallo Thomas,
es geht in die richtige Richtung. Möchte genau dieselbe XML-Datei (von der Struktur her) haben mit leicht verändertem Inhalt.
Habe dein Beispiel kurz versucht, aber der "Sometext" wird nicht eingesetzt, sondern weiterhin nur "Anytext". Probiere das ganze gerade in der Beta2 von Visual Studio 2008 aus.
Danke trotzdem.
Gruß
joh.w
Hallo joh.w,
Habe dein Beispiel kurz versucht, aber der "Sometext" wird nicht eingesetzt, sondern weiterhin nur "Anytext". Probiere das ganze gerade in der Beta2 von Visual Studio 2008 aus.
Wie sieht denn das Ausgangsdokument genau aus? Mit dem geposteten Fragment funktioniert der genannte Code problemlos. An VS 2008 sollte es formal nicht liegen. Zumindest habe ich sehr gute Erfahrungen mit VS 2005 und XML+XSLT gemacht.
Probiere es testweise mit einem Kommandozeilentool wie XMLStarlet und dieser Syntax:
xml -tr stylesheet.xsl eingabe.xml > ausgabe.xml
Grüße,
Thomas
Hallo Thomas,
<xsl:template match="root[Element/@attr='Anytext']">
<root>
<Element attr="Sometext"/>
</root>
</xsl:template>
dein Template ergibt in Bezug auf die Fragestellung und in Verbindung mit der Identitätstransformation keinerlei Sinn. Dein Template ist nicht nur falsch formuliert, sondern kontraproduktiv, da es die Identitätstransformation "abwürgt". Was aber sogar ein Glücksfall ist, da sonst (abgesehen davon ebenfalls) alles andere als das gewünschte Ergebnis herauskommen würde.
Das »root/Element/@attr[.='Anytext']« wäre beispielsweise eine "richtige" Formulierung des Template-Patterns. Der Unterschied zu deiner Formulierung misst sich in Galaxien.
Vermutlich würde aber »@attr[.='Anytext']« ausreichen. Genaueres kann man so nicht sagen, da wie üblich eine Wischiwaschi-Fragestellung vorliegt.
Gruß Uwe
Hallo Uwe,
dein Template ergibt in Bezug auf die Fragestellung und in Verbindung mit der Identitätstransformation keinerlei Sinn. Dein Template ist nicht nur falsch formuliert, sondern kontraproduktiv, da es die Identitätstransformation "abwürgt". Was aber sogar ein Glücksfall ist, da sonst (abgesehen davon ebenfalls) alles andere als das gewünschte Ergebnis herauskommen würde.
Bezogen auf das Beispiel
<?xml version="1.0" encoding="ISO-8859-1"?>
<root>
<Element attr="Anytext"/>
</root>
hat der Ansatz funktioniert, hatte ich ja getestet.
Besonders allgemeingültig war das doch nicht, soweit gebe ich Dir Recht. Diese Formulierung trifft es eher:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="ISO-8859-1"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Element[@attr='Anytext']">
<Element attr="Sometext"/>
</xsl:template>
</xsl:stylesheet>
Hier fehlt lediglich der ursprüngliche root-Bezug im zweiten Template.
Ein Dokument dieser Art lässt sich damit durchaus behandeln:
<?xml version="1.0" encoding="ISO-8859-1"?>
<root>
<Element attr="Anytext"/>
<x>Test</x>
<Element attr="Anytext"/>
<x>
<y>Test</y>
<z>
<Element attr="Anytext"/>
</z>
</x>
<hallo>
<blub>123</blub>
</hallo>
<Element attr="Anytext"/>
</root>
mit dem Ergebnis:
<?xml version="1.0" encoding="ISO-8859-1"?>
<root>
<Element attr="Sometext" />
<x>Test</x>
<Element attr="Sometext" />
<x>
<y>Test</y>
<z>
<Element attr="Sometext" />
</z>
</x>
<hallo>
<blub>123</blub>
</hallo>
<Element attr="Sometext" />
</root>
Grüße,
Thomas
Hallo Thomas,
Bezogen auf das Beispiel
<root>
<Element attr="Anytext"/>
</root>
hat der Ansatz funktioniert, hatte ich ja getestet.
Eine kleine Erweiterung des Beispiels zeigt, dass der Ansatz grundsätzlich nichts taugt.
<root>
<Element attr="Anytext"/>
<Element attr="Anytext"/>
</root>
Auch dieser Ansatz (sorry) taugt nichts.
<xsl:template match="Element[@attr='Anytext']">
<Element attr="Sometext"/>
</xsl:template>
Du würgst hier wieder die Identitätstransformation ab, das merkst du, falls der Knoten "Element" Kindknoten hat. Du müsstest hier deswegen noch eine apply-templates Anweisung einbauen, damit es ggf. "weiter geht".
Aber das wäre keineswegs im Sinne des Erfinders. Du sprichst hier den Knoten "Element" an, um den geht es aber gar nicht.
Die Identitätstransformation macht eine eins zu eins Kopie des Quellbaums. Will man nun bestimmte Knoten gesondert behandeln, so nimmt man sie einfach "aus der Identitätstransformation raus" indem man für genau diese Knoten entsprechende Templates definiert (die ja dann eine höhere Priorität haben), worin man dann das Gewünschte umsetzt.
Der Knoten um den es geht, ist nicht der Knoten "root" auch nicht der Knoten "Element", sondern der Knoten »@attr[.='Anytext']«.
Ein entsprechendes Template könnte wie folgt aussehen:
<xsl:template match="@attr[.='Anytext']">
<xsl:attribute name="attr">Sometext</xsl:attribute>
</xsl:template>
Gruß Uwe
Hallo Uwe,
Der Knoten um den es geht, ist nicht der Knoten "root" auch nicht der Knoten "Element", sondern der Knoten »@attr[.='Anytext']«.
Ein entsprechendes Template könnte wie folgt aussehen:
<xsl:template match="@attr[.='Anytext']">
<xsl:attribute name="attr">Sometext</xsl:attribute>
</xsl:template>
Direkt auf die relevanten Attributknoten zu gehen ist natürlich die universelle Lösung. Ich bin davon ausgegangen, dass das Element-Level dem OP ausreichen würde.
Kommt halt immer auf die Anforderungen an und mehr vom XML-Code des OP wäre auch zielführender gewesen. Da soll aber keine Ausrede für meinen Holzweg sein ;-). Danke für die Diskussion und ein schönes WE.
Grüße,
Thomas