<?xml version="1.0" encoding="UTF-8"?>
<invoice>
<obs>
<ob>
<code>ABC</code>
</ob>
<ob>
<code>123</code>
</ob>
</obs>
</invoice>
<invoice>
<obs>
<ob>
<code>DEF</code>
</ob>
</obs>
</invoice>
</invoices>
&#13;
问题:
我有来自外部系统的xml,它可以有大量invoice
个节点,一个invoice
节点可以有大量的代码&#39;节点。我想阅读所有&#39;发票的code
个节点&#39;节点并将它们保存在这样的数组中:
invoice[1].code[1]=ABC
invoice[1].code[2]=123
invoice[2].code[1]=DEF
如何在JAVA中使用XPathExpression执行此操作。我的代码在下面不起作用。
expr = xpath.compile("//invoices/invoice/obs/ob/code/text()");
result1=expr.evaluate(dc, XPathConstants.NODESET);
nodes =(NodeList)result1;
如果节点数很高,请给出一些通用解决方案。
答案 0 :(得分:0)
它会同时给出两个发票,试着给你的xml提供id,如
<invoices>
<invoice name="invoice1">
<obs>
<ob>
<code>ABC</code>
</ob>
</obs>
</invoice>
<invoice name="invoice2">
<obs>
<ob>
<code>DEF</code>
</ob>
</obs>
</invoice>
</invoices>
&#13;
然后
expr = xpath.compile("//invoices[@name='invoice1']/invoice/obs/ob/code/text()");
&#13;
答案 1 :(得分:0)
xpath传递了2个节点。你可以试试这个。
String xml = "<invoices><invoice><obs><ob><code>ABC</code></ob><ob><code>111</code></ob></obs></invoice><invoice><obs><ob><code>DEF</code></ob></obs></invoice></invoices>";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder =factory.newDocumentBuilder();
Document document = builder.parse(new InputSource(new StringReader(xml)));
XPathFactory xpathFactory = XPathFactory.newInstance();
Map<String,List<String>> invoiceCodeMap = new LinkedHashMap<>();
XPathExpression invoiceXpathExp = xpathFactory.newXPath().compile("//invoices/invoice");
NodeList invoiceNodes = (NodeList) invoiceXpathExp.evaluate(document, XPathConstants.NODESET);
//Iterate Invoice nodes
for(int invoiceIndex=0;invoiceIndex<invoiceNodes.getLength();invoiceIndex++){
String invoiceID = "invoice"+(invoiceIndex+1);
List<String> codeList = new ArrayList<>();
XPathExpression codeXpathExp = xpathFactory.newXPath().compile("obs/ob/code/text()");
NodeList codeNodes = (NodeList) codeXpathExp.evaluate(invoiceNodes.item(invoiceIndex), XPathConstants.NODESET);
for(int codeIndex=0;codeIndex<codeNodes.getLength();codeIndex++){
Node code = codeNodes.item(codeIndex);
codeList.add(code.getTextContent());
}
invoiceCodeMap.put(invoiceID, codeList);
}
System.out.println(invoiceCodeMap);
答案 2 :(得分:0)
你可以尝试这个xpath:
//invoices/invoice[descendant::code[.='ABC']]/obs/ob/code