Xslt - 如何检查具有特定路径名的孙子节点。 (xpath 1.0)

时间:2013-06-06 13:44:50

标签: xslt xpath xpath-1.0

我想要做的是给一个元素作为上下文,我想确定它是否有一个具有给定名称的子节点,并确定该子节点是否具有给定名称的节点,以便我可以对其进行操作。重要的是我在XPath 1.0语法中执行此操作。

到目前为止,我得到的代码就是这个。

<xsl:for-each select="child::*">
  <xsl:if test="contains(name(), 'description')">
    <xsl:for-each select="child::*">
      <xsl:if test="contains(name(), 'text')">
        <xsl:value-of select="node()"/>
      </xsl:if>
</xsl:for-each>
  </xsl:if>
</xsl:for-each>

它有效,但它又大又丑,我知道有一种方法可以浓缩它。 for-eachs是不必要的,因为我只期望一个子节点被命名为description,并且它只有一个文本节点。

我觉得这个解决方案应该有效

<xsl:for-each select="./description/text">
  ..
</xsl:for-each>

但事实并非如此,而且我对XPath Syntax的了解还不够好。

我问的原因是因为虽然我找到了检测子节点是否有名称的答案,并且我找到了可以到达该子节点上下文的答案,但我还没有找到答案结合这两者,虽然也许我只是没有进行足够的搜索,在这种情况下我道歉。

编辑:Woops,对不起,是的,我忘了提到代码的contains()部分也只是一个黑客,因为我不确定如何将它们的值与平等进行比较。

只要答案存在,<xsl:for-each select="description/text">也不起作用。

有问题的XML示例是

<leaf>
  <description>
    <text> Various Words
    </text>
  </description>
</leaf>

上下文是叶子,我试图进入文本节点。

编辑:第二次来临:

对我来说问题是我的XSLT文件使用的是默认命名空间(在我的例子中名为a)。如果我补充说,那么鲍罗丁的回答是正确的。

具体来说,这是最终为我工作的代码,万一有人想知道。

<xsl:for-each select="a:description/a:text>
  <xsl:value-of select="node()"/>
</xsl:for-each>

谢谢大家^ - ^

1 个答案:

答案 0 :(得分:1)

您真的想检查元素名称​​是否包含这些字符串?或者,正如您的叙述所说,您是否希望元素具有该名称

要执行您已编写的内容,请使用

<xsl:for-each select="*[contains(name(), 'description')]/*[contains(name(), 'text')]">
  <xsl:value-of select="node()"/>
</xsl:for-each>

但如果你知道完整的名字,那就更整洁了:

<xsl:for-each select="description/text">
  <xsl:value-of select="node()"/>
</xsl:for-each>

如果这不起作用,那么我们需要查看更多源XML和转换。


<强>更新

如果我使用此XML

<leaf>
  <description>
    <text>Various Words</text>
  </description>
  <description>
    <text>More Words</text>
  </description>
  <description>
    <text>Other Words</text>
  </description>
</leaf>

并应用此样式表

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="text"/>

  <xsl:template match="/leaf">
    <xsl:for-each select="description/text">
      <xsl:value-of select="."/>
    </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>

输出是预期的Various WordsMore WordsOther Words。我不知道如何帮助你,除非你更好地描述你的情况,除非说变换应该用另一个模板写,而不是for-each。像这种变化产生与上面相同的输出。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="text"/>

  <xsl:template match="/leaf">
    <xsl:apply-templates select="description/text"/>
  </xsl:template>

  <xsl:template match="text">
    <xsl:value-of select="."/>
  </xsl:template>

</xsl:stylesheet>