【问题标题】:Parsing XML file using DOM4J使用 DOM4J 解析 XML 文件
【发布时间】:2013-07-30 03:05:08
【问题描述】:

我在解析 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>

如果我必须给我的程序一个“浓缩咖啡机”,我应该有以下输出:

[浓缩咖啡机] [360] [360] [360] [0.25] [15]

然而,结果是这样的:

[浓缩咖啡机] [] [] [] [] []

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

【问题讨论】:

    标签: java parsing xml-parsing dom4j


    【解决方案1】:

    在您解析文档的代码中存在一些错误,并且您的 XML 文件中的某些内容也需要更新。请参阅以下更新的代码和 XML 文档。我在 cmets 中添加了这样您就可以按照逻辑进行操作。

    调用方法:

    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>
    

    【讨论】:

    • 我已经更改了我的 XML 文件,但仍然无法正常工作。我不知道为什么。我有相同的输出
    【解决方案2】:

    这只是建议使用 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
            }
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-27
      • 2012-07-15
      相关资源
      最近更新 更多