如何在XSLT中获取祖先轴上的属性

时间:2015-10-16 19:01:03

标签: xml xslt

我有xml:

<msg id="abc" type="test">
  <local id="def"/>
  <cnts x:type="fld" id="111" type="a2">
  </cnts>
</msg>

xslt是:

<xsl:template match="contents[@x:type='fld']">
  <xsl:variable name="msgs">
    <xsl:for-each select="ancestoer::msg">
      <msg><xsl:value-of select="@type"/></msg>
    </xsl:for-each>
  </xsl:variable>
</xsl:template>

我希望输出为:

<msg>test</msg>

但它没有按预期工作。有人可以帮忙吗?

1 个答案:

答案 0 :(得分:1)

您的XSLT和XML存在一些问题,每个问题可能是也可能不是您的问题的原因:

  1. 你的XSLT不完整,你可能这样做是为了节省空间,但是它更难以猜出什么是错的(命名空间绑定,应用模板等)
  2. 您的XML与您的XSLT不匹配,如评论中所述,模板匹配的元素contents不在您的XML中(您的意思是cnts吗?)。
  3. 您的代码段即使包含在有效的xsl:stylesheet元素中也无法编译,ancestoer::msg会引发编译时(静态)错误。
  4. 您的代码段定义了一个变量,但不使用它,因此您的变量中的任何内容都将不可见。
  5. 您似乎想要遍历祖先轴,这可能会选择多个元素msg,不确定这是故意的
  6. 如果以上所有内容在您的实际XSLT中都是正确的,那么您的问题就在其他地方,我们将不得不看到更多您的XSLT XML,事实上,我们需要一个Minimal, Complete, and Verifiable example

    也就是说,这里有三种使用祖先轴的方法:

    1. 如果您只需要一个项目,则不需要中间变量,只需使用<xsl:value-of select="ancestor::msg/@type" />
    2. 如果要循环遍历所有祖先,可以使用:

      <xsl:template match="contents[@x:type='fld']">
          <xsl:apply-templates select="ancestor::msg" mode="anc" />
      </xsl:template>
      
      <xsl:template match="msg" mode="anc">
          <msg><xsl:value-of select="@type" /></msg>
      </xsl:message>
      

      在这个例子中,我故意切换模式,因为你很可能已经在其他地方的msg匹配,在这种情况下,你可能会以一个永无止境的循环结束。

    3. 您当前使用xsl:for-each的方法。这没有错,只是不那么灵活,从长远来看更多的打字。不需要使用变量,但如果您想使用变量,请确保您也使用变量,例如使用xsl:copy-of