使用Java解析xml(获取可选的childnode值)

时间:2015-11-24 19:16:35

标签: java xml

我需要解析一个名为学生的xml文件,每个学生都有rollno,firstname,lastname作为属性,但并非所有学生都有俱乐部。 xml文件如下所示:

<?xml version="1.0"?>
<class>
   <student rollno="393" firstname="Dinkar" lastname="Kad">
    <club name="Asian-Caucus" />
   </student>
   <student rollno="493" firstname="Vaneet" lastname="Gupta"/>
   <student rollno="593" firstname="jasvir" lastname="jazz">
      <club name="Students-for-Corporate-Citizenship"/>
   </student>
   <student rollno="693" firstname="Joseph" lastname="Patterson"/>
</class>

我想检索有关每个学生的信息,获取他们的名字,名字,姓氏和俱乐部名称(如果存在)。 我的代码可以获取有关所需属性的信息,但俱乐部名称始终为空(即使应该有与该学生相关联的俱乐部): 我的代码如下:

    import java.io.File;
    import java.util.ArrayList;
    import java.util.List;

    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;

    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.NamedNodeMap;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;


    public class TestParser {


        public void parseXML() throws Exception{
              DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
              DocumentBuilder docBuilder = factory.newDocumentBuilder();
              File file = new File("c:\\My Documents\\students.xml");
              Document doc = docBuilder.parse(file);




              NodeList list = doc.getElementsByTagName("student");
              for(int i=0; i<list.getLength(); i++){

                  int rollno = 0;
                  String firstname = "";
                  String lastname = "";
                  String clubname  = "";

                  Element cur = (Element)list.item(i);

                  NamedNodeMap curAttr = cur.getAttributes();


                  for(int j=0; j<curAttr.getLength(); j++){
                      Node attr = curAttr.item(j);
                      if(attr.getNodeName().equals("rollno"))
                          rollno = Integer.parseInt(attr.getNodeValue());
                      if(attr.getNodeName().equals("firstname")) 
                          firstname = attr.getNodeValue();
                      if(attr.getNodeName().equals("lastname")) 
                          lastname = attr.getNodeValue();
                      if(attr.getNodeName().equals("club name")) 
                          clubname = attr.getNodeValue();

                  } // end for each attribute
                  System.out.print("rollno: " + rollno);
                  System.out.print(" firstname: " + firstname);
                  System.out.print(" lastname: " + lastname);
                  System.out.println(" club name: " + clubname);



              }// end for each element


        }     


        public static void main(String[] args) throws Exception {
            // TODO Auto-generated method stub
            TestParser tp = new TestParser();
            tp.parseXML();

        }

    }



Output looks like this:

    rollno: 393 firstname: Dinkar lastname: Kad club name: 
    rollno: 493 firstname: Vaneet lastname: Gupta club name: 
    rollno: 593 firstname: jasvir lastname: jazz club name: 
    rollno: 693 firstname: Joseph lastname: Patterson club name: 

Any idea to fix this problem, so that student has a club can print out the correct club name? I'm very new to xml parsing, any suggestion is appreciated. Thanks a lot!

更新     根据@tanjir的回答修改了代码,现在该程序可以顺利获得childnode俱乐部的价值:)

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;


public class TestParser {


    public void parseXML() throws Exception{
          DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
          DocumentBuilder docBuilder = factory.newDocumentBuilder();
          File file = new File("c:\\My Documents\\students.xml");
          Document doc = docBuilder.parse(file);




          NodeList list = doc.getElementsByTagName("student");
          for(int i=0; i<list.getLength(); i++){

              int rollno = 0;
              String firstname = "";
              String lastname = "";
              String clubname  = "";

              Element cur = (Element)list.item(i);

              NamedNodeMap curAttr = cur.getAttributes();


              for(int j=0; j<curAttr.getLength(); j++){
                  Node attr = curAttr.item(j);
                  if(attr.getNodeName().equals("rollno"))
                      rollno = Integer.parseInt(attr.getNodeValue());
                  if(attr.getNodeName().equals("firstname")) 
                      firstname = attr.getNodeValue();
                  if(attr.getNodeName().equals("lastname")) 
                      lastname = attr.getNodeValue();
                  if(attr.getNodeName().equals("name")) 
                      clubname = attr.getNodeValue();

              } // end for each attribute


              //check if there is any optional childnode
              if(cur.hasChildNodes()) {
                  NodeList stChildNodes = cur.getChildNodes();
                  // Loop through all the nodes and find the club node only
                  for(int c=0; c<stChildNodes.getLength(); c++) {
                      Node child = stChildNodes.item(c);
                      if(child.getNodeName().equals("club")) {
                        //"club" node detected. now loop through the attributes
                          NamedNodeMap curChildAttr = child.getAttributes();
                          for(int j=0; j<curChildAttr.getLength(); j++){
                              Node attr = curChildAttr.item(j);
                              if(attr.getNodeName().equals("name")) {
                                  clubname = attr.getNodeValue();
                            }
                        }
                      }
                  }
              }// end if hasChildNodes



              System.out.print("rollno: " + rollno);
              System.out.print(" firstname: " + firstname);
              System.out.print(" lastname: " + lastname);
              System.out.println(" club name: " + clubname);



          }// end for each element


    }     


    public static void main(String[] args) throws Exception {
        // TODO Auto-generated method stub
        TestParser tp = new TestParser();
        tp.parseXML();

    }

}

1 个答案:

答案 0 :(得分:2)

你需要获得俱乐部节点然后循环它的属性 - 类似于你已经做过的方式..

       //check if there is any optional childnode
          if(cur.hasChildNodes()) {
            NodeList stChildNodes = cur.getChildNodes();
             // Loop through all the nodes and find the club node only
            for(Node child : stChildNodes) {
              if(child.getNodeName().equals("club") {
                  //"club" node detected. now loop through the attributes like the way you already did for students
                  NamedNodeMap clubAttr = child.getAttributes();
                  for(int j=0; j<clubAttr.getLength(); j++){
                    Node clattr = clubAttr.item(j);
                    if(clattr.getNodeName().equals("name")) {
                      clubname = clattr.getNodeValue();
                    }
                  }
                  break; // probably we are not interested in other nodes
               }
             }
          }