简体   繁体   English

Java for循环从xml文档获取子元素

[英]Java for loop to obtain child elements from xml document

I'm getting hard time in figuring how to write a loop to retrieve values from a given XML document for simplicity I'll give you a sample of the xml file 为了简化起见,为了弄清楚如何编写一个循环以从给定的XML文档中检索值,我变得很费力,我将为您提供xml文件的示例

 </solution> <solution> <cost>505.9208295302417</cost> <routes> <route> <driverId>noDriver</driverId> <vehicleId>1_1</vehicleId> <start>0.0</start> <act type="service"> <serviceId>5 </serviceId> <arrTime>109.9819741964403</arrTime> <endTime>119.9819741964403</endTime> </act> <end>229.9639483928806</end> </route> <route> <driverId>noDriver</driverId> <vehicleId>3_1</vehicleId> <start>0.0</start> <act type="service"> <serviceId>4 </serviceId> <arrTime>109.98190391287031</arrTime> <endTime>119.98190391287031</endTime> </act> <act type="service"> <serviceId>2 </serviceId> <arrTime>119.98282618841856</arrTime> <endTime>129.98282618841856</endTime> </act> <act type="service"> <serviceId>1 </serviceId> <arrTime>129.98372097890456</arrTime> <endTime>139.98372097890456</endTime> </act> <act type="service"> <serviceId>3 </serviceId> <arrTime>139.9846432544528</arrTime> <endTime>149.9846432544528</endTime> </act> <end>259.9668316441239</end> </route> </routes> </solution> </solutions> 

so basically what I've in the code that I'll be showing you is to obtain value from only the node where there is cost = 505.9208295302417, please don't take into account this part of the code, so the next step was to retrieve driverid``, vehicleid and act , I know that there is a missing for loop but I don't know where to put it!! 因此,基本上我将向您展示的代码中的内容是仅从有成本= 505.9208295302417的节点获取价值,请不要考虑这部分代码,因此下一步是检索driverid``, vehicleid and act,我知道缺少for循环,但是我不知道将它放到哪里! please can someone help. 请有人帮忙。 The desired output that i need to have is like for every vehicleid obtain list act values associated with it 我需要的期望输出就像每个vehicleid获取与之关联的列表动作值一样

java code Java代码

        public static void main(String[] args) {
        try {
            int totalVehicle;
            totalVehicle = 2;
            File fXmlFile = new File("C:/Users/HP/Desktop/solution.xml");
            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(fXmlFile);
            doc.getDocumentElement().normalize();
            Double requiredCost = 505.9208295302417;
            System.out.println("Root element :" + doc.getDocumentElement().getNodeName());
            // NodeList nList = doc.getElementsByTagName("route");
            System.out.println("----------------------------");
            NodeList nodeList = doc.getElementsByTagName("solution");
            for (int i = 0; i < nodeList.getLength(); i++) {

                Node solutionNode = nodeList.item(i);

                if (solutionNode.getNodeType() == Node.ELEMENT_NODE) {
                    Element solutionElement = (Element) solutionNode;
                    Node costNode = solutionElement.getElementsByTagName("cost").item(0);
                    Node route = solutionElement.getElementsByTagName("routes").item(0);
                    // if correct cost, proceed to parse further
                    Double costValue = Double.valueOf(costNode.getTextContent());
                    if (Double.compare(requiredCost, costValue) == 0) {
                        System.out.println("working");
                        // there you go, found the node with the cost 505.9208295302417
                        // now just parse all the node elements you need here

                        System.out.println("cost : "
                                + solutionElement.getElementsByTagName("cost")
                                        .item(0).getTextContent());
                        for (int h = 0; h < totalVehicle; h++) {
                            System.out.println("DriverId : "
                                    + solutionElement.getElementsByTagName("driverId")
                                            .item(h).getTextContent().toString());
                            System.out.println("vehicleId : "
                                    + solutionElement.getElementsByTagName("vehicleId")
                                            .item(h).getTextContent());
NodeList optionList = solutionElement.getElementsByTagName("act");
                            System.out.println(optionList.getLength());

        for (int j = 0; j < optionList.getLength(); ++j)
        {

            for(int k =0;k<1;++k){
                Element option = (Element) optionList.item(j);
            String optionText = option.getTextContent();
           //address.add(optionText.replaceAll("[^A-Za-z]"," "));
            System.out.println("Citizen :"+optionText.replaceAll("[^A-Za-z]"," "));}
            ;


        }

As others have suggested, using xpath would be much easier but if it's an absolute requirement that you loop over all this stuff, break the problem into smaller, more manageable pieces. 正如其他人所建议的那样,使用xpath会容易得多,但是如果绝对需要您遍历所有这些内容,请将问题分解为更小,更易于管理的部分。 I thought I'd give it a try and I have a complete, working solution to your problem. 我以为可以尝试一下,并且为您的问题提供了完整,有效的解决方案。

The idea is to break xml up into Java objects and use those objects to do the work you need. 这个想法是将xml分解为Java对象,并使用这些对象来完成您需要的工作。

public static void main(String... args) throws SAXException, IOException, ParserConfigurationException {
    Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder()
            .parse(new File("/home/william/Documents/test.xml"));
    doc.getDocumentElement().normalize();

    NodeList nodeList = doc.getElementsByTagName("solution");
    for (int i = 0; i < nodeList.getLength(); i++) {
        Node solutionNode = nodeList.item(i);

        try {
            System.out.println(Solution.newInstance(solutionNode).toString());
        } catch (Exception e) {
            // do something
            e.printStackTrace();
        }   
    }
}

Here, your original document parsed the same way you did it but Solution is its own class you can put the logic in: 在这里,原始文档的解析方式与您处理原始文档的方式相同,但是Solution是其自己的类,您可以将逻辑放入:

public class Solution {

    private final double cost;

    private final Collection<Route> routes;

    public static final Solution newInstance(Node solution) throws Exception {
        return new Solution(solution);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("solution:");
        sb.append(System.lineSeparator());
        sb.append("--------");
        sb.append(System.lineSeparator());
        sb.append("cost:");
        sb.append(this.cost);

        for (Route route : this.routes) {
            sb.append(route.toString());
        }

        return sb.toString();
    }

    private Solution(Node solution) throws Exception {
        if (solution.getNodeType() == Node.ELEMENT_NODE) {
            Element solutionElement = (Element) solution;
            this.cost = Double.valueOf(solutionElement.getElementsByTagName("cost").item(0).getTextContent());
            this.routes = Routes.get(solutionElement.getElementsByTagName("routes").item(0));
        } else {
            // TODO something?
            this.cost = 0D;
            this.routes = Collections.emptyList();
        }
    }
}

Note that in your main method you have a check on the cost. 注意,在您的main方法中,您需要检查成本。 I've left all class variable getter methods out, add the ones you need if you need to read them from outside the object. 我没有列出所有类变量getter方法,如果需要从对象外部读取它们,请添加所需的方法。 So for example in your Solution class add a getCost() method and then in the main method you can check as appropriate: if (solution.getCost() == requiredCost) { ... 因此,例如,在您的Solution类中,添加一个getCost()方法,然后在main方法中进行相应检查: if (solution.getCost() == requiredCost) { ...

Here, based on your requirements, you could add getters to the class members if needed. 在这里,根据您的要求,您可以根据需要向类成员添加getter。 I've just overridden the toString() method in order to print something you can read. 我只是重写了toString()方法,以便打印一些您可以阅读的内容。

Routes is a util class to create a collection of Route objects out of the child nodes of the <routes> node. Routes是一个util类,用于在<routes>节点的子节点之外创建Route对象的集合。

public class Routes {

    private final Collection<Route> items;

    public static Collection<Route> get(Node routes) throws Exception {
        return new Routes(routes).items;
    }

    private Routes() {
        this.items = new ArrayList<>();
    }

    private Routes(Node routes) throws Exception {
        this.items = new ArrayList<>();
        NodeList routesList = routes.getChildNodes();
        for (int i = 0; i < routesList.getLength(); i++) {
            Node route = routesList.item(i);
            if (Node.ELEMENT_NODE == route.getNodeType()) {
                items.add(Route.newInstance(route));
            } else {
                // TODO something?
            }
        }
    }   
}

The Acts class has similar logic to the Routes class (same thing but for acts): Acts类与Routes类具有相似的逻辑(除了行为外,其他内容相同):

public class Acts {

    private Collection<Act> items;

    public static Collection<Act> get(NodeList acts) throws Exception {
        return new Acts(acts).items;
    }

    private Acts() {
        this.items = new ArrayList<>();
    }

    private Acts(NodeList acts) throws Exception {
        this.items = new ArrayList<>();
        for (int i = 0; i < acts.getLength(); i++) {
            Node act = acts.item(i);
            if (Node.ELEMENT_NODE == act.getNodeType()) {
                this.items.add(Act.newInstance(act));
            } else {
                // TODO something?
            }
        }
    }
}

and finally, each individual Act : 最后,每个Act

public class Act {

    private final String service;

    private final double arrTime;

    private final double endTime;

    public static Act newInstance(Node act) throws Exception {
        return new Act(act);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();

        sb.append("Act");
        sb.append(System.lineSeparator());
        sb.append("arr time");
        sb.append(System.lineSeparator());
        sb.append(this.arrTime);
        sb.append(System.lineSeparator());
        sb.append("end time:");
        sb.append(System.lineSeparator());
        sb.append(this.endTime);
        sb.append(System.lineSeparator());
        sb.append("service:");
        sb.append(System.lineSeparator());
        sb.append(this.service);

        return sb.toString();
    }

    private Act(Node act) throws Exception {
        Element actElement = (Element) act;
        this.service = actElement.getAttribute("service");
        this.arrTime = Double.valueOf(actElement.getElementsByTagName("arrTime").item(0).getTextContent());
        this.endTime = Double.valueOf(actElement.getElementsByTagName("endTime").item(0).getTextContent());
    }
}

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

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