简体   繁体   English

如果有许多同名的父节点,如何从xml的父节点中选择所有子节点?

[英]How to select all child nodes from a parent node from xml if there are many parents node with same name?

 <?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> 

Question: I have that xml, which will come to me from external system ,it can have large number of invoice nodes and one invoice node can have large number of 'code' nodes. 问题:我有一个xml,它将从外部系统传给我,它可以具有大量的invoice节点,而一个invoice节点可以具有大量的“代码”节点。 I want to read the code nodes of all 'invoice' nodes and save them in an array like this : 我想读取所有“发票”节点的code节点,并将其保存在这样的数组中:

invoice[1].code[1]=ABC 
invoice[1].code[2]=123 
invoice[2].code[1]=DEF

How to do this using XPathExpression in JAVA. 如何在JAVA中使用XPathExpression做到这一点。 My code is below which is not working. 我的代码在下面不起作用。

expr = xpath.compile("//invoices/invoice/obs/ob/code/text()");

 result1=expr.evaluate(dc, XPathConstants.NODESET);

nodes =(NodeList)result1;

Please give some general solution in case of number of nodes are high. 如果节点数很多,请给出一些一般的解决方案。

It will give both as there are two invoices try to give id to your xml like 它会同时给出两个发票,因为有两个发票会尝试给您的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> 

then 然后

 expr = xpath.compile("//invoices[@name='invoice1']/invoice/obs/ob/code/text()"); 

There are 2 nodes where your xpath passes. xpath通过2个节点。 You can try this. 你可以试试看

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

您可以尝试以下xpath:

//invoices/invoice[descendant::code[.='ABC']]/obs/ob/code

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM