首页 文章

表达式中的XPath相对路径

提问于
浏览
1

我在'组'节点 . 从中,我想找到这样的'item'节点,其'id'属性等于当前'group'节点'ref_item_id'属性值 . 所以在我的情况下,通过在'组'节点B中,我想要'item'节点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>

4 回答

  • 8

    这与 context 有关 . 输入谓词后,上下文将成为谓词当前正在过滤的节点,并且 no longer 是模板匹配的节点 .

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

    <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"/>
    
  • 0

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

  • 1

    使用 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>
    
  • 0

    查看XML,如果我假设您有 <item><group> 作为兄弟姐妹并且以任何顺序 . 然后,示例输入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与相应的 <group> *节点ref_item_id *匹配的所有 <item> 节点的描述 . 然后我们可以简单地循环这样的 <item> 节点并获得它们的描述 .

    <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>
    

相关问题