如何通过模板xslt从子节点获取祖父节点的属性?

时间:2012-12-11 06:28:54

标签: 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>

预期产出:

<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>

我通过模板将属性ID添加到“label”标签。如何从Children节点获取属性“id”?这是我的代码

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

它不起作用。我在这里错过了什么吗?

提前感谢:)

2 个答案:

答案 0 :(得分:3)

如果您想将Xpath表达式的结果作为属性,则需要使用属性值模板,因此您应该将其写为

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

花括号表示它是一个要计算的表达式,而不是字面输出的字符串。

但是,我认为在这种情况下表达式是错误的。你应该这样做:

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

这是完整的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>

应用于XML时,输出以下内容

<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>

答案 1 :(得分:2)

您可以使用AVT

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