Nokogiri/Xpath Namespace Query

Nokogiri/Xpath namespace query

All namespaces need to be registered when parsing. Nokogiri automatically registers namespaces on the root node. Any namespaces that are not on the root node you have to register yourself. This should work:

puts doc.xpath('//dc:title', 'dc' => "URI")

Alternately, you can remove namespaces altogether. Only do this if you are certain there will be no conflicting node names.

doc.remove_namespaces!
puts doc.xpath('//title')

How to use xmlns declarations with XPath in Nokogiri

That XPath query looks for elements that are not in any namespace. You need to tell your XPath processor that you are looking for elements in the http://sdb.amazonaws.com/doc/2007-11-07/ namespace.

One way to do that with Nokogiri is:

doc = Nokogiri::XML.parse(...)
doc.xpath("//aws:Item/aws:Attribute[Name='Foo']/aws:Value", {"aws" => "http://sdb.amazonaws.com/doc/2007-11-07/"})

Syntax error about XPath in Nokogiri, when combining namespace and node()

Different from elements, you don't need to use a namespace prefix to match by node(). The following will return all nodes in any namespace just fine:

result = xml_doc.xpath("//node()")

There are several types of nodes in XPath, namely text node, comment node, element node, so on. node() is a node tests which simply returns true for any node type whatsoever. Compare to text() which is another type of node tests that returns true only for text nodes. (See "w3.org > Xpath > Node Tests")

In my understanding, the notion of local name and namespace are only exists in the context of element nodes, so using a namespace prefix along with the node() test simply doesn't make sense.

If you meant to select all elements in a specific namespace use * instead of node():

result = xml_doc.xpath("//x:*", 'x' => 'www.example.com')

XPATH in Nokogiri

You can use data.remove_namespaces! ( see http://www.rubydoc.info/github/sparklemotion/nokogiri/Nokogiri/XML/Document:remove_namespaces! ). Then this query works:

data.xpath('/Envelope/Body/findResponse/result/service.SapEgrQosQueueStatsLogRecord')

How do I get Nokogiri to understand my namespaces?

It doesn't look like the namespaces in this document are correctly declared - there should be xmlns:samlp and xmlns:saml attributes on the root node. In cases like this, Nokogiri essentially ignores the namespaces (as it can't map them to URIs or URNs), so your XPath works if you remove them, i.e.

doc.xpath(XPATH_QUERY)

Undefined namespace prefix in Nokogiri and XPath

I'm not sure why, but it seems that you have to drop the namespace prefix to get the node:

xmlfeed.at_xpath("//totalresults")

Also note that I added the double forward slash, which scopes the search over the whole document (it won't work without it).

UPDATE:

Based on this answer: How do I get Nokogiri to understand my namespaces? I'd guess that the namespace (openSearch:totalResults) is not correctly declared as an attribute on the root node of the document, and hence Nokogiri is just ignoring it, which is why the selector above works but the namespaced one doesn't.

XML Namespace issue with Nokogiri

Because Nokogiri requires you to register the XML namespaces you are querying within (read more about XML Namespaces). But you should still be able to query the element if you specify its namespace when calling at_css. To see the exact usage, check out the css method documentation. It should end up looking something like this:

document.at_css "world", 'namespace_name' => 'namespace URI'

Xpath doesn't return anything in Nokogiri

Your XML is in the namespace some_namespace but your XPaths don't have a namespace binding. You're essentially querying different elements than are in your XML.

Using "Clark notation", the element you're trying to get to is

{some_namespace}ShortMessage

but you're querying for ShortMessage in the no-namespace.

Just because there is no prefix, i.e. the namespace is the default namespace, doesn't mean you can ignore it.



Related Topics



Leave a reply



Submit