Reputation: 785
I have a XML Document like this:
<Module Name="DacInPlaceUpgradeLtmTest" Desc="" >
<TestCase Name="ExecuteInPlaceUpgradeTest">
<TestCase Name="BugRepro">
<TestCase Name="295130">
<Variation Id="1" Desc="Sql - EmptyAlterScript">
<Variation Id="2" Desc="Sql - EmptyDatabase">
</TestCase>
</TestCase>
</TestCase>
</Module>
I use xsl to get a value:
ExectionInplaceUPgradeTest BugRepro 295130
by using following template:
<xsl:template match="TestCase//Variation">
<xsl:for-each select="..@Name">
Today, I can only get 295130, I wonder how can I get all Attribtes of the parent nodes which is TestCase.
Upvotes: 4
Views: 1369
Reputation: 243479
This transformation:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="Variation[@Id = 1]">
<xsl:apply-templates mode="printName"
select="ancestor::TestCase"/>
</xsl:template>
<xsl:template match="TestCase" mode="printName">
<xsl:if test="not(position()=1)">
<xsl:text> </xsl:text>
</xsl:if>
<xsl:value-of select="@Name"/>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
when applied on the provided XML document:
<Module Name="DacInPlaceUpgradeLtmTest" Desc="" >
<TestCase Name="ExecuteInPlaceUpgradeTest">
<TestCase Name="BugRepro">
<TestCase Name="295130">
<Variation Id="1" Desc="Sql - EmptyAlterScript"/>
<Variation Id="2" Desc="Sql - EmptyDatabase"/>
</TestCase>
</TestCase>
</TestCase>
</Module>
produces the wanted, correct result:
ExecuteInPlaceUpgradeTest BugRepro 295130
II. XPath 2.0/XSLT 2.0 solution
//TestCase[Variation]
/ancestor-or-self::TestCase
/@Name/string(.)
The above XPath 2.0 expression when evaluated on the above XML document produces exactly the wanted, correct result:
ExecuteInPlaceUpgradeTest BugRepro 295130
It can be used in the following XSLT 2.0 solution:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:sequence select=
"//TestCase[Variation]
/ancestor-or-self::TestCase
/@Name/string(.)
"/>
</xsl:template>
</xsl:stylesheet>
Upvotes: 2
Reputation: 24826
I wonder how can I get all Attributes of the parent nodes which is TestCase
You might need the XPath ancestor-or-self
axis:
ancestor-or-self::TestCase/@Name
how to concat the attribte names of the parent nodes
It really depends on the template context and on the code you are already working on. taking as a reference your fragment, I would write better:
<xsl:template match="TestCase[Variation]">
<xsl:for-each select="ancestor-or-self::TestCase/@Name">
<xsl:value-of select="concat(.,' ')"/>
</xsl:for-each>
</xsl:template>
This will print the wanted string starting from the TestCase
node which has a Variation
node as a child.
Upvotes: 3