【问题标题】:XSLT - Matching nodes that have that a certain node inside them (like jQuery ":has")XSLT - 匹配其中包含某个节点的节点(如 jQuery ":has")
【发布时间】:2009-03-05 14:34:52
【问题描述】:

假设我有以下 XML 文件

<a id="123">
   <b type="foo" value="1" />
   <b type="baz" value="1" />
</a>
<a id="789">
  <b type="bar" value="12" />
</a>
<a id="999">
   <b type="foo", value="2" />
</a>

我想获取所有“a”节点的列表,这些节点的“b”子节点的类型=“foo”和值=“1”。你可以在 jQuery 中使用 ":has" 选择器做类似的事情。

为了记录,我计划在命令行上使用 xmlstarlet(但我不喜欢这样做),所以以这种方式工作的 xslt 是最好的。

【问题讨论】:

    标签: xml xslt xpath


    【解决方案1】:

    类似这样的:

    a[b[@type='foo'][@value='1']]
    

    应该做的伎俩

    【讨论】:

    • 我不知道你可以做 node[node[something]],这是一种优雅而干净的方式。 :)
    【解决方案2】:

    这可以使用 Gizmo 的回答中指出的单个 XPath 表达式来完成。

    因为这个问题是专门针对 XSLT 的,所以这是一个使用键的高效 XSLT 解决方案

    <xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes"/>
    <!--                                      --> 
     <xsl:key name="kAByBTypeVal" 
      match="a"
      use="concat(b/@type,'+',b/@value)"/>
    <!--                                      -->       
        <xsl:template match="/">
          <xsl:copy-of select=
           "key('kAByBTypeVal', 'bar+12')"/>
        </xsl:template>
    </xsl:stylesheet>
    

    当上述转换应用于此 XML 文档时

    <t>
        <a id="123">
            <b type="foo" value="1" />
            <b type="baz" value="1" />
        </a>
        <a id="789">
            <b type="bar" value="12" />
        </a>
        <a id="999">
            <b type="foo" value="2" />
        </a>
    </t>
    

    产生正确的结果

    <a id="789">
      <b type="bar" value="12"/>
    </a>
    

    【讨论】:

      【解决方案3】:

      我认为这将是:/b[@type='foo' and @value=1]/parent::a

      【讨论】:

      • 这不是答案。此 XPath 表达式选择 top 节点,并且仅当其名称为“b”时。顶部节点是单个节点,它永远不会有一个也是元素的父节点。
      【解决方案4】:
      <xsl:variable name="nodeList" select="a[b[@type='foo' and @value=1]]"/>
      
      <xsl:for-each select="$nodeList">
          <xsl:value-of select="."/>
      </xsl:for-each>
      

      【讨论】:

      • 你从 Maurice Perry 那里得到了 /b[@type='foo' 和 @value=1]],但它比我想要的更复杂和冗长。
      • 如果它比你想要的更复杂,那还好,但我没有从另一个 SO 用户那里复制它
      • OP 想要一个“'a' 节点列表”——而不是“a”节点的字符串值列表。
      • 哦,我不是在指责你抄袭。我是说你和莫里斯·佩里的洞察力相同,但你的洞察力稍微复杂一些。
      猜你喜欢
      • 1970-01-01
      • 2018-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-21
      • 2011-08-01
      相关资源
      最近更新 更多