使用DOM4J解析XML文件

时间:2013-07-30 03:05:09

标签: java parsing xml-parsing dom4j

我在解析XML方面遇到了问题。

我有以下方法:

public void componentsInfoToSimulation(String houseDivision, String equipment) {
        Element root = doc.getRootElement();
        pt.ipp.isep.gecad.masgrip.Simulation.getHouseNamesOfComponents().add(equipment);

        for (Iterator i = root.elementIterator("house"); i.hasNext();) {
            Element element = (Element) i.next();

            if (element.attributeValue("id").equals(houseDivision)) {

                for (Iterator j = element.elementIterator("" + houseDivision); j.hasNext();) {
                    Element innerElement = (Element) j.next();

                    if (innerElement.attributeValue("id").equals(equipment)) {

                        for (Iterator k = innerElement.elementIterator("" + equipment); k.hasNext();) {
                            Element innerSubElement = (Element) k.next();

                            String op = innerSubElement.getQualifiedName();
                            switch (op) {
                                case "power":
                                    pt.ipp.isep.gecad.masgrip.Simulation.getHousePowerDosComponents().add(Integer.parseInt(innerSubElement.getTextTrim()));
                                    break;
                                case "min_power":
                                    pt.ipp.isep.gecad.masgrip.Simulation.getHouseMinPowerComponents().add(Integer.parseInt(innerSubElement.getTextTrim()));
                                    break;

                                case "max_power":
                                    pt.ipp.isep.gecad.masgrip.Simulation.getHouseMaxPowerComponents().add(Integer.parseInt(innerSubElement.getTextTrim()));
                                    break;

                                case "average_usage_hour":
                                    pt.ipp.isep.gecad.masgrip.Simulation.getHouseAverageUsageHoursPerDay().add(Float.parseFloat(innerSubElement.getTextTrim()));
                                    break;

                                case "average_usage_minute":
                                    pt.ipp.isep.gecad.masgrip.Simulation.getHouseAverageUsageMinutesPerDay().add(Float.parseFloat(innerSubElement.getTextTrim()));
                                    break;

                                default:
                                    break;
                            }
                        }
                    }
                }
            }
        }
        System.out.println("" + pt.ipp.isep.gecad.masgrip.Simulation.getHouseNamesOfComponents());
        System.out.println("" + pt.ipp.isep.gecad.masgrip.Simulation.getHousePowerDosComponents());
        System.out.println("" + pt.ipp.isep.gecad.masgrip.Simulation.getHouseMinPowerComponents());
        System.out.println("" + pt.ipp.isep.gecad.masgrip.Simulation.getHouseMaxPowerComponents());
        System.out.println("" + pt.ipp.isep.gecad.masgrip.Simulation.getHouseAverageUsageHoursPerDay());
        System.out.println("" + pt.ipp.isep.gecad.masgrip.Simulation.getHouseAverageUsageMinutesPerDay());

    }

这是我的XML文件示例:

<components>
    <house id="Kitchen">
        <espresso_machine id="espresso machine">
            <power>360</power>
            <min_power>360</min_power>
            <max_power>360</max_power>
            <average_usage_hour>0.25</average_usage_hour>
            <average_usage_minute>15</average_usage_minute>
        </espresso_machine>
        <coffee_machine id="coffee machine">
            <power>1500</power>
            <min_power>800</min_power>
            <max_power>1500</max_power>
            <average_usage_hour>0.25</average_usage_hour>
            <average_usage_minute>15</average_usage_minute>
        </coffee_machine>
        <coffee_pot id="coffee pot">
            <power>0</power>
            <min_power>200</min_power>
            <max_power>200</max_power>
            <average_usage_hour>0.25</average_usage_hour>
            <average_usage_minute>15</average_usage_minute> 
        </coffee_pot>
    </house>
</components>

如果我的程序是“浓缩咖啡机”,我应该输出以下内容:

[espresso_machine] [360] [360] [360] [0.25] [15]

然而,它是这样的:

[espresso_machine] [] [] [] [] []

我问题是在使用innerElement.getTextTrim()时在Switch / Case中,但我不确定。你能帮我解决这个问题吗?

2 个答案:

答案 0 :(得分:1)

代码中存在一些错误,包括解析文档的方式以及XML文件中需要更新的一些错误。请参阅以下更新的代码和XML文档。我在评论中添加了你可以遵循的逻辑。

致电方法:

componentsInfoToSimulation("Kitchen", "espresso machine");

方法:

 public static void componentsInfoToSimulation(String houseDivision, String equipment)
   {
      Element root = doc.getRootElement();

      // Iterate over the houses
      for (Iterator i = root.elementIterator("house"); i.hasNext();)
      {
         Element houseElement = (Element) i.next();

         // Check if the id of one the house elements equals the houseDivision
         String houseId = houseElement.attributeValue("id");
         if (houseId.equals(houseDivision))
         {
            // Iterate over the equipment for the house
            for (Iterator x = houseElement.elementIterator("equipment"); x.hasNext();)
            {
               Element equipmentElement = (Element) x.next();

               // Check if the id of one the equipment elements equals the
               // equipment
               String equipId = equipmentElement.attributeValue("id");
               if (equipId.equals(equipment))
               {
                  // Get all the elemnts and their values
                  int power = Integer.valueOf(equipmentElement.element("power").getTextTrim());
                  int minPower = Integer.valueOf(equipmentElement.element("min_power").getTextTrim());
                  int maxPower = Integer.valueOf(equipmentElement.element("max_power").getTextTrim());
                  float averageUsageHours = Float.valueOf(equipmentElement.element("average_usage_hour").getTextTrim());
                  float averageUsageMins = Float.valueOf(equipmentElement.element("average_usage_minute").getTextTrim());

                  // Update the model
                  pt.ipp.isep.gecad.masgrip.Simulation.getHouseNamesOfComponents().add(equipment);
                  pt.ipp.isep.gecad.masgrip.Simulation.getHousePowerDosComponents().add(power);
                  pt.ipp.isep.gecad.masgrip.Simulation.getHouseMinPowerComponents().add(minPower);
                  pt.ipp.isep.gecad.masgrip.Simulation.getHouseMaxPowerComponents().add(maxPower);
                  pt.ipp.isep.gecad.masgrip.Simulation.getHouseAverageUsageHoursPerDay().add(averageUsageHours);
                  pt.ipp.isep.gecad.masgrip.Simulation.getHouseAverageUsageMinutesPerDay().add(averageUsageMins);
               }
            }
         }
      }
   }

注意有多个设备元素。它们由ID标识。没有必要让所有元素都有所不同。它们都代表了一种通用的“设备”。

<components>
    <house id="Kitchen">
        <equipment id="espresso machine">
            <power>360</power>
            <min_power>360</min_power>
            <max_power>360</max_power>
            <average_usage_hour>0.25</average_usage_hour>
            <average_usage_minute>15</average_usage_minute>
        </equipment>
        <equipment id="coffee machine">
            <power>1500</power>
            <min_power>800</min_power>
            <max_power>1500</max_power>
            <average_usage_hour>0.25</average_usage_hour>
            <average_usage_minute>15</average_usage_minute>
        </equipment>
        <equipment id="coffee pot">
            <power>0</power>
            <min_power>200</min_power>
            <max_power>200</max_power>
            <average_usage_hour>0.25</average_usage_hour>
            <average_usage_minute>15</average_usage_minute> 
        </equipment>
    </house>
</components>

答案 1 :(得分:0)

这只是建议使用XPath而不是显式导航。大大减少了代码量:

    String expression = String.format(
            "/components/house[@id='%s']/*[@id='%s']/*", houseDivision,
            equipment);
    @SuppressWarnings("unchecked")
    List<Element> elements = doc.selectNodes(expression);
    for (Element e : elements) {
        switch (e.getName()) {
        case "power":
            break;
        case "min_power":
            break;
                    // etc
        }
    }