iCeR
iCeR

Reputation: 149

How can I get the attribute of the grandparent node from child node via template xslt?

XML:

<Grandparent>
  <Parent>
    <Children id ="1">
      <Info>
        <Name>
          <label name ="chname" />
        </Name>
      </Info>
    </Children>
    <Children name ="2">
      <Info>
        <Name>
          <label name="chname" />
        </Name>
      </Info>
    </Children>
    <Children id ="3">
      <Info>
        <Name>
          <label name="chname" />
        </Name>
      </Info>
    </Children>
  </Parent>
</Grandparent>

XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" omit-xml-declaration="yes" />
<xsl:strip-space elements="*" />  

<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="label">
  <label id="../../../preceding-sibling::Children/@id">
    <xsl:apply-templates select="@*|node()"/>
  </label>
</xsl:template>

</xsl:stylesheet>

Expected Output:

<Grandparent>
      <Parent>
        <Children id ="1">
          <Info>
            <Name>
              <label id="1" name ="chname" />
            </Name>
          </Info>
        </Children>
        <Children name ="2">
          <Info>
            <Name>
              <label id="2" name="chname" />
            </Name>
          </Info>
        </Children>
        <Children id ="3">
          <Info>
            <Name>
              <label id="3" name="chname" />
            </Name>
          </Info>
        </Children>
      </Parent>
    </Grandparent>

Im adding A attribute id to "label" tag via template. How can I get the attribute "id" from Children node? this is my code

<label id="../../../preceding-sibling::Children/@id"> 

it doesnt work. Am I missing something here?

thanks in advance :)

Upvotes: 2

Views: 1914

Answers (2)

Daniel Haley
Daniel Haley

Reputation: 52858

You can use an AVT:

<label id="{../../../@id}"> 

Upvotes: 2

Tim C
Tim C

Reputation: 70618

If you want to have the results of an Xpath expression as an attribute, you need to use Attribute Value Templates, so you should be writing it as this

<label id="{../../../preceding-sibling::Children/@id}"> 

The curly braces indicate it is an expression to be evaluated, rather than a string to be output literally.

However, I think the expression is wrong though in this case. You should be actually doing this:

<label id="{../../../@id}">

Here is the full XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" omit-xml-declaration="yes" />
<xsl:strip-space elements="*" />  

<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

<xsl:template match="label">
  <label id="{../../../@id}">
    <xsl:apply-templates select="@*|node()"/>
  </label>
</xsl:template>

</xsl:stylesheet>

When applied to your XML, the following is output

<Grandparent>
   <Parent>
      <Children id="1">
         <Info>
            <Name>
               <label id="1" name="chname"/>
            </Name>
         </Info>
      </Children>
      <Children name="2">
         <Info>
            <Name>
               <label id="" name="chname"/>
            </Name>
         </Info>
      </Children>
      <Children id="3">
         <Info>
            <Name>
               <label id="3" name="chname"/>
            </Name>
         </Info>
      </Children>
   </Parent>
</Grandparent>

Upvotes: 3

Related Questions