Hi David

There are numerous threads in the archives explaining this - and it really
should be added to the FAQ ASAP. e.g.

http://www.geocrawler.com/archives/3/8797/2002/2/0/7951539/

In essence any name used in an XPath expression implicitly means match
no-namespace URI. More details below...

> Ok, I think we've gone over this before.  I have a document which has a
> default namespace (I guess that's what it's called) and some other
> namespaces defined:
>
>
> <root xmlns="http://blah blah" xmlns:crap="http://yadda yadda">
>  ....
> </root>
>
> Now, I can use xpath to find nodes in the "crap" namespace, like so:
>
>   //crap:elem[@attr='whatever']
>
> However, I can't use xpath to find default namespace elements, like so:
>
>   //someElem[@attr='poop']

So this means match an element called <someElement> which is in
no-namespace. However someElement in your document is really in the
"http://blah blah" namespace and so it *should* not match.

Matching in XPath / XSLT matches only the namespace URI and the local name
of the elements.

To match a node just based on local name then you can use

//*[local-name()='someElement' and @attr='poop']

Though you should really always match on the namespace URI too. So to do
this you need to create a namespace prefix and bind it to the namespace URI
and use this new prefix in your XPath expression. Note that this prefix may
not even exist at all in your source document, only in the XPath
expressions.

> Why is this?  What code do I use to make the second xpath work?  I've
> tried using SimpleNamespaceContexts and DefaultNamespaceContexts, and
> I'm lost.  HELP!

So this example from

http://dom4j.org/status.html

with details of the dom4j 1.2 release shows how to define some namespace
prefix <-> URI mappings for use in your code...

Map uris = new HashMap();
uris.put( "env", "http://schemas.xmlsoap.org/soap/envelope/"; );
uris.put( "m", "urn:xmethodsBabelFish" );

XPath xpath = document.createXPath( "/env:Envelope/env:Body/m:BabelFish" );
xpath.setNamespaceURIs( uris );
Node element = xpath.selectSingleNode( document );

You can also register your namespace mappings with a DocumentFactory so that
this all happens by default. e.g.

// register prefixes with my factory
Map uris = new HashMap();
uris.put( "env", "http://schemas.xmlsoap.org/soap/envelope/"; );
uris.put( "m", "urn:xmethodsBabelFish" );

// create my own factory
DocumentFactory factory = new DocumentFactory();
factory.setXPathNamespaceURIs( uris );

// now parse a document using my factory
SAXReader reader = new SAXReader();
reader.setDocumentFactory( factory );

Document doc = reader.read( "soap.xml" );

// now lets use the prefixes
// we've defaulted into our factory
Node element = doc.selectSingleNode( "/env:Envelope/env:Body/m:BabelFish" );


I hope that helps clear things up a bit...

James


_________________________________________________________
Do You Yahoo!?
Get your free @yahoo.com address at http://mail.yahoo.com


_______________________________________________
dom4j-user mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/dom4j-user

Reply via email to