Получить все узлы с одинаковым именем на разных уровнях

Ниже приведен мой XML-файл:

<scenario>
  <negotiation>
    <type>auction</type>

    <agent>
      <type>UtilityCompany</type>
      <electricityPlan>
        <type>PlanUtility</type>
        <offeredEnergy>10</offeredEnergy>
        <duration>20</duration>
        <price>10</price>
        <role>
          <type>Seller</type>
        </role>
        <electricityOrder>
          <type>SalesOrder</type>
        </electricityOrder>
      </electricityPlan>
    </agent>

    <agent>
      <type>LargeCustomer</type>
      <electricityPlan>
        <type>LargecPlan</type>
        <requestedEnergy>100</requestedEnergy>
        <duration>20</duration>
        <price>10</price>
        <role>
          <type>Buyer</type>
        </role>
        <electricityOrder>
          <type>PurchaseOrder</type>
        </electricityOrder>
      </electricityPlan>
    </agent>

  </negotiation>
</scenario>

Мне нужно знать, как добавить все значения внутри тега <type></type> в тег ArrayList.

Что-то вроде следующего:

Agent[0] = UtilityCompany
Agent[1] = LargeCustomer

electricityPlan[0] = PlanUtility
electricityPlan[1] = LargecPlan

role[0] = Seller
role[1] = Buyer

Может кто-нибудь, пожалуйста, дать некоторое представление?

ОБНОВЛЕННАЯ ИНФОРМАЦИЯ

На данный момент у меня так:

public static void main(String[] args) выдает ParserConfigurationException, SAXException, IOException, XPathExpressionException {

    File fXmlFile = new File("scenario.xml");
    DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
    Document doc = dBuilder.parse(fXmlFile);

    NodeList nodes = doc.getElementsByTagName("negotiation");
    Element element = (Element) nodes.item(0);
    NodeList negotiationList = element.getElementsByTagName("agent");
    for (int i = 0; i < negotiationList.getLength(); i++) {

    Element negotiationElement = (Element) negotiationList.item(i);


NodeList agent = negotiationElement.getElementsByTagName("type");
System.out.println(agent.item(0).getFirstChild().getTextContent());

NodeList role = negotiationElement.getElementsByTagName("role");
Element roleline = (Element) role.item(0);
System.out.println(roleline.getElementsByTagName("type").item(0).getTextContent());

}

}

Output

UtilityCompany
Seller
LargeCustomer
Buyer
LargeCustomer
Buyer

Крупный покупатель

Но я не знаю, как получить значения из

      1.         <type>auction</type>

      2. <type>PlanUtility</type>  from ElectricityPlan tag.

Наконец я нашел решение для этого:

ЭТОТ КОД РАБОТАЕТ ДЛЯ ПОЛУЧЕНИЯ ЗАПРОШЕННЫХ УЗЛОВ

У меня есть решение для этого:

 public class ReadingXML {

static List<String> AuctionType = new ArrayList<String>();
static List<String> AgentType = new ArrayList<String>();
static List<String> PlanType = new ArrayList<String>();
static List<String> RoleType = new ArrayList<String>();
static List<String> OrderType = new ArrayList<String>();
static NodeList auction ;

 public List<List<String>> ReadingXML(String fileLocation) throws      
 ParserConfigurationException, SAXException, IOException {

//File fXmlFile = new File("C:....location\\scenario.xml");

File fXmlFile = new File(fileLocation);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
List<List<String>> listOfLists = Lists.newArrayList();

    NodeList nodesScenario = doc.getElementsByTagName("scenario");
    Element element0 = (Element) nodesScenario.item(0);
    NodeList scenarioList = element0.getElementsByTagName("negotiation");

   for (int j = 0; j < scenarioList.getLength(); j++) 
     {
       Element scenarioElement = (Element) scenarioList.item(j);
       auction = scenarioElement.getElementsByTagName("type");
       System.out.println(auction.item(0).getFirstChild().getTextContent());
       AuctionType.add(auction.item(0).getFirstChild().getTextContent()); 
     }
    List<String> AuctionTypeFiltered = Lists.newArrayList(Sets.newHashSet(AuctionType));
    listOfLists.add(Lists.newArrayList(AuctionTypeFiltered));

NodeList nodesNegotiation = doc.getElementsByTagName("negotiation");
Element element = (Element) nodesNegotiation.item(0);
NodeList negotiationList = element.getElementsByTagName("agent"); 

for (int i = 0; i < negotiationList.getLength(); i++) 
 {
   Element negotiationElement = (Element) negotiationList.item(i);
   NodeList agent = negotiationElement.getElementsByTagName("type");
   System.out.println(agent.item(0).getFirstChild().getTextContent());
   AgentType.add(agent.item(0).getFirstChild().getTextContent());

   NodeList nodesElectricityPlan = doc.getElementsByTagName("electricityPlan");
   Element element1 = (Element) nodesElectricityPlan.item(0);
   NodeList ElectricityPlanList = element1.getElementsByTagName("plan");

   for (int j = 0; j < ElectricityPlanList.getLength(); j++) 
    {
      Element electricityPlanElement = (Element) ElectricityPlanList.item(j);
      NodeList plan = electricityPlanElement.getElementsByTagName("type");
      System.out.println(plan.item(0).getFirstChild().getTextContent());
      PlanType.add(plan.item(0).getFirstChild().getTextContent());
    } 
    List<String> PlanTypeFiltered = Lists.newArrayList(Sets.newHashSet(PlanType));
    listOfLists.add(Lists.newArrayList(PlanTypeFiltered));

    NodeList role = negotiationElement.getElementsByTagName("role");
    Element roleline = (Element) role.item(0);
    System.out.println(roleline.getElementsByTagName("type").item(0).getTextContent());
    RoleType.add(roleline.getElementsByTagName("type").item(0).getTextContent());

    NodeList electricityorder = negotiationElement.getElementsByTagName("electricityOrder");
    Element electricityorderline = (Element) electricityorder.item(0);
    System.out.println(electricityorderline.getElementsByTagName("type").item(0).getTextContent());
    OrderType.add(electricityorderline.getElementsByTagName("type").item(0).getTextContent());
  }
   List<String> AgentTypeFiltered = Lists.newArrayList(Sets.newHashSet(AgentType));
   listOfLists.add(Lists.newArrayList(AgentTypeFiltered));

   List<String> RoleTypeFiltered = Lists.newArrayList(Sets.newHashSet(RoleType));
   listOfLists.add(Lists.newArrayList(RoleTypeFiltered));

   List<String> OrderTypeFiltered = Lists.newArrayList(Sets.newHashSet(OrderType));
   listOfLists.add(Lists.newArrayList(OrderTypeFiltered));

    return listOfLists;
    }



  } 

person user1069571    schedule 07.03.2017    source источник
comment
Возможно, вам придется использовать некоторые библиотеки синтаксических анализаторов xml. Некоторые из них — Dom Parser, SAX parser, Stax parser.   -  person Yohannes Gebremariam    schedule 07.03.2017
comment
Да, я знаю, проблема в том, как я могу получить элементы, во-первых, я разбирал файл xml: .... dom = db.parse(file.xml)....; позже я разбирал документ, но использовал: NodeList nl = docEle.getElementsByTagName(Agent);   -  person user1069571    schedule 07.03.2017
comment
Что вы используете для разбора XML? Я напишу ответ, используя то, что вы используете.   -  person Jonny Henly    schedule 07.03.2017
comment
Я не понимаю, что в этом сложного. Почему вы не можете обойти дом и вспомнить родительский элемент, когда спускаетесь глубже? когда вы найдете «тип», вы добавляете сохраненный родитель в список массивов...?   -  person Calicoder    schedule 07.03.2017
comment
@Calicoder сложная часть для меня - получить ‹type›auction‹/type› и ‹type›PlanUtility‹/type›. Спасибо   -  person user1069571    schedule 07.03.2017
comment
Поскольку ваш метод main объявлен для генерации XPathExpressionException, вы, кажется, по крайней мере знаете о существовании XPath. Почему бы не использовать его? Это сделало бы это значительно проще.   -  person VGR    schedule 08.03.2017
comment
@ user1069571 эй, я пишу ответ, вчера мне нужно было идти на работу.   -  person Jonny Henly    schedule 08.03.2017


Ответы (1)


Вместо того, чтобы иметь ArrayList для каждого типа, рассмотрите возможность использования подхода OO (объектно-ориентированного). Вы заметите много преимуществ этого подхода, например (намного) меньше переменных и строк кода. Возьмем, к примеру, следующее:

Driver.java:

public class Driver {
    public static final String XML_FILE_PATH = "zin/zin.xml";

    /**
     * Entry point of the program.
     */
    public static void main(String[] args) throws IOException, JDOMException {
        File xmlFile = new File(XML_FILE_PATH);
        // the SAXBuilder is the easiest way to create the JDOM2 objects
        SAXBuilder jdomBuilder = new SAXBuilder();

        // jdomDocument is the JDOM2 Object
        Document jdomDocument = jdomBuilder.build(xmlFile);
        Element root = jdomDocument.getRootElement();
        Element negotiation = root.getChild("negotiation");

        // get the list of children agent elements
        List<Element> xmlAgents = negotiation.getChildren("agent");
        // list for holding the agent objects parsed from the XML file
        List<Agent> agents = new ArrayList<Agent>();

        // iterate over the agent nodes from the XML file and create
        // agent objects to represent them
        for (Element currentAgent : xmlAgents) {
            Agent newAgent = new Agent();
            // set the new agent's 'AgentType' before descending into
            // the children XML nodes
            newAgent.setAgentType(currentAgent.getChildText("type"));

            // recursively finish the new agent
            descend(currentAgent, newAgent);

            // add the new agent to the ArrayList of agents
            agents.add(newAgent);
        }

        // print agent data to output
        for(Agent agent : agents) {
            System.out.println(agent);
        }
    }

    /**
     * Note: Agent is not immutable, this method alters the members
     * of the passed in Agent object.
     * 
     * Recursive method to fill in the rest of a passed in Agent object.
     * 
     * @param ele - an XML element to descend.
     * @param agent - the Agent object to finish filling.
     */
    public static void descend(Element ele, Agent agent) {
        for (Element e : ele.getChildren()) {
            switch (e.getName()) {
                case "electricityPlan":
                    agent.setPlanType(e.getChildText("type"));
                    break;
                case "role":
                    agent.setRoleType(e.getChildText("type"));
                    break;
                case "electricityOrder":
                    agent.setOrderType(e.getChildText("type"));
                    break;
                default:
                    break;
            }

            descend(e, agent);
        }
    }
}

Агент.java

public class Agent {
    private String auctionType;
    private String agentType;
    private String planType;
    private String roleType;
    private String orderType;

    public Agent() {
        auctionType = "";
        agentType = "";
        planType = "";
        roleType = "";
        orderType = "";
    }

    @Override
    public String toString() {
        String str = "Agent\r\n";

        str += "  AuctionType: " + getAuctionType() + "\r\n";
        str += "    AgentType: " + getAgentType() + "\r\n";
        str += "     RoleType: " + getRoleType() + "\r\n";
        str += "     PlanType: " + getPlanType() + "\r\n";
        str += "    OrderType: " + getOrderType();

        return str;
    }

    public String getAuctionType() {
        return auctionType;
    }

    public void setAuctionType(String auctionType) {
        this.auctionType = auctionType;
    }

    public String getAgentType() {
        return agentType;
    }

    public void setAgentType(String agentType) {
        this.agentType = agentType;
    }

    public String getPlanType() {
        return planType;
    }

    public void setPlanType(String planType) {
        this.planType = planType;
    }

    public String getRoleType() {
        return roleType;
    }

    public void setRoleType(String roleType) {
        this.roleType = roleType;
    }

    public String getOrderType() {
        return orderType;
    }

    public void setOrderType(String orderType) {
        this.orderType = orderType;
    }

}

Метод Running Driver main выводит следующее:

Agent
  AuctionType: 
    AgentType: UtilityCompany
     RoleType: Seller
     PlanType: PlanUtility
    OrderType: SalesOrder
Agent
  AuctionType: 
    AgentType: LargeCustomer
     RoleType: Buyer
     PlanType: LargecPlan
    OrderType: PurchaseOrder

Конечно, приведенный выше код является лишь примером. Класс Agent не обязательно должен иметь все эти методы доступа и мутаторы или вообще какие-либо, все его члены могут быть общедоступными или защищенными. Дело в том, что у вас может быть список агентов, в котором каждый объект агента содержит элементы для каждого типа, а не список для каждого типа, где каждый индекс представляет отдельный агент.

person Jonny Henly    schedule 08.03.2017