与元素内容无关的命名空间XPath查询

时间:2011-02-10 04:10:52

标签: xpath namespaces default xml-namespaces

我见过的名称空间不可知语法令我感到困惑。

说我有:

<root>
  <parent attribute="A">A<child>A</child></parent>
  <parent attribute="B">B<child>B</child></parent>
</root>

到目前为止,我看到了:

/root/parent/child/text()

转换为:

/*[local-name()='root']/*[local-name()='parent']/*[local-name()='child']/text()

但我正在努力解决这个问题:

/root/parent[@attribute="A"]/child/text()

或:

/root/parent[text()="B"]/child/text()

或:

/root/parent[1]/child/text()

这些是如何翻译的?

谢谢,

编辑:再一次: - )

<root>
        <parent>
            <childName>serverName</childName>
            <childValue>MyServer</childValue>
        </parent>
        <parent>
            <childName>ServerLocation</childName>
            <childValue>Somewhere</childValue>
         </parent>
</root>

这是如何翻译的?

/root/parent[childName="serverName"]/childValue/text()

2 个答案:

答案 0 :(得分:10)

  

命名空间不可知的语法我   看到周围让我感到困惑。

首先,我建议你使用这种语法,特别是如果它令人困惑的话。它也可能导致错误 - 请参阅我的答案的结尾。

在命名空间中指定XPath表达式名称的标准方法是使用XPath引擎注册命名空间(请参阅相应的特定于供应商的文档),然后使用绑定到已注册命名空间的前缀(比如说“x”),其名称为x:someName

关于这个主题有很多好的答案 - 不要使用其中一个。

现在,如果由于某种原因你仍然决定使用令人困惑的语法,那么:

  但是我正在努力解决这些问题   这样:

     

/root/parent[@attribute="A"]/child/text()

使用

/*[local-name()='root']/*[local-name()='parent' and @attribute='A']

然后:

  

或:

     

/root/parent[text()="B"]/child/text()

使用

/*[local-name()='root']/*[local-name()='parent' and text()='B']
                                    /*[local-name()='child']/text()

然后:

  

或:

/root/parent[1]/child/text()

使用

/*[local-name()='root']/*[local-name()='parent'][1]
                                 /*[local-name()='child']/text()

然后:

  

再一次: - )

<root>
  <parent>
      <childName>serverName</childName>
      <childValue>MyServer</childValue>
  </parent>
  <parent>
      <childName>ServerLocation</childName>
      <childValue>Somewhere</childValue>
  </parent>
</root>
     

这是如何翻译的?

/root/parent[childName="serverName"]/childValue/text()

使用

/*[local-name()='root']
      /*[local-name()='parent'][*[local-name()='childName"]='serverName']
                                           /*[local-name()='childValue']/text()

请注意

如果在XML文档中存在属于两个不同名称空间的具有相同本地名称的元素,则此类表达式可能无法选择所需节点。

答案 1 :(得分:4)

我理解您的问题是什么意思,我如何使这些XPath表达式与命名空间无关? (这不是一种特殊的语法,只是local-name()函数的典型用法。)

/root/parent[@attribute="A"]/child/text()

会变成

/*[local-name()='root']/*[local-name()='parent'][@attribute='A']/*[local-name()='child']/text()

(如果需要,可以使用双引号作为属性值,但这会使嵌入XSLT或您的环境更加困难。)

/root/parent[text()="B"]/child/text()

会变成

/*[local-name()='root']/*[local-name()='parent'][text() = 'B']/*[local-name()='child']/text()

/root/parent[1]/child/text()

会变成

/*[local-name()='root']/*[local-name()='parent'][1]/*[local-name()='child']/text()