Quite often while implementing SOAP based service we need to traverse xpath.
So, my XSD looks like this;
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:tns="myorg.xml.com" targetNamespace="myorg.xml.com">
<element name="employeeDetails">
<complexType >
<sequence>
<element name="employee" type="tns:Employee" minOccurs="1" maxOccurs="unbounded"/>
</sequence>
</complexType>
</element>
<complexType name="Employee">
<sequence>
<element name="employeeId" type="int" />
<element name="employeeName" type="string" />
<element name="department" type="tns:Department"/>
<element name="EmployeeDesignation" type="tns:Designation"/>
</sequence>
</complexType>
<complexType name="Department">
<sequence>
<element name="departmentId" type="int" />
<element name="departmentName" type="string" />
</sequence>
</complexType>
<simpleType name="Designation">
<restriction base="string">
<enumeration value="Associate"/>
<enumeration value="Software Engineer"/>
<enumeration value="Senior Software Engineer"/>
<enumeration value="Manager"/>
<enumeration value="Executive"/>
</restriction>
</simpleType>
</schema>
And a sample XML:
<?xml version="1.0" encoding="UTF-8"?>
<tns:employeeDetails xmlns:tns="myorg.xml.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="myorg.xml.com Employee.xsd ">
<employee>
<employeeId>230</employeeId>
<employeeName>Jim</employeeName>
<department>
<departmentId>1</departmentId>
<departmentName>IT</departmentName>
</department>
<EmployeeDesignation>Associate</EmployeeDesignation>
</employee>
<employee>
<employeeId>231</employeeId>
<employeeName>Tim</employeeName>
<department>
<departmentId>12</departmentId>
<departmentName>Admin</departmentName>
</department>
<EmployeeDesignation>Manager</EmployeeDesignation>
</employee>
</tns:employeeDetails>
JXPath (http://commons.apache.org/jxpath/) provides APIs for traversal of graphs of JavaBeans, DOM and other types of objects using the XPath syntax. Both child and attribute axis of a node is mapped to Java Beans Properties.
Below is the code to be used for xpath.
private Object traverseXpath(EmployeeDetails details , String xpath){
JXPathContext context = JXPathContext.newContext(details);
return context.getValue(xpath);
}
JXPath supports indexed properties according to the JavaBeans specification. Hence following xpath
Employee employee = (Employee)consumeDetails.traverseXpath(employeeDetails, "employee[1]");
System.out.println(employee.getEmployeeName());
will return the EmployeeName of first object in the list of employee. Output will be “Jim”
Few points to be taken care:
1. In XPath the first element of a collection has index 1, not 0.
2. The node names in xpath should be as per the generated JAXB classes not the xml.
Example:
In the above XSD inside Employee complex type we have following element
<element name="EmployeeDesignation" type="tns:Designation"/>
When classes are generated using XJC command we will have following property inside Employee Class
@XmlElement(name = "EmployeeDesignation", required = true)
protected Designation employeeDesignation;
but in XML we will have following node
<EmployeeDesignation>Associate</EmployeeDesignation>
Following code
Object obj = consumeDetails.traverseXpath(employeeDetails, "employee[1]/EmployeeDesignation");
System.out.println(obj);
Will shoot JXPathNotFoundException.
But below code will
Object obj = consumeDetails.traverseXpath(employeeDetails, "employee[1]/EmployeeDesignation");
System.out.println(obj);
Generate output as “Associate” ,as expected
1 comment:
Awesome post. I am so thankful to you for sharing this code. I have been working on it but is getting error. I tried many times but my code is still giving error.
digital signature certificate
Post a Comment