Namespace agnostic XPath query with element content

本秂侑毒 提交于 2019-11-30 21:15:50
Dimitre Novatchev

The namespace agnostic syntax I've seen around is confusing me.

First, I would advise you not to use this syntax, especially if it is confusing. It can also result in errors -- see the end of my answer for details.

The standard way to specify in an XPath expression names that are in a namespace is to register a namespace with your XPath engine (see the respective, vendor-specific documentation) and then to use the prefix bound to the registered namespace (say "x") with names like x:someName

There are plenty of good answers on this topic -- jus t use one of them.

Now, if due to some reason you still decide to use the confusing syntax, then:

but i'm struggling with things like this:

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

Use:

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

then:

or:

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

Use:

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

then:

or:

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

Use:

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

then:

One More :-)

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

How does this translate?

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

Use:

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

Do note:

Such expressions may not select the wanted nodes if in the XML documents there are elements with the same local-name that belong to two different namespaces.

I understand your question to mean, how do I make these XPath expressions namespace-agnostic? (It's not a special syntax, just a typical use of the local-name() function.)

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

would become

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

(You could use double-quotes for the attribute value if you want, but that would make it harder to embed in XSLT or whatever your environment is.)

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

would become

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

And

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

would become

/*[local-name()='root']/*[local-name()='parent'][1]/*[local-name()='child']/text()
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!