| Make JXPATH 1.2 namespace aware |
|
|
| Wednesday, 30 April 2008 10:49 | ||||||||
|
Some hours of hard work to find a workaround for this issue...I hope that it will help some of you Here is a sample xml that reveal the issue (sample.xml): 1: <?xml version="1.0" encoding="UTF-8"?> 2: <address xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3: xmlns="http://www.example.com/test" 4: xsi:schemaLocation="http://www.example.com/test sample.xsd"> 5: <name>name</name> 6: <street>street</street> 7: <city>city</city> 8: <country>country</country> 9: </address> A very simple XSD schema (sample.xsd) 1: <?xml version="1.0" encoding="UTF-8" standalone="no"?> 2: <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 3: targetNamespace="http://www.example.com/test" 4: xmlns="http://www.example.com/test"> 5: <xs:element name="address"> 6: <xs:complexType> 7: <xs:sequence> 8: <xs:element name="name" type="xs:string" /> 9: <xs:element name="street" type="xs:string" /> 10: <xs:element name="city" type="xs:string" /> 11: <xs:element name="country" type="xs:string" /> 12: </xs:sequence> 13: </xs:complexType> 14: </xs:element> 15: </xs:schema> And a simple java client, using JUNIT4 1: import java.io.InputStream;
2:
3: import javax.xml.parsers.DocumentBuilder;
4: import javax.xml.parsers.DocumentBuilderFactory;
5:
6: import org.apache.commons.jxpath.JXPathContext;
7: import org.junit.Assert;
8: import org.junit.Test;
9: import org.w3c.dom.Document;
10:
11: public class JXpath12NameSpaceIssue{ 12:
13: @Test 14: public void testCountNonWorkingXML() { 15: InputStream xmlStream = this.getClass().getResourceAsStream("/sample.xml"); 16:
17: try { 18: JXPathContext context = this.getJXPathContext(xmlStream); 19: Double value = (Double)context.getValue("count(//name)"); 20: Assert.assertEquals(1, value, 0.0);
21: } catch (Exception e) { 22: Assert.fail(e.getMessage());
23: }
24: }
25:
26: public JXPathContext getJXPathContext(InputStream inputStream) { 27: try { 28: DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
29: factory.setValidating(false); //This is for xml with DTD only! 30: factory.setNamespaceAware(true); //if namespace in xml, make no difference if true or false 31: factory.setFeature("http://apache.org/xml/features/validation/schema", true); 32:
33: DocumentBuilder builder = factory.newDocumentBuilder();
34: builder.setErrorHandler(new JXPathErrorHandler()); 35:
36: Document document = builder.parse(inputStream);
37: JXPathContext context = JXPathContext.newContext(document);
38:
39: context.setLenient(true); 40: return context; 41: } catch (Throwable throwable) { 42: throwable.printStackTrace();
43: }
44: return null; 45: }
This line Double value = (Double)context.getValue("count(//name)"); will always make the
As soon as You remove the namespace from the XML file 1: <?xml version="1.0" encoding="UTF-8"?> 2: <address xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3: 4: xsi:schemaLocation="http://www.example.com/test sample.xsd">
The code will return the correct value aka 1.0. The explanation has been found on internet thanks to Google
More can also be read here
So you should end up with: 1: Document document = builder.parse(inputStream);
2: JXPathContext context = JXPathContext.newContext(document);
3: context.registerNamespace("schema", "http://www.example.com/test"); 4: Double value = (Double)context.getValue("count(//schema:name)"); You can also go another way, and remove any namespace by forcing JAXB2 to
In com.example.xml.jaxb.package-info.java.package-info.java go from
1: @javax.xml.bind.annotation.XmlSchema
2: (namespace = "http://www.example.com/test", 3: elementFormDefault = javax.xml.bind.annotation.XmlNsForm.UNQUALIFIED)
4: package com.example.test;
Powered by !JoomlaComment 3.20
3.20 Copyright (C) 2007 Alain Georgette / Copyright (C) 2006 Frantisek Hliva. All rights reserved." |
||||||||


























yes it should be if ($hasSecurityIma...
components\com_maxcomment\max...
use search of my site, there is more ...