That's because your XML document uses a namespace. XPath is really annoying with namespaces. To confirm this, strip the two xmlns=http://.../v1
from the document and run your XPath expression agains the unnamespaced, unverifiable XML file. It'll match.
What's happening is that your XPath expression tries to select /xyzevent
, when your document contains {http://.../v1}:xyzevent
, which is not the same thing.
There are various ways around this problem. The proper way is to set up a NamespaceContext
so you can use the prefix:localName
notation in your XPath expression and have the prefixes be resolved to the correct URI. There's a short blurb about this in the xerces docs and some more elsewhere on StackOverflow. There's an extensive description at ibm.com.
Your NamespaceContext
will contain two (or more) mappings:
{
event => http://www.xyz.com/common/xyzevent/v1
source => http://www.xyz.com/common/xyzevent/source/v1
}
Your XPath expression can then become /event:xyzevent/source:subscription/source:receiver/.../text()
.
As a nasty workaround, you can rewrite your xpath expression to select using the local-name()
function:
/*[local-name()='xyzevent']/*[local-name()='subscription'/ ...
In this case, the expression matches any element whose local name is xyzevent
, regardless of namespace URI.