qingsong
qingsong

Reputation: 785

how to concat the attribute names of the parent nodes

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

Answers (2)

Dimitre Novatchev
Dimitre Novatchev

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

Emiliano Poggi
Emiliano Poggi

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

Related Questions