【问题标题】:JXPath with multiple namespaces具有多个名称空间的 JXPath
【发布时间】:2013-12-03 20:39:16
【问题描述】:

我需要使用 JXPath 在 JAXB 生成的对象上创建一个查询。下面的试用代码生成以下错误:线程“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>

试用...

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

有什么想法可以为我指明正确的方向来解决这个问题吗?

【问题讨论】:

  • 您的Purchase 对象是否已正确解组?它是否包含 XML 数据?另外,您确定CustomerDetails 查询的结果应该作为OrderType 对象返回(如果是,请发布对象树的相关部分)?如果以上所有答案都是肯定的,请尝试List CustomerDetails = ctx.selectNodes("p:CustomerDetails");
  • jxpath 是否会知道命名空间,因为您正在针对未编组的对象结构运行 jxpath?
  • @AnthonyAccioly 看起来我的 Purchase 对象已正确解组,因为我可以直接使用结果调用它。但是,我通过调用得到一个空数组: List jlist = (List) jctx.selectNodes("//p:OrderDetail");正如你所建议的。还是卡住了。非常感谢安东尼的帮助。
  • @UESer 我很确定您的Purchase 包含订单详细信息列表。所以你根本不需要低效的//(可以用/nameOfYourOrderDetailList代替。如果你可以发布你的购买对象的相关部分,包括你的订单详细信息列表的getter,我们也许可以进一步协助你。
  • @AnthonyAccioly Purchase.getOrderDetail() 方法返回一个 OrderType 对象。关于“/”的好点,但我徒劳地尝试了多个 xpath 查询。如果您需要更多详细信息,请告诉我。如果有任何帮助,可以在此处找到 xml/xsd 文件的详细信息:liquid-technologies.com/Tutorials/XmlSchemas/….

标签: java xml namespaces jaxb jxpath


【解决方案1】:

由于您是在未编组的对象树中构造 JXPathContext(而不是直接从 xml DocumentElement 构造它),因此您不必担心命名空间。

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()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-16
    • 1970-01-01
    相关资源
    最近更新 更多