2013-12-03 3 views
1

Мне нужно создать запрос на JAXB сгенерированный объект, используя JXPath. Код пробной ниже генерирует следующее сообщение об ошибке: исключение в потоке "основного" org.apache.commons.jxpath.JXPathNotFoundException: Нет значения для XPath: // р: OrderDetailJXPath с несколькими пространствами имен

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> 

испытание ...

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; 
} 

XML-файл был взят из: http://www.liquid-technologies.com/Tutorials/XmlSchemas/XsdTutorial_04.aspx

Любые идеи, которые бы мне точку в правильном направлении, чтобы исправить это будет apreacitaed?

+0

Неверно настроен ли ваш объект 'Покупка'? Он содержит данные XML? Кроме того, вы уверены, что результаты для запроса 'CustomerDetails' должны быть возвращены как объект' OrderType' (если это так, разместите соответствующие части вашего дерева объектов)? Если ответ на все вышеизложенное да, попробуйте 'List CustomerDetails = ctx.selectNodes (« p: CustomerDetails »);' –

+0

. Не будет ли jxpath знать пространства имен, так как вы используете jxpath для структуры немаршаллированных объектов? – Taylor

+0

@AnthonyAccioly выглядит как мой объект Purchase unmarshalled правильно, так как я могу назвать его напрямую с результатом. Однако я получаю пустой массив, вызывая: List jlist = (Список ) jctx.selectNodes ("// p: OrderDetail"); как вы предположили. Все еще застряли. Направься на помощь Антония. – UESer

ответ

0

Поскольку вы строите JXPathContext из unmarshalled дерева объектов (в отличие от его построения непосредственно из XML Document или Element), вы не должны беспокоиться о пространствах имен.

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() 
Смежные вопросы