I need to create a query on a JAXB generated object using JXPath. The trial code below generates the following error: Exception in thread "main" org.apache.commons.jxpath.JXPathNotFoundException: No value for xpath: //p:OrderDetail
Purchase.xml
<?xml version="1.0"?>
<!-- Created with Liquid XML Studio 0.9.8.0 (http://www.liquid-technologies.com) -->
<p:Purchase xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://NamespaceTest.com/Purchase Main.xsd"
xmlns:p="http://NamespaceTest.com/Purchase"
xmlns:o="http://NamespaceTest.com/OrderTypes"
xmlns:c="http://NamespaceTest.com/CustomerTypes"
xmlns:cmn="http://NamespaceTest.com/CommonTypes">
<p:OrderDetail>
<o:Item>
<o:ProductName>Widget</o:ProductName>
<o:Quantity>1</o:Quantity>
<o:UnitPrice>3.42</o:UnitPrice>
</o:Item>
</p:OrderDetail>
<p:PaymentMethod>VISA</p:PaymentMethod>
<p:CustomerDetails>
<c:Name>James</c:Name>
<c:DeliveryAddress>
<cmn:Line1>15 Some Road</cmn:Line1>
<cmn:Line2>SomeTown</cmn:Line2>
</c:DeliveryAddress>
<c:BillingAddress>
<cmn:Line1>15 Some Road</cmn:Line1>
<cmn:Line2>SomeTown</cmn:Line2>
</c:BillingAddress>
</p:CustomerDetails>
</p:Purchase>
trial...
JAXBContext ctx = JAXBContext.newInstance(ObjectFactory.class);
Unmarshaller um = ctx.createUnmarshaller();
Purchase purchase = (Purchase) um.unmarshal(new File("Purchase.xml"));
JXPathContext jctx = JXPathContext.newContext(purchase);
jctx.registerNamespace("p", "http://NamespaceTest.com/OrderTypes");
OrderType cust = (OrderType) jctx.getValue("//p:OrderDetail");
System.out.println(cust.getItem());
Purchase.java
@XmlRootElement(name = "Purchase")
public class Purchase {
@XmlElement(name = "OrderDetail", required = true)
protected OrderType orderDetail;
/**
* Gets the value of the orderDetail property.
*
* @return
* possible object is
* {@link OrderType }
*
*/
public OrderType getOrderDetail() {
return orderDetail;
}
The xml file was taken from: http://www.liquid-technologies.com/Tutorials/XmlSchemas/XsdTutorial_04.aspx
Any ideas that would point me in the right direction to fix this would be apreacitaed?
Since you are constructing a JXPathContext
out of a unmarshalled object tree (as opposed to constructing it directly from a xml Document
or Element
) you should not worry about namespaces.
JXPathContext context = JXPathContext.newContext(purchase);
OrderType orderDetail = (OrderType) context.getValue("orderDetail");
// equivalent to purchase.getOrderDetail()
for(Iterator iter = context.iterate("/orderDetail/items"); iter.hasNext()){
Item i = (Item) iter.next();
//...
}
// Assumes that OrderType has a items property
// List<Item> getItems()