Samuel
Samuel

Reputation: 2019

What is the correct xsl to replace a part of xml

I am trying to create some html using a xsl file. Most of it is working fine but I am confused with matching rules for replacing a part of xml. Here is an example, I just need to replace the secondLine tag with the xsl rule.

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="test.xslt" ?>
<website>
  <content>
    <b>First Line</b>
    <br/>
    <secondLine/>
    <br/>
    <b>Third Line</b>
  </content>
</website>

The xsl file:

<?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"
                encoding="utf-8"  />

<xsl:template match="/">
  <html>
    <head></head>
    <body>
      <xsl:apply-templates />
    </body>
  </html>
</xsl:template>

<xsl:template match="content/secondLine">
    <b>Second Line</b>
</xsl:template>

<xsl:template match="content">
  <xsl:copy-of select="current()/node()" />
</xsl:template>

It is not really replacing the secondLine. I am looking for output like this

<html>
<head></head>
<body>
<b>First Line</b>
<br/>
<b>Second Line</b>
<br/>
<b>Third Line</b>
</body>
</html>

Upvotes: 0

Views: 47

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 116993

The tool to use in situations like these - when you only want to modify parts of the XML input, and leave most of it intact - is the identity transform template, which copies everything as is - unless another template overrides it for (more) specific nodes.

Try the following stylesheet:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="/website">
    <html>
        <head/>
        <body>
        <xsl:apply-templates select="content/*"/>
    </body>
  </html>
</xsl:template>

<xsl:template match="secondLine">
    <b>Second Line</b>
</xsl:template>

</xsl:stylesheet>

As you can see, it creates two exceptions to the default rule: the first creates the HTML wrappers and skips the existing content wrapper; the second replaces the secondLine node.

Upvotes: 1

Related Questions