I am transforming all <p> tags and renaming these nodes to <Body_Text>, on the condition that they are within the <body> element (using xsl:if).
My code is doing this, however it is omitting all <p> elements that are outside of the <body> element, which I don’t want it to do.
Here is the XML to be transformed:
<root>
<p>asdf</p>
<body>
<p>asdfasdf</p>
<p>asdfasdf</p>
</body>
<footer>
<p>asdf</p>
</footer>
</root>
…here is the XSL:
<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>
<!-- Body_Text -->
<xsl:template match="p">
<xsl:if test="parent::body">
<Body_Text>
<xsl:apply-templates select="@*|node()"/>
</Body_Text>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
…and here is the undesired result (omitting all <p> elements that are outside of the <body> element, which I don’t want it to do):
<root>
<body>
<Body_Text>asdfasdf</Body_Text>
<Body_Text>asdfasdf</Body_Text>
</body>
<footer/>
</root>
This was tested at http://xslt.online-toolz.com/tools/xslt-transformation.php.
This is the desired result, which I am not getting:
<root>
<p>asdf</p>
<body>
<Body_Text>asdfasdf</Body_Text>
<Body_Text>asdfasdf</Body_Text>
</body>
<footer>
<p>asdf</p>
</footer>
</root>
No
xsl:ifis needed — just specify proper template patterns.This transformation:
when applied on the provided XML document:
produces the wanted, correct result:
Explanation:
The template pattern of:
causes this template to be selected for execution only on
pelements that are descendents of abodyelement. All the rest nodes are copied “as-is” by the identity rule.