【问题标题】:XPath relative path in expression表达式中的 XPath 相对路径
【发布时间】:2012-07-02 04:01:54
【问题描述】:

我在“组”节点中。从中,我想找到这样的 'item' 节点,它的 'id' 属性等于当前的 'group' 节点 'ref_item_id' 属性值。因此,在我的情况下,通过在“组”节点 B 中,我希望“项目”节点 A 作为输出。这有效:

<xsl:value-of select="preceding-sibling::item[@id='1']/@description"/>

但这并没有(什么都不提供):

<xsl:value-of select="preceding-sibling::item[@id=@ref_item_id]/@description"/>

当我输入时:

<xsl:value-of select="@ref_item_id"/>

结果是“1”。所以这个属性肯定是可访问的,但我无法从上面的 XPath 表达式中找到它的路径。我尝试了许多 '../' 组合,但无法正常工作。

要测试的代码:http://www.xmlplayground.com/7l42fo

完整的 XML:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <item description="A" id="1"/>
    <item description="C" id="2"/>
    <group description="B" ref_item_id="1"/>
</root>

完整的 XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:output method="text" indent="no"/>
  <xsl:template match="root">
     <xsl:for-each select="group">
        <xsl:value-of select="preceding-sibling::item[@id=@ref_item_id]/@description"/>
     </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

【问题讨论】:

  • 几个问题需要澄清。你可以有许多具有特定 id 的 节点吗?是否所有 节点都放在 节点之前?
  • @Ravz 'id' 在 节点中是唯一的。所有 都放在 之前

标签: xslt xpath


【解决方案1】:

这与上下文有关。一输入谓词,上下文就变成了当前被谓词过滤的节点,不再是模板匹配的节点。

您有两个选择 - 使用变量来缓存外部范围数据并在谓词中引用该变量

<xsl:variable name='ref_item_id' select='@ref_item_id' />
<xsl:value-of select="preceding-sibling::item[@id=$ref_item_id]/@description"/>

或使用current() 函数

<xsl:value-of select="preceding-sibling::item[@id=current()/@ref_item_id]/@description"/>

【讨论】:

【解决方案2】:

您的表达式搜索其 id 属性与它自己的 ref_item_id 匹配的项目。您需要在 xsl:variable 中捕获当前 ref_item_id 并在表达式中引用该 xsl:variable。

【讨论】:

    【解决方案3】:

    使用xsl:key 的另一种可能的解决方案

    <xsl:key name="kItemId" match="item" use="@id" />
    
    <xsl:template match="root">
        <xsl:for-each select="group">
            <xsl:value-of select="key('kItemId', @ref_item_id)[1]/@description"/>
        </xsl:for-each>
    </xsl:template>
    

    【讨论】:

      【解决方案4】:

      查看 XML,如果我假设您有 &lt;item&gt;&lt;group&gt; 作为兄弟姐妹,并且顺序不限。 然后一个示例输入 XML 将如下所示。

       <?xml version="1.0" encoding="UTF-8"?>
          <root>
              <item description="A" id="1"/>
              <item description="C" id="2"/>
              <group description="B" ref_item_id="1"/>
              <item description="D" id="1"/>
              <group description="E" ref_item_id="2"/>
          </root>
      

      现在,如果目标是提取其 id 与对应的&lt;group&gt; *nodes ref_item_id* 匹配的所有&lt;item&gt; 节点的描述。然后我们可以简单地只遍历这些&lt;item&gt; 节点并获取它们的描述。

          <xsl:output method="text" indent="no"/>
            <xsl:template match="root">
               <xsl:for-each select="//item[(./@id=following-sibling::group/@ref_item_id) or (./@id=preceding-sibling::group/@ref_item_id)]">
                  <xsl:value-of select="./@description"/>
               </xsl:for-each>
            </xsl:template>
          </xsl:stylesheet>
      

      既然您说节点具有唯一的 ID,并且所有节点都放在节点之前。 我建议您使用以下 XSL 并遍历特定节点而不是节点。

       <xsl:output method="text" indent="no"/>
            <xsl:template match="root">
               <xsl:for-each select="//item[./@id=following-sibling::group/@ref_item_id]">
                  <xsl:value-of select="./@description"/>
               </xsl:for-each>
            </xsl:template>
          </xsl:stylesheet>
      

      【讨论】:

      • @Ravz 感谢另一个想法,但这在我的情况下不起作用,因为在 for-each 中我选择 并进一步分析它,这个解决方案给我留下了 在每个。我需要访问 并且从 我只需要“描述”。
      • 好的。我假设您只是在提取描述。在这种情况下,此解决方案将不起作用,您需要使用@Utkanos 在第一个解决方案中描述的可变方法。
      猜你喜欢
      • 2019-04-10
      • 1970-01-01
      • 2012-11-21
      • 2010-09-19
      • 2016-01-07
      • 1970-01-01
      • 1970-01-01
      • 2021-11-07
      • 1970-01-01
      相关资源
      最近更新 更多