您的位置:首页 > 编程语言 > Java开发

Java 解析 xml 之 DOM and SAX

2012-06-16 19:20 471 查看
Java解析XML有两种方式:

**DOM

**SAX

例子:

<?xml version="1.0" encoding="UTF-8"?>
<users>
<description>information of users</description>
<user>
<name>LiLei</name>
<sex>1</sex>
<age>19</age>
</user>

<user>
<name>Han Meimei</name>
<sex>0</sex>
<age>18</age>
</user>
</users>


DOM方式:

载入XML,在内存中建立与xml文件相对应的DOM树。

根据DOM树中的Node和NodeList,获取需要的信息。

public boolean parserXml(InputStream is) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(is);

NodeList descNodes = doc.getElementsByTagName("description");
NodeList userNodes = doc.getElementsByTagName("user");
if (descNodes.getLength() > 0) {
// ignore following descriptions
document.setDescription(descNodes.item(0).getFirstChild().getNodeValue());
}
Node node;
NodeList nodes;
String name;
User user;
for (int i = 0; i < userNodes.getLength(); i++) {
user = new User();
nodes = userNodes.item(i).getChildNodes();
for (int j = 0; j < nodes.getLength(); j++) {
node = nodes.item(j);
name = node.getNodeName();
if ("name".equals(name)) {
user.setName(node.getFirstChild().getNodeValue());
} else if ("sex".equals(name)) {
user.setSex(Integer.parseInt(node.getFirstChild().getNodeValue()));
} else if ("age".equals(name)) {
user.setAge(Integer.parseInt(node.getFirstChild().getNodeValue()));
}
}
document.addUser(user);
}
return true;
}


** getChildNodes() 中会包含空白和换行,所以 nodes.getLength() 返回值是7,除了3个子节点,还有4个换行+tab。所以第一个childNode是 \n\t\t

** name节点的子节点有1个, 即 LiLei 这个#text节点

SAX方式:

事件驱动方式。

读取xml文件流,根据读取到的节点触发相应的事件。常用的如 startDocument()、endDocument()、startElement()、endElement()、characters()。。。。。

/**
* event driven parse xml as an input stream, with a handler as a callback while
* meeting each element tag startElement will contain lots of if/else
*
* @author xuefeng
*
*/
public class SaxXmlDemo implements IXmlDocument {

private UserDocument document;

public SaxXmlDemo() {
document = new UserDocument();
}

public boolean parserXml(InputStream is) throws Exception {
SAXParserFactory saxfac = SAXParserFactory.newInstance();
SAXParser saxparser = saxfac.newSAXParser();
saxparser.parse(is, new MySAXHandler(document));

return true;
}

public static void main(String[] args) throws Exception {
SaxXmlDemo demo = new SaxXmlDemo();
FileInputStream fis = new FileInputStream("data/test.xml");
demo.parserXml(fis);
System.out.println();
}
}

class MySAXHandler extends DefaultHandler {

private UserDocument document;

private User user; // userd for startElement and endElement

private String curTag; // userd for startElement and endElement

public MySAXHandler(UserDocument document) {
this.document = document;
}

public void startDocument() throws SAXException {
}

public void endDocument() throws SAXException {
}

public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
curTag = qName;
if ("user".equals(qName)) {
user = new User();
document.addUser(user);
}
}

public void endElement(String uri, String localName, String qName)
throws SAXException {
curTag = null;
}

public void characters(char[] ch, int start, int length)
throws SAXException {
if (curTag == null)
return;
String value = new String(ch, start, length);
if ("description".equals(curTag)) {
document.setDescription(value);
} else if ("name".equals(curTag)) {
user.setName(value);
} else if ("sex".equals(curTag)) {
user.setSex(Integer.parseInt(value));
} else if ("age".equals(curTag)) {
user.setAge(Integer.parseInt(value));
}
}

}


其中,

public void startElement(String uri, String localName, String qName, Attributes attributes)


uri : 如果解析器支持命名空间,uri为命名空间;如果不支持、或是没有命名空间, uri=""

localName : 如果解析器支持命名空间,为tag的名称;否则,为空。

qName : 如果tag有命名空间前缀,为 前缀+tag名称;否则,为tag名称。

attributes : tag的属性列表,可通过getLength()、getValue() 访问。

本文代码: svn : http://hsuehfeng.googlecode.com/svn/trunk/xml/XMLParse/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: