我在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实现吗?
答案 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