stofl
stofl

Reputation: 2982

XSL: Copy XML and then replace some tags

I am very new to XSL/XSLT. I want to copy an xml document into an other but replace some namespaced tags and some tags that have some special attributes. For example:

<root>
  <ext:foo>Test</ext:foo>
  <bar>Bar</bar>
  <baz id="baz" x="test">
    <something/>
  </baz>
</root>

Should be rewritten into:

<root>
  --Test--
  <bar>Bar</bar>
  xxx<baz id="baz">
    <something/>
  </baz>xxx
</root>

Is it possible to copy the whole XML and then apply some rules to replace the tags I want to replace?

Upvotes: 5

Views: 4115

Answers (2)

FailedDev
FailedDev

Reputation: 26930

Assuming your .xml file has the same namespace for ext : xmlns:ext="www.foo.com" this xslt produces your output, although you must take it with a grain of salt since it doesn't exactly check for anything, just produces your output for this specific case.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:ext="www.foo.com">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/root">
    <root>

      <xsl:text>--</xsl:text><xsl:value-of select="./ext:foo/text()"/><xsl:text>--</xsl:text>
      <xsl:copy-of select="./bar"/>
      <xsl:variable name="bazElem" select="./baz"/>
      <xsl:text>xxx</xsl:text><baz id="{$bazElem/@id}">
        <xsl:copy-of select="$bazElem/something"/>
      </baz><xsl:text>xxx</xsl:text>
    </root>
  </xsl:template>
</xsl:stylesheet>

Upvotes: 0

Carl Raymond
Carl Raymond

Reputation: 4479

You can copy some nodes and re-write others with different rules. To keep <root> and <bar> the same, and re-write <baz>, try this (untested) as a starting point:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml"/>

  <!-- Match <baz> and re-write a little -->
  <xsl:template match="baz">
    xxx<baz id="{@id}">
     <xsl:apply-templates />
    </baz>xxx
  </xsl:template>

  <!-- By default, copy all elements, attributes, and text -->
  <xsl:template match="@* | node()">
<xsl:copy>
  <xsl:apply-templates select="@* | node()"/>
</xsl:copy>
  </xsl:template>


</xsl:stylesheet>

Upvotes: 7

Related Questions