我正在使用DOM解析器/生成器解析Java中的XML文件。 对于我的XML标记名的一部分来说,它工作正常。但是当我尝试解析另一个Tagname时,情况变得越来越糟,因为Tagname也用于其他Tag中。
XML文件:
<RootTag>
<humans>
<human>
<name>Max</name>
<age>22</age>
<friends>
<friend>
<name>Peter</name>
<adress>
<street>Way down 1</street>
</adress>
</friend>
<friend>
<name>Kevin</name>
<adress>
<street>Way left 2</street>
</adress>
</friend>
</friends>
</human>
<human>
<name>Justin</name>
<age>22</age>
<friends>
<friend>
<name>Georg</name>
<adress>
<street>Way up 1</street>
</adress>
</friend>
</friends>
</human>
</humans>
<friend>
<friends>
<name>Max</name>
<numberFriends>2</numberFriends>
</friends>
<friends>
<name>Justin</name>
<numberFriends>1</numberFriends>
</friends>
</friend>
</RootTag>
Java:
public static void parse() throws ParserConfigurationException, IOException, SAXException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(true);
factory.setIgnoringElementContentWhitespace(true);
DocumentBuilder builder = factory.newDocumentBuilder();
File file = new File("humanFriends.xml");
Document doc = builder.parse(file);
NodeList humanL = doc.getElementsByTagName("human");
for (int j = 0; j < humanL.getLength(); j++) {
Node humanN = humanL.item(j);
if (humanN.getNodeType() == Node.ELEMENT_NODE) {
Element humanE = (Element) humanN;
String name = humanE.getElementsByTagName("name").item(0).getTextContent();
String vehicleId = humanE.getElementsByTagName("age").item(0).getTextContent();
...
}
NodeList friendsL = doc.getElementsByTagName("friends");
for (int j = 0; j < friendsL.getLength(); j++) {
Node friendsN = friendsL.item(j);
if (friendsN.getNodeType() == Node.ELEMENT_NODE) {
Element friendsE = (Element) friendsN;
String name = friendsE.getElementsByTagName("name").item(0).getTextContent();
String vehicleId = friendsE.getElementsByTagName("numberFriends").item(0).getTextContent();
here I'm getting error because parser take also friends from human Tag...
}
}
是否可以像在特定子节点中按层次结构或仅对标记名进行解析? 而且即使在不同节点中使用相同的标记名也可以解析XML,还是XML的结构不好?
答案 0 :(得分:1)
Element.getElementsByTagName("foo")
返回所有 后代元素(当前元素的名称,具有给定的标记/元素名称)。在您的代码+示例中,这只会抛出一个讨厌的NPE,因为前friends
个元素内部没有numberFriends
。
现在您可以:
NullPointerException
(或进行其他测试,确定您是否使用了正确的元素……这不是我最喜欢的方法,不是干净的方法,但很实用,简短且有效)。getElementsByTagName()
...,而是从相应的子元素中获取。):(代表2。)假设您想要所有//humans/human
(<-XPATH)元素的名称+年龄以及所有//friend/friends
元素的name + numberFriends,您将执行以下操作: / p>
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class Test {
public static void main(String[] args) throws ParserConfigurationException, IOException, SAXException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating(true);
factory.setIgnoringElementContentWhitespace(true);
DocumentBuilder builder = factory.newDocumentBuilder();
File file = new File("humanFriends.xml");
Document doc = builder.parse(file);
NodeList humansL = doc.getElementsByTagName("humans");
//System.out.println(humansL.getLength());
for (int i = 0; i < humansL.getLength(); i++) {
Node humansN = humansL.item(i);
if (humansN.getNodeType() == Node.ELEMENT_NODE) {
NodeList humanL = ((Element) humansN).getElementsByTagName("human");
// System.out.println(humanL.getLength());
for (int j = 0; j < humanL.getLength(); j++) {
Node humanN = humanL.item(j);
if (humanN.getNodeType() == Node.ELEMENT_NODE) {
Element humanE = (Element) humanN;
String name = humanE.getElementsByTagName("name").item(0).getTextContent();
String age= humanE.getElementsByTagName("age").item(0).getTextContent();
System.out.println(name);
System.out.println(age);
}
}
}
}
NodeList friendsL = doc.getElementsByTagName("friend");
// System.out.println(friendsL.getLength());
for (int i = 0; i < friendsL.getLength(); i++) {
Node friendsN = friendsL.item(i);
if (friendsN.getNodeType() == Node.ELEMENT_NODE) {
NodeList friendL = ((Element) friendsN).getElementsByTagName("friends");
// System.out.println(friendL.getLength());
for (int j = 0; j < friendL.getLength(); j++) {
Node friendN = friendL.item(j);
if (friendN.getNodeType() == Node.ELEMENT_NODE) {
Element friendE = (Element) friendN;
String name = friendE.getElementsByTagName("name").item(0).getTextContent();
System.out.println(name);
String numberFriends = friendE.getElementsByTagName("numberFriends").item(0).getTextContent();
System.out.println(numberFriends);
}
}
}
}
}
}
请稍微改变(测试)“ humanFriends.xml”中的值,尤其是要识别不明确的标记名称中的问题;)