Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find elements by attribute namespace in XPath

I'm trying to use XPath to find all elements that have an element in a given namespace.

For example, in the following document I want to find the foo:bar and doodah elements:

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:foo="http://foo.example.com">
  <foo:bar quux="value">Content</foo:bar>
  <widget>Content</widget>
  <doodah foo:quux="value">Content</doodah>
</root>

I know I can use the following XPath expression to load all attributes from a given namespace:

"//@*[namespace-uri()='http://foo.example.com']"

However:

  • This doesn't give me the elements, just the attributes.
  • Where elements contain multiple attributes from that namespace, this selector will return a result per-attribute rather than per-element

Is it possible to get what I want, or do I have to gather the attributes and calculate the unique set of elements they correspond to?

like image 710
Gareth Avatar asked Feb 09 '09 19:02

Gareth


People also ask

How does XPath handle namespace?

XPath queries are aware of namespaces in an XML document and can use namespace prefixes to qualify element and attribute names. Qualifying element and attribute names with a namespace prefix limits the nodes returned by an XPath query to only those nodes that belong to a specific namespace.

Can a namespace have attribute?

The namespace can be defined by an xmlns attribute in the start tag of an element. The namespace declaration has the following syntax. xmlns:prefix="URI".


3 Answers

Use:

//*[namespace-uri()='yourNamespaceURI-here'    or     @*[namespace-uri()='yourNamespaceURI-here']    ] 

the predicate two conditions are or-ed with the XPath or operator.

The XPath expression thus selects any element that either:

  • belongs to the specified namespace.
  • has attributes that belong to the specified namespace.
like image 120
Dimitre Novatchev Avatar answered Oct 05 '22 07:10

Dimitre Novatchev


I'm not sure if this is what you mean, but by only deleting one char in your XPath you get all elements in a certain namespace:

//*[namespace-uri()='http://foo.example.com'] 
like image 21
jor Avatar answered Oct 05 '22 06:10

jor


You could try

//*[namespace-uri()='http://foo.example.com' or @*[namespace-uri()='http://foo.example.com']]

It will give you element foo:bar and element doodah (if you change tal:quux to foo:quux in your XML-data):

<?xml version="1.0" encoding="UTF-8"?>
<root xmlns:foo="http://foo.example.com" xmlns:tal="xxx">
  <foo:bar quux="value">Content</foo:bar>
  <widget>Content</widget>
  <doodah foo:quux="value">Content</doodah>
</root>

Is that what you want?

like image 30
Johannes Weiss Avatar answered Oct 05 '22 08:10

Johannes Weiss