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)
localName : 如果解析器支持命名空间,为tag的名称;否则,为空。
qName : 如果tag有命名空间前缀,为 前缀+tag名称;否则,为tag名称。
attributes : tag的属性列表,可通过getLength()、getValue() 访问。