Given the following XML:
<root>
<StepFusionSet name="SF1">
<StepFusionSet name="SF2">
</StepFusionSet>
</StepFusionSet>
<StepFusionSet name="SF10">
</StepFusionSet>
</root>
The following C# code :
XPathDocument doc = new XPathDocument("input.xml");
var nav = doc.CreateNavigator();
var item = nav.Select("//StepFusionSet[@name]");
while (item.MoveNext())
{
Debug.WriteLine(item.Current.GetAttribute("name", item.Current.NamespaceURI));
}
Gives me the output :
SF1
SF2
SF10
But the following XSLT file :
<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="//StepFusionSet">
<xsl:call-template name="a"/>
</xsl:template>
<xsl:template name="a">
<xsl:apply-templates select="@name"/>
</xsl:template>
</xsl:stylesheet>
(called by C# code:)
XslTransform xslt = new XslTransform();
xslt.Load("transform.xslt");
XPathDocument doc = new XPathDocument("input.xml");
MemoryStream ms = new MemoryStream();
xslt.Transform(doc, null, ms);
Gives me the output :
SF1
SF10
What I’m doing wrong in my XSLT file?
Consider your first template…
…as applied to your
SF1and (nested)SF2elements:The template matches your outer
SF1element; however, it then needs to be reapplied to the children of the matched element in order to match your innerSF2.This can be achieved by embedding a recursive
<xsl:apply-templates/>inside your second template definition:Alternatively, you can use an
<xsl:for-each>element to select all your<StepFusionSet>elements (including nested ones such asSF2):