使用Java解析xml(获取可选的childnode值)
我需要解析一个名为students的xml文件,每个学生都有rollno、firstname、lastname作为属性,但不是所有学生都有一个俱乐部。 xml文件如下所示:使用Java解析xml(获取可选的childnode值),java,xml,Java,Xml,我需要解析一个名为students的xml文件,每个学生都有rollno、firstname、lastname作为属性,但不是所有学生都有一个俱乐部。 xml文件如下所示: <?xml version="1.0"?> <class> <student rollno="393" firstname="Dinkar" lastname="Kad"> <club name="Asian-Caucus" /> </student&
<?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!
导入java.io.File;
导入java.util.ArrayList;
导入java.util.List;
导入javax.xml.parsers.DocumentBuilder;
导入javax.xml.parsers.DocumentBuilderFactory;
导入org.w3c.dom.Document;
导入org.w3c.dom.Element;
导入org.w3c.dom.NamedNodeMap;
导入org.w3c.dom.Node;
导入org.w3c.dom.NodeList;
公共类测试分析器{
public void parseXML()引发异常{
DocumentBuilderFactory工厂=DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder=factory.newDocumentBuilder();
File File=新文件(“c:\\My Documents\\students.xml”);
Document doc=docBuilder.parse(文件);
NodeList list=doc.getElementsByTagName(“学生”);
对于(int i=0;i,您需要获取俱乐部节点,然后通过其属性循环-类似于您已经使用的方式
//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
}
}
}
//检查是否有任何可选的子节点
if(cur.hasChildNodes()){
NodeList stChildNodes=cur.getChildNodes();
//循环遍历所有节点并仅查找俱乐部节点
用于(节点子节点:stChildNodes){
if(child.getNodeName().equals(“俱乐部”){
//检测到“俱乐部”节点。现在,像您为学生所做的那样循环属性
NamedNodeMap clubAttr=child.getAttributes();
对于(int j=0;j,属性名称不是“club name”。club是元素的名称,“name”是属性。您可以通过cur.getChildNodes()访问club节点……感谢提示anwser。我尝试将like更改为if(attr.getNodeName().equals(“name”))clubname=attr.getNodeValue()
但这没有任何区别。@tanjir谢谢。我之前试过这个。结果不太对劲。请你提供一个代码片段好吗?谢谢!非常感谢!我修改了一点,现在效果很好!我已经编辑了原始帖子和你的答案。很高兴听到这一点。你已经非常接近了哎……)
//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
}
}
}