如何使用java代码迭代xml节点

时间:2015-06-17 14:14:51

标签: java xml

我应该检查<LineItem>是否包含<Tender>(此<Tender>可以位于<LineItem>中的任何一个,此处为此XML中的<LineItem> )。如果存在<Tender>,我应该从第一个开始循环,检查<LineItem>是否包含<Return>

xml如下:

<Transaction>
    <LineItem>
        <Return></Return>
    </LineItem>
    <LineItem>
        <Return></Return>
    </LineItem>
    <LineItem>
        <Return></Return>
    </LineItem>
    <LineItem>
        <Return></Return>
    </LineItem>
    <LineItem>
        <Tender></Tender>
    </LineItem>
</Transaction>

如何遍历XML并检查<Tender>,以及如何从开始迭代到检查<Return>

我已实现为(只是我提供的代码片段,因为它很大)

//Tender Type
    Lineitems = retailChildren.item(j).getChildNodes();
    for(int i2=0;i2<Lineitems.getLength();i2++)
    {
        if(Lineitems.item(i2).getNodeName().equalsIgnoreCase("Tender")){
            System.out.println("Inside Tender");
            //start
            NodeList TenderId=Lineitems.item(i2).getChildNodes();
            TenderId=Lineitems.item(i2).getChildNodes();
            for(int i4=0;i4<TenderId.getLength();i4++){
                if(TenderId.item(i4).getNodeName().equalsIgnoreCase("TenderID")){
                    System.out.println("Inside Tender ID");
                    String TenderID=TenderId.item(i4).getFirstChild().getNodeValue();
                    System.out
                    .println(TenderID);
                    NodeList SaleType=TenderId.item(i2).getChildNodes();
                    //SaleType=TenderId.item(i2).getChildNodes();
                    for(int i3=0;i3<SaleType.getLength();i3++){
                        if(SaleType.item(i3).getNodeName().equalsIgnoreCase("bby:SaleTenderType")){
                            System.out.println("Inside Sale Tender Type");
                            String eCommValue=SaleType.item(i3).getFirstChild().getNodeValue();
                            if(eCommValue.equalsIgnoreCase("Magento")){
                                System.out.println("Inside Magento");

                                Lineitems = retailChildren.item(j).getChildNodes();
                                for (int i1 = 0; i1 < Lineitems.getLength(); i1++) {
                                    if(Lineitems.item(i1).getNodeName().equalsIgnoreCase("Return")){
                                        //Do method
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        // If <Tender> is not present, it should come here
        else
        {
            Lineitems = retailChildren.item(j).getChildNodes();
            for (int i1 = 0; i1 < Lineitems.getLength(); i1++) {
                if(Lineitems.item(i1).getNodeName().equalsIgnoreCase("Return")){
                    //do method
                }
            }

        }//End for for tender type

    }

2 个答案:

答案 0 :(得分:1)

您可以使用XPATH

从xml获取节点

XPath ,XML路径语言,是一种用于从XML文档中选择节点的查询语言。此外,XPath可用于根据XML文档的内容计算值(例如,字符串,数字或布尔值)。 What is Xpath

您的XPath表达式将是

/Transaction/LineItem/Return
boolean(/Transaction/LineItem/Tender)

我假设您将xml作为字符串,因此您需要以下想法

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();    
InputSource inputSource = new InputSource(new StringReader(xml));
Document document = builder.parse(inputSource);
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();

您首先必须通过

检查节点是否存在
Boolean hasTender = (Boolean) expr.evaluate(document, XPathConstants.BOOLEAN);  

只需查找Return个节点

  XPathExpression exprResult = xpath.compile("/Transaction/LineItem/Return");
  NodeList nl = (NodeList) exprResult.evaluate(document, XPathConstants.NODESET);

现在它将简单地遍历每个节点

for (int i = 0; i < nl.getLength(); i++)
{
  System.out.println(nl.item(i).getNodeName());
}

简而言之,以下代码..请记住,您希望将其分解为重用方法。

控制器测试

public class Controller {

  public static void main(String[] args) throws XPathExpressionException, IOException, SAXException, ParserConfigurationException {

    String xml ="<Transaction>\n" +
            "    <LineItem>\n" +
            "        <Return></Return>\n" +
            "    </LineItem>\n" +
            "    <LineItem>\n" +
            "        <Return></Return>\n" +
            "    </LineItem>\n" +
            "    <LineItem>\n" +
            "        <Return></Return>\n" +
            "    </LineItem>\n" +
            "    <LineItem>\n" +
            "        <Return></Return>\n" +
            "    </LineItem>\n" +
            "    <LineItem>\n" +
            "        <Tender></Tender>\n" +
            "    </LineItem>\n" +
            "</Transaction>";

    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();
    InputSource inputSource = new InputSource(new StringReader(xml));
    Document document = builder.parse(inputSource);
    XPathFactory xPathfactory = XPathFactory.newInstance();
    XPath xpath = xPathfactory.newXPath();
    XPathExpression expr = xpath.compile("boolean(/Transaction/LineItem/Tender)");
    Boolean hasTender = (Boolean) expr.evaluate(document, XPathConstants.BOOLEAN);
    if (hasTender)
    {
      XPathExpression exprResult = xpath.compile("/Transaction/LineItem/Return");
      NodeList nl = (NodeList) exprResult.evaluate(document, XPathConstants.NODESET);
      for (int i = 0; i < nl.getLength(); i++)
      {
        System.out.println(nl.item(i).getNodeName());
      }
    }
  }
}

答案 1 :(得分:1)

改用XPath

XPathFactory xpf = XPathFactory.newInstance();
XPath path = xpf.newXPath();
XPathExpression tenderExpr = path.compile("/Transaction//LineItem/Tender");
NodeList tenderNodes = (NodeList)tenderExpr.evaluate(document, XPathConstants.NODESET);
if (tenderNodes.getLength() > 0) {
    // tender was found
} else {
    XPathExpression returnExpr = path.compile("/Transaction//LineItem/Return");
    NodeList returnNodes = (NodeList)returnExpr.evaluate(document, XPathConstants.NODESET);
    // returnNodes has all the elements you wanted, iterate that and see what you can see
}