0

I a started to use xml.jcabi xml library. It looks like a simple library but I am not able to query nodes if xmlns namespace is set.

Here is my xml file:

<MyRequestData xmlns='http://www.myaddress.com/myfile.xsd' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'>
  <RequestData>
    <startDate>2016-03-25</startDate>
    <endDate>2016-03-25</endDate>
  </RequestData>
</MyRequestData>

And my Java code looks like this:

XML xmlRequest = new XMLDocument(requestFileIS);
xmlRequest.registerNs("xmlns", "http://www.myaddress.com/myfile.xsd");    
for (XML requestData : xmlAdHocRequest.nodes("//xmlns:RequestData")) 
{
    String startDate = requestData.xpath("startDate/text()").get(0);
}

My problem is that xmlAdHocRequest.nodes("//xmlns:RequestData") returns zero nodes. If I remove the default namespace from the XML file and (obviously) from NS register than the query works.

I also tried to register the xmlns (default) namespace by setting its prefix to m istead of xmlns:

XML xmlAdHocRequest = new XMLDocument(requestFileIS);
xmlRequest.registerNs("m", "http://www.myaddress.com/myfile.xsd");    

for (XML requestData : xmlRequest.nodes("//m:RequestData")) {
    String startDate = requestData.xpath("startDate/text()").get(0);
}

When i try to fetch nodes I only got an error:

java.lang.IllegalArgumentException: invalid XPath query '//x:RequestData' by org.apache.xpath.jaxp.XPathFactoryImpl
    at org.apache.xpath.compiler.XPathParser.errorForDOM3(XPathParser.java:655)
    at org.apache.xpath.compiler.Lexer.mapNSTokens(Lexer.java:647)
    at org.apache.xpath.compiler.Lexer.tokenize(Lexer.java:365)
    at org.apache.xpath.compiler.Lexer.tokenize(Lexer.java:98)
    at org.apache.xpath.compiler.XPathParser.initXPath(XPathParser.java:112)
    at org.apache.xpath.XPath.<init>(XPath.java:178)
    at org.apache.xpath.XPath.<init>(XPath.java:266)
    at org.apache.xpath.jaxp.XPathImpl.eval(XPathImpl.java:195)
    at org.apache.xpath.jaxp.XPathImpl.evaluate(XPathImpl.java:281)
    at com.jcabi.xml.XMLDocument.fetch(XMLDocument.java:429)
    at com.jcabi.xml.XMLDocument.nodes(XMLDocument.java:352)

My question is: am I doing something wrong or is this some kind of xml.jcabi issue?

Gico
  • 1,276
  • 2
  • 15
  • 30
  • Your error message does not agree with your source code regarding the XPath. – kjhughes Mar 16 '17 at 19:15
  • I appreciate your help. I update the question. I am trying to hide my project related data. What you saw in the stack trace, it was just something that sneaked in. I am positive that the code is correct. It seems that the trick with fiction namespace just doesn't work. I have been able to select the nodes by defining xmlRequest.nodes("//*[local-name()='RequestData']"), however this is an awful sollution. – Gico Mar 16 '17 at 23:02
  • *I am positive that the code is correct* is inconsistent with your code not working, so you'll have to forgive us if we don't believe you. – kjhughes Mar 16 '17 at 23:10
  • Without a [mcve] to go on, the best we can recommend is that you see the duplicate link. Good luck. – kjhughes Mar 16 '17 at 23:12
  • Just as a proof i am attaching an image with full source code published here, exception stack trace and xml content. http://i65.tinypic.com/2s151rn.png – Gico Mar 17 '17 at 07:37

1 Answers1

0

Define a namespace prefix (xmlns= defines a default namespace -- not a namespace prefix) and then use it in your XPaths.

Specifically...

Change

xmlRequest.registerNs("xmlns", "http://www.myaddress.com/myfile.xsd");

to

xmlRequest.registerNs("m", "http://www.myaddress.com/myfile.xsd");

Change

//xmlns:RequestData

to

//m:RequestData
kjhughes
  • 106,133
  • 27
  • 181
  • 240
  • Hi @kjhughes. Thanks for feedback. I tried that but i am getting an error: java.lang.IllegalArgumentException: invalid XPath query '//m:RequestData' by org.apache.xpath.jaxp.XPathFactoryImpl – Gico Mar 16 '17 at 16:08
  • Show your call to `registerNs` for `m`. – kjhughes Mar 16 '17 at 16:20
  • Hi! Here is the code snippet: XML xmlAdHocRequest = new XMLDocument(requestFileIS); xmlRequest.registerNs("m", "http://www.myaddress.com/myfile.xsd"); for (XML requestData : xmlRequest.nodes("//m:RequestData")) { String startDate = requestData.xpath("startDate/text()").get(0); } – Gico Mar 16 '17 at 16:31
  • The namespace URI that you register via `registerNs()` has to agree with that declared in the XML. Yours does not. – kjhughes Mar 16 '17 at 16:47
  • Hi @kjhughess. It seems the stackoverflow removed the http :// www from the comment. In code i have the correct address. – Gico Mar 16 '17 at 17:33
  • Please update your question with a [mcve] that exhibits the problem. – kjhughes Mar 16 '17 at 18:33
  • I finally got a correct solution to my answer. jaxbi's XMLDocument is immutable. To apply a namespace, you must chain the calls. The call should be done like this: XML xmlAdHocRequest = new XMLDocument(requestFileIS).registerNs("m", "http://www.myaddress.com/myfile.xsd"); – Gico Apr 07 '17 at 21:30