最先与XPath匹配

时间:2012-02-07 16:00:08

标签: xpath

我在xml中有一个配置文件,具有更高的特异性。也就是说,对某个部分的最接近设置是即使在较高级别设置也将生效的设置。一位同事建议使用XPath。但我不确定它会如何起作用?我想我想找到设置的“最深匹配”,然后在没有匹配时自动退出。

例如:

<Settings>
 <Foo>Bar</Foo>
 <Products>
  <Bar>Baz</Bar>
  <Product Name="Thingamabob">
   <Foo>Baz</Foo>
  </Product>
  <Product Name="Whizbang">
   <Bar>Foo</Bar>
  </Product>
 </Products>
</Settings>

搜索Thingamabob的Bar设置应返回“Baz”,但在Whizbang上返回“Foo”。同样地,Foo对于Thingamabob的值为“Baz”,而在Whizbang上的值为“Bar”。

这种类型的查找可以用XPath实现吗?

2 个答案:

答案 0 :(得分:0)

Foo上搜索Thingamabob可以这样做

//*[@Name='Thingamabob']/ancestor-or-self::*/Foo

但这会给你两个节点,你想获得最大count(ancestor::*)的节点,然后得到它的text()

我不知道如何在像你这样的xml层次结构上执行max,使用外部脚本迭代xpath给出的节点列表以找到最大深度,然后获取其内容。

编辑:

您可以在XSLT 2.0中执行此操作,请注意我尚未对此进行测试。

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0">

  <xsl:function name="my:lookup">
    <xsl:param name="name"/>
    <xsl:param name="arg"/>
    <xsl:for-each select="//*[@Name='$name']/ancestor-or-self::*/$arg">
       <xsl:sort select="count(ancestor::*)" data-type="number" order="descending"/>
       <xsl:if test="position()=1"><xsl:value-of select="."/></xsl:if>
    </xsl:for-each>
  </xsl:function>

  <xsl:template match="/">
        <xsl:copy-of select="my:lookup('Thingamabob','Foo')" />
  </xsl:template>

</xsl:stylesheet>

编辑2:

我也认为这应该适用于XPATH 2.0,但我还没有测试过它

//*[@Name='Thingamabob']/ancestor-or-self::*/Foo[count(ancestor::*) >= //*[@Name='Thingamabob']/ancestor-or-self::*/Foo/count(ancestor::*)]/text()

答案 1 :(得分:-1)

如果您确定知道&lt; Bar&gt;将在&lt; Product&gt;之前,您可以这样做:

//Product[@Name='Thingamabob']/preceding-sibling::Bar|//Product[@Name='Thingamabob']/Bar