Search code examples
xmlxsltxpath-1.0

How can I wrap everything inside a specified XML element with a new node using XSL?



So, considering this XML:

<root>
    <table>
      <tr>
        <td>asdf</td>
        <td>qwerty</td>
        <td>1234 <p>lorem ipsum</p> 5678</td>
      </tr>
    </table>
<root>


...how might I transform it to look like this?

<root>
    <table>
      <tr>
        <td><BLAH>asdf</BLAH></td>
        <td><BLAH>qwerty</BLAH></td>
        <td><BLAH>1234 <p>lorem ipsum</p> 5678</BLAH></td>
      </tr>
    </table>
</root>


Every instance of  <td>  would then be containing the  <BLAH> element, and the contents of each  <td>  would then be within the new node.



...so far, I have this XSL which is wrapping each  <td>  element with the new node, but on the outside and not on the inside:

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

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

    <xsl:template match="table//td">
        <BLAH>
            <xsl:copy>
                <xsl:apply-templates select="@*"/>
                <xsl:apply-templates select="node()"/>
            </xsl:copy>
        </BLAH>
    </xsl:template>
</xsl:stylesheet>


...this is producing this undesired result:

<root>
  <table>
    <tr>
      <BLAH><td>asdf</td></BLAH>
      <BLAH><td>qwerty</td></BLAH>
      <BLAH><td>1234 <p>lorem ipsum</p> 5678</td></BLAH>
    </tr>
  </table>
</root>


tested at http://xslt.online-toolz.com/tools/xslt-transformation.php


Solution

  • Just move <BLAH> inside of the xsl:copy:

    <xsl:template match="td">
        <xsl:copy>
            <xsl:apply-templates select="@*"/>
            <BLAH>
                <xsl:apply-templates select="node()"/>
            </BLAH>
        </xsl:copy>
    </xsl:template>