4

我对 XPATH 相当陌生,当某个节点等于两个值之一时,我需要从多个 XML 对象返回一个值。该解决方案还需要使用 local-name() 与命名空间无关。鉴于以下 XML,我希望返回“B”的所有值,其中“A”等于“4”或“5”。

<?xml version="1.0"?>
    <element>
        <A>3</A>
        <B>Value 1</B>
    </element>
    <element>
        <A>4</A>
        <B>Value 2</B>
    </element>
    <element>
        <A>5</A>
        <B>Value 3</B>
    </element>

我已经尝试了以下表达式的多次迭代,但是当我尝试为“A”添加第二个值时似乎无法获得正确的语法。我似乎无法弄清楚“或”表达式的正确语法。我也考虑过使用联合,但也无法正确使用该语法。

这适用于“A”等于单个值“4”但如何添加“5”值的测试,以便结果返回“B”的两个值(“值 2”和“值 3” )?

//*[local-name()='element'][*[local-name()='A']='4']/*[local-name()='B']/text()

谢谢你。任何帮助将不胜感激!

4

3 回答 3

5

试试这个:

//*[local-name() = 'element']/*[local-name() = 'A' and (. = 4 or . = 5)]
    /../*[local-name() = 'B']

此表达式选择Value 2Value 3

于 2012-11-19T23:06:37.737 回答
3

处理命名空间的正确方法是将它们注册到您的 XPath API 并...在 XPath 表达式中使用它们:

使用

//x:element[x:A = 4 or x:A = 5]/x:B

基于 XSLT 的验证

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:x="some:default NS">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:template match="/">
     <xsl:copy-of select="//x:element[x:A = 4 or x:A = 5]/x:B"/>
 </xsl:template>
</xsl:stylesheet>

当此转换应用于以下 XML 文档(提供的片段,由具有默认命名空间定义的单个顶部元素包装)时:

<t xmlns="some:default NS">
    <element>
        <A>3</A>
        <B>Value 1</B>
    </element>
    <element>
        <A>4</A>
        <B>Value 2</B>
    </element>
    <element>
        <A>5</A>
        <B>Value 3</B>
    </element>
</t>

对 XPath 表达式求值,并将该求值的结果(选定节点)复制到输出

<B xmlns="some:default NS">Value 2</B>
<B xmlns="some:default NS">Value 3</B>
于 2012-11-19T23:32:35.973 回答
1

您可以嵌套谓词。

//*[
  local-name() = 'element' and *[local-name() = 'A' and (. = 4 or . = 5)]
]/*[
  本地名称() = 'B'
]/文本()

但实际上您应该使用命名空间感知 XPath:

//ns1:element[ns2:A[. = 4 or . = 3]]/ns2:B/text()
于 2012-11-19T23:07:38.437 回答