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 是不必要的,因为我只希望一个子节点被命名为描述,并且它只有一个文本节点。

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

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

但事实并非如此,而且我对 XPath 语法的了解还不够好,无法知道原因。

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

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

此外,只要答案在那里,<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>

谢谢各位^-^

4

1 回答 1

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>
于 2013-06-06T13:54:09.727 回答