xml modifizieren mit xslt

quixx

Grünschnabel
Hallo,

ich habe folgende xml-Datei:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="test.xsl" type="text/xsl"?>
<root>
  <a>foo</a>	
  <b>bar</b>
  <b>foobar</b>
  <a>foo2</a>
  <b>bar2</b>
</root>
Jetzt möchte ich ein xslt, das alle <a>-Tags entfernt und durch den Text "Hallo" ersetzt. Also:
Code:
<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="test.xsl" type="text/xsl"?>
<root>
  Hallo	
  <b>bar</b>
  <b>foobar</b>
  Hallo
  <b>bar2</b>
</root>
Mein Ansatz ist:
Code:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="xml" indent="yes" />
 <xsl:template match="/">
  <xsl:copy-of select="* | @* | text()" />
 </xsl:template>
</xsl:stylesheet>
Das spuckt mir erstmal das xml unverändert aus, soweit so gut. Aber wo kann ich jetzt die Ersetzung machen? ein
Code:
<xsl:template match="a">Hallo</xsl:template>
vor oder nach dem root-match bringts nicht, innerhalb des templates gehts nicht (templates können offenbar nicht verschachtelt werden). Was mache ich falsch? Oder geht der Ansatz in die falsche Richtung? Igendwie steh ich auf der Leitung, ist wahrscheinlich ganz simpel. Konnte allerdings nicht herausfinden, wie das gehen soll und suche und probiere jetzt schon eine ganze Weile... hat jemdand einen Tipp?

Danke.
 

deepthroat

Erfahrenes Mitglied
Hi.
Code:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="xml" indent="yes" />
 <xsl:template match="/">
  <xsl:copy-of select="* | @* | text()" />
 </xsl:template>
</xsl:stylesheet>
Das spuckt mir erstmal das xml unverändert aus, soweit so gut. Aber wo kann ich jetzt die Ersetzung machen?
Auf diese Weise kannst du keine Ersetzung machen. Du hast hier ein Template für das Dokumentelement angegeben und gibst dann eine Kopie aus von allen Elementen die ausgehend vom Kontextknoten (dem Dokumentelement!) entweder ein Element-, Attribut- oder Textknoten sind. Damit gibst du hier lediglich das /root Element mit all seinen Unterknoten aus...

Weiter passiert da nichts. Wenn du weitere Templates verarbeiten willst, dann mußt du das explizit mit apply-templates spezifizieren.

Textknoten werden standardmäßig automatisch ausgegeben.
XML:
<xsl:template match="*">
   <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates />
   </xsl:copy>
</xsl:template>
  
<xsl:template match="a">Hallo</xsl:template>
Gruß
 
Zuletzt bearbeitet von einem Moderator:

quixx

Grünschnabel
Hi deepthroat,

danke das funktioniert. Habe etwas gebraucht um zu kapieren, wie (fange mit xslt gerade erst an). Mit copy-of und apply-templates hatte ich auch schon rumprobiert, allerdings wurden dann die tags nie mitkopiert. Inzwischen ist auch der Unterschied zwischen copy und copy-of klar. Dabei bin ich über das gestolpert, ist wenn ich richtig verstanden habe das Gleiche:
XML:
<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>
Jetzt gab es aber noch ein Problem: wenn die tags der xml-Datei etwas anders verschachtelt sind, funktioniert die Lösung nicht mehr.
Beispiel:
XML:
<a>foo<b>bar<a>foobar</a></b></a>
Ist auch klar, der innere <b>-Tag wird ja garnicht verarbeitet. Hier ist jetzt meine Lösung:
XML:
<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>
 
<xsl:template match="a">Hallo<xsl:apply-templates select="*" /></xsl:template>
Danke nochmal, hast mir sehr geholfen.
 
Zuletzt bearbeitet von einem Moderator: