I am newbie to XSLT. My am is to remove elements from XML based on a field if it is higher than some threshold value which I will be getting as parameter to it.
My XML is as shown below:
<tns:PM objectClass="MyNode" objectName="" className="com.project.converter.PMFamilyConverter" interfaceName="ComponentPM"
xmlns:tns="http://www.myproject/SS/PMSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.myProject.com/SS/PM.xsd">
<tns:family desc="family0" id="f0" eventNumber="000000">
<tns:performanceIndicator desc="Description 1" id="Success" eventNumber="000001" />
<tns:performanceIndicator desc="Description 2" id="Error" eventNumber="000002" />
</tns:family>
<tns:family desc="family1" id="f1" eventNumber="010000">
<tns:performanceIndicator desc="Description 1" id="Success" eventNumber="010001" />
<tns:performanceIndicator desc="Description 2" id="Name Error" eventNumber="010002" />
<tns:performanceIndicator desc="Description 3" id="Server Not Found Error" eventNumber="010003" />
</tns:family>
<tns:family desc="family2" id="f2" eventNumber="020000">
<tns:performanceIndicator desc="Description 1" id="Success" eventNumber="020001" />
<tns:performanceIndicator desc="Description 2" id="Format Error" eventNumber="020002" />
<tns:performanceIndicator desc="Description 3" id="Logic Error" eventNumber="020003" />
<tns:performanceIndicator desc="Description 4" id="Success with warning message" eventNumber="020004" />
</tns:family>
<tns:family desc="family3" id="f3" eventNumber="030000">
<tns:performanceIndicator desc="Description 1" id="Success" eventNumber="030001" />
<tns:performanceIndicator desc="Description 2" id="Error" eventNumber="030002" />
</tns:family>
</tns:PM>
Based on some samples available online, the XSL I have written is:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" standalone="no" indent="yes"/>
<xsl:param name="maxEventNum"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:apply-templates select="/*[contains(local-name(),'PM')]/*[contains(local-name(),'family')]/@eventNumber"/>
<xsl:if test="number(.) < $maxEventNum">
<xsl:copy-of select="/*[contains(local-name(),'PM')]/*[contains(local-name(),'family')]"/>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
The output I want is shown below if I pass maxEventNumber as 020004
.
<tns:PM objectClass="MyNode" objectName="" className="com.project.converter.PMFamilyConverter" interfaceName="ComponentPM"
xmlns:tns="http://www.myproject/SS/PMSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.myProject.com/SS/PM.xsd">
<tns:family desc="family0" id="f0" eventNumber="000000">
<tns:performanceIndicator desc="Description 1" id="Success" eventNumber="000001" />
<tns:performanceIndicator desc="Description 2" id="Error" eventNumber="000002" />
</tns:family>
<tns:family desc="family1" id="f1" eventNumber="010000">
<tns:performanceIndicator desc="Description 1" id="Success" eventNumber="010001" />
<tns:performanceIndicator desc="Description 2" id="Name Error" eventNumber="010002" />
<tns:performanceIndicator desc="Description 3" id="Server Not Found Error" eventNumber="010003" />
</tns:family>
</tns:PM>
Also can you please tell when and how to use apply-template
and is it related to match
if apply-template
is used inside match
.
First thing: you should use the namespace/s in your input XML, not dance around them with awkward expressions like
*[contains(local-name(),'...')]
.Now, the simplest way to exclude specific nodes is to start with the identity transform template (as you have) to copy all nodes as the rule, then add an empty template matching the nodes you want to exclude as the exception.
However, this cannot work when the nodes you want to exclude are determined by a parameter, because a template's match pattern cannot contain a reference to a variable. In such case, you can make the content of the template conditional:
XSLT 1.0
Note: (1) the added
xmlns:tns="http://www.myproject/SS/PMSchema"
namespace declaration and the use of thetns:
prefix, and (2) the escaping of the<
operator as<
.An alternative solution would make sure that templates are applied only to
tns:family
nodes that meet the criteria:XSLT 1.0