xmlxml-parsingjtreejdom-2

How can create a loop to count an specific "Child" in a list of "Children"?


Consider the following XML file:

<project>
    <props>
        <prop name="currency" value="USD" />
        <prop name="user-type" value="admin" />
    </props>

    <plans>
        <plan name="-" showFirst="false" showSecond="false">
            <props>
                <prop name="moneyback" value="true" />
                <prop name="capacity" value="5" />
            </props>
            <section id="setup"/>
            <section id="hardware" defaultChoice="machines">
                <parts level="1">
                    <part choice="machine_001" name="DAP010" />
                    <part choice="machine_002" name="DAP011" />
                </parts>
            </section>
            <section id="software" />     
            <queues>
                <queue type="q2" minPlan="CC_Q" />
            </queues>
        </plan>


        <plan name="A" showFirst="true" showSecond="true">
            <users>
                <user planName="classic" cost="$20.00" />
                <user planName="lite" cost="$10.00" />
            </users>
        </plan>

        <plan name="B" showFirst="true" showSecond="false">
            <props>
                <prop name="moneyback" value="false" />
                <prop name="capacity" value="2" />
            </props>
            <section id="setup"/>
            <section id="software" />     
            <queues>
                <queue type="q2" minPlan="CC_Q" />
            </queues>
        </plan>

    </plans>
</project>

Using the "JDOM2",

public void actionPerformed(ActionEvent e) {
  JFileChooser ServiceOfferFileChooser = new JFileChooser();
  ServiceOfferFileChooser.setCurrentDirectory(new File(System.getProperty("user.home")));
  ServiceOfferFileChooser.setAcceptAllFileFilterUsed(false);
  FileNameExtensionFilter filter = new FileNameExtensionFilter("*.xml", "xml");
  ServiceOfferFileChooser.addChoosableFileFilter(filter);

  int resultChangeServiceOfferFileChooser = ServiceOfferFileChooser.showOpenDialog(null);

  if (resultChangeServiceOfferFileChooser == JFileChooser.APPROVE_OPTION) {
    File selectedServiceOfferFile = ServiceOfferFileChooser.getSelectedFile();

    SAXBuilder soRead = new SAXBuilder();

    Document ReadSO;
    try {
      ReadSO = soRead.build(new File(selectedServiceOfferFile.getPath()));

      JTree loadedTree = new JTree();
      loadedTree.setModel(new DefaultTreeModel(
        new DefaultMutableTreeNode("Service Offer") {

          private static final long serialVersionUID = 1L;

          {
            add(new DefaultMutableTreeNode("Service Offer Properties"));

            List<Element> soPlans = ReadSO.getRootElement().getChild("plans").getChildren();
            for(int i=0;i<soPlans.size();i++){
              Element soPlan = soPlans.get(i);
              DefaultMutableTreeNode node_soPlan = new DefaultMutableTreeNode("Plan: "+soPlan.getAttributeValue("name"));
                add(node_soPlan);

                List<Element> plansProps = soPlans.get(i).getChildren();
                for (int ii=0;ii<=plansProps.size()-1;ii++){
                  Element plansProp = plansProps.get(ii);
                  node_soPlan.add(new DefaultMutableTreeNode(plansProp));
                }
            }

          }
        }
      ));
      newTree.setVisible(false);
      westNorthPanel.add(loadedTree);

This is how my JTree looks like


Regarding that I need each of the Children "props", "section", "queues", and "user" has their own label as I define, So I have to count each of these Child Element in their parent element Plan.

I created a loop which counts number of the Child "Plan" in its parent "Plans". How?

List<Element> soPlans = ReadSO.getRootElement().getChild("plans").getChildren();
            for(int i=0;i<soPlans.size();i++){
              Element soPlan = soPlans.get(i);

Please note that the "List<Element>" implies a "list" which is satisfied by ensemble of "children".

Now the issue and my question is that in the second loop I want that the codes visits all "Plans" and when it find a "props" creates JTree node with desired text.

The problem is that if I use the method [.getChild("props")] after the method ".getChildren()", compiler correctly complains that I need to change "List<Element>" into "Elemen"; and by doing so, the method ".size()" is not defined for the "PlansProps"

List<Element> plansProps = soPlans.get(i).getChildren();
                    for (int ii=0;ii<=plansProps.size()-1;ii++){
                      Element plansProp = plansProps.get(ii);
                      node_soPlan.add(new DefaultMutableTreeNode(plansProp));
                    }

How can I use a "for (int)" loop to count a certain "Element" and not a "List of Elements"


Solution

  • I found a way to achieve my goal through implementing another method [.getQualifiedName()] for the Element declared inside the second loop where we can use the method [.getSize()] for the loop counter:

    SAXBuilder soRead = new SAXBuilder();
    
      Document ReadSO;
      try {
        ReadSO = soRead.build(new File(selectedServiceOfferFile.getPath()));
    
        JTree loadedTree = new JTree();
        loadedTree.setModel(new DefaultTreeModel(
          new DefaultMutableTreeNode("Service Offer") {
    
            private static final long serialVersionUID = 1L;
    
            {
              add(new DefaultMutableTreeNode("Service Offer Properties"));
    
              List<Element> soPlans = ReadSO.getRootElement().getChild("plans").getChildren();
              for(int i=0;i<soPlans.size();i++){
                Element soPlan = soPlans.get(i);
                DefaultMutableTreeNode node_soPlan = new DefaultMutableTreeNode("Plan: "+soPlan.getAttributeValue("name"));
                  add(node_soPlan);
    
              **List<Element> plansProps = soPlans.get(i).getChildren();**
              for (int ii=0;ii<=plansProps.size()-1;ii++){
                Element plansProp = plansProps.get(ii);
                **if (plansProp.getQualifiedName()** == "props"){
                  node_soPlan.add(new DefaultMutableTreeNode("Plan Properties"));
                }
                else if (plansProp.getQualifiedName() == "section"){
                  //System.out.println(plansProp.getAttributeValue("id"));
                  node_soPlan.add(new DefaultMutableTreeNode("Section: "+plansProp.getAttributeValue("id")));
                }
                else if (plansProp.getQualifiedName() == "queues"){
                  node_soPlan.add(new DefaultMutableTreeNode("Queue Licences: "));
                }
                else if (plansProp.getQualifiedName() == "users"){
                  node_soPlan.add(new DefaultMutableTreeNode("Users: "));
                }
                else {
                  node_soPlan.add(new DefaultMutableTreeNode(plansProp));
                }
    
                System.out.println(plansProp.getAttributeValue("id"));
              }
    
          }
    
    
        }
      }
    

    And now this is how does it look like: