2015-10-16 63 views
-1

我的xml:如何获得的祖先轴的属性在XSLT

<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

输入XML有一个元素'cnts',它与XSLT中的'contents'不同。为什么要这么做?更新XML以完成。有一个变量来存储一些值不会输出它,向我们展示您的完整XSLT!而且,这个轴被拼成“祖先”! –

回答

1

有几个与你的XSLT和你的XML,问题的每一个可能会或可能不会是你的问题的原因:

  1. 你的XSLT是不完整的,你可能这样做是为了节省空间,但它更难猜测什么是错误的(名称空间绑定,应用模板等)
  2. 您的XML与您的XSLT不匹配,如注释中所述,该模板匹配contents,这不在您的XML中你的意思是cnts?)。
  3. 即使您的代码段包含在有效的xsl:stylesheet元素中,也无法编译,ancestoer::msg会引发编译时(静态)错误。
  4. 您的代码段定义了一个变量,但没有使用它,因此无论您的变量中的任何内容都不可见。
  5. 你似乎要循环祖先轴,它可以选择多个元素msg,不知道这是故意的

如果以上所有都在您的实际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
+0

我在最后一刻更改了属性名称,并忘记在xslts中更改它。 xslt中的变量确实用在其他地方。感谢答案阿贝尔! – dellair