解析XML数据
Posted 猪八戒1.0
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解析XML数据相关的知识,希望对你有一定的参考价值。
下面只解析,如果想用解析后的数据创建对象,直接写在其中即可
若vehicles.xml
<vehicles>
<cars>
<car id="1">
<name>战神</name>
<oil>20</oil>
<loss>0</loss>
<brand>长城</brand>
</car>
<car id="2">
<name>跑得快</name>
<oil>40</oil>
<loss>20</loss>
<brand>红旗</brand>
</car>
</cars>
<trucks>
<truck id="3">
<name>大力士</name>
<oil>20</oil>
<loss>0</loss>
<load>5吨</load>
</truck>
<truck id="4">
<name>大力士二代</name>
<oil>30</oil>
<loss>30</loss>
<load>10吨</load>
</truck>
</trucks>
</vehicles>
1.采用Java默认的Dom解析xml
package test;
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;
/**
* 采用 DOM 方式解析 XML 数据
*/
public class TestDOM
/**
* 文件解析
* @param filename 文件名
*/
public void parseFile(String filename)
try
//创建解析器工厂
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
//通过解析器工厂获得DOM解析器
DocumentBuilder db = dbf.newDocumentBuilder();
//解析指定XML文档,得到DOM节点树
Document doc = db.parse(filename);
//得到根节点
NodeList vehicles = doc.getChildNodes();
System.out.println(" `租车系统` 中共有" + vehicles.getLength() + "种类型的车!");
//得到所有<truck>节点列表信息
NodeList truckList = doc.getElementsByTagName("truck");
System.out.println(" `租车系统` 中共有" + truckList.getLength() + "辆卡车!");
//遍历所有卡车
for (int i = 0; i < truckList.getLength(); i++)
//获取索引为i的卡车
Node truck = truckList.item(i);
//获取卡车属性值并显示
Element element = (Element) truck;
String idValue = element.getAttribute("id");
//以下通过属性名获得属性节点,再通过getNodeValue()获得属性值
//Node attr = element.getAttributeNode("id");
//String idValue = attr.getNodeValue();
System.out.println("id为" + idValue + "的卡车信息为:");
//获取索引为i的卡车详细信息并输出
for (Node node = truck.getFirstChild(); node != null; node = node.getNextSibling())
//根据节点类型进行判断,显示元素节点信息,如 <oil>20</oil>
if (node.getNodeType() == Node.ELEMENT_NODE)
//元素节点的节点名为标签名,如oil
String name = node.getNodeName();
//元素节点<oil>20</oil>下第一个子节点为文本节点20,得到节点值20
String value = node.getFirstChild().getNodeValue();
System.out.println(" " + name + ":" + value + ";");
catch (ParserConfigurationException e)
e.printStackTrace();
catch (SAXException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
public static void main(String[] args)
new TestDOM().parseFile("src//test//vehicles.xml");
2.使用 Dom4j 解析 XML 数据
package test;
import java.util.List;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
* Dom4j 解析 XML 文档数据
* @author 小桃子
*/
public class TestDom4j
/**
* 解析文件
* @param filename 路径+文件名
*/
public void parseFile(String filename)
// 创建 SAX 解析对象
SAXReader reader = new SAXReader();
try
// 获取文档对象
Document document = reader.read(filename);
// 获取根元素
Element root = document.getRootElement();
// 获取子元素
Element cars = root.element("cars");
Element trucks = root.element("trucks");
// 调用数据获取的方法
this.getData(cars, "car");
//this.getData(trucks, "truck");
catch (DocumentException e)
e.printStackTrace();
/**
* 获取子元素以及子元素文本数据
* @param element 子元素对象
* @param elementName 子元素标记名
*/
public void getData(Element element, String elementName)
// 获取子元素的列表集合
List<Element> elementList = element.elements(elementName);
for (Element e : elementList)
//获取属性信息
Attribute attid = e.attribute("id");
if(attid != null)
System.out.println("编号:" + attid.getValue());
String attsupplier = e.attributeValue("supplier");
if(attsupplier != null)
System.out.println("供应商编号:" + attsupplier);
//获取子元素文本数据
Element name = e.element("name");
System.out.println("名称:" + name.getText());
System.out.println("油量:" + e.elementText("oil"));
System.out.println("损耗:" + e.elementText("loss"));
// if("car".equals(elementName))
// Element brand = e.element("brand");
// System.out.println("品牌:" + brand.getText());
// else
// System.out.println("载重:" + e.elementText("load"));
//
System.out.println("----------");
public static void main(String[] args)
new TestDom4j().parseFile("src//test//vehicles.xml");
如果book2.xml
<?xml version="1.0" encoding="UTF-8"?> <books> <book id="100003"> <bookname>深入理解Java虚拟机:JVM高级特性与最佳实践</bookname> <bookauthor>周志明</bookauthor> <bookprice>79</bookprice> </book> <book id="100004"> <bookname> Java多线程编程核心技术</bookname> <bookauthor>高洪岩</bookauthor> <bookprice>99</bookprice> </book> <book id="100005"> <bookname>Java高并发编程详解:并发核心库+多线程设计</bookname> <bookauthor>汪文君</bookauthor> <bookprice>188</bookprice> </book> </books>
package test;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.util.List;
public class Dom4jParseXml
public void parseFile(String filename)
// 创建 SAX 解析对象
SAXReader reader = new SAXReader();
try
// 获取文档对象
Document document = reader.read(filename);
// 获取根元素
Element root = document.getRootElement();
// 调用数据获取的方法
this.getData(root, "book");
catch (DocumentException e)
e.printStackTrace();
/**
* 获取子元素以及子元素文本数据
* @param element 子元素对象
* @param elementName 子元素标记名
*/
public void getData(Element element, String elementName)
// 获取子元素的列表集合
List<Element> elementList = element.elements(elementName);
for (Element e : elementList)
//获取属性信息
Attribute attid = e.attribute("id");
if(attid != null)
System.out.println("编号:" + attid.getValue());
//获取子元素文本数据
Element bookname = e.element("bookname");
System.out.println("书名:" + bookname.getText());
System.out.println("作者:" + e.elementText("bookauthor"));
System.out.println("价格:" + e.elementText("bookprice"));
public static void main(String[] args)
new Dom4jParseXml().parseFile("src//test//books2.xml");
运行结果:
3.采用 SAX 方式解析 XML 数据
SAX(Simple API for XML)是一种速度更快、更有效的解析 XML 文档的方法。它不需要一次性建立一个完整的 DOM 树,而是读取文档时激活事件进行处理。
DOM 是 W3C 标准,提供的是标准的解析方式,但其解析效率一直不尽如人意。这是因为 DOM 解析 XML 文档时,把所有内容一次性装载入内存,并构建一个驻留在内存中的节点树。如果需要解析的 XML 文档过大,或者只对该文档中的一部分内容感兴趣,这种做法就会引起性能问题。
SAX 既是一个接口,也是一个软件包。
SAX 在解析 XML 时是事件驱动型的,它的工作原理简单地说就是对文档进行顺序扫描,当扫描到文档开始与结束、元素开始与结束等地方时通知事件处理程序,由事件处理程序做相应动作,然后继续同样的扫描,直至文档结束。
SAX 的缺点也很明显,要用 SAX 对 XML 文档进行解析时,就要实现多个事件处理程序,用来处理可能触发的事件,对程序员而言操作起来相对复杂。
package test;
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**
* 采用 SAX 方式解析 XML 数据
*/
public class TestSAX extends DefaultHandler
private String tagName;
// 开始解析xml文件 (只执行一次)
@Override
public void startDocument() throws SAXException
System.out.println("SAX解析开始...");
// 解析xml文件 结束(只执行一次)
@Override
public void endDocument() throws SAXException
System.out.println("SAX解析结束...");
// 开始解析xml元素(执行多次)
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
if (qName.equals("car"))
int id = Integer.parseInt(attributes.getValue(0));
System.out.println(id);
if (qName.equals("truck"))
int id = Integer.parseInt(attributes.getValue(0));
System.out.println(id);
this.tagName = qName;
// 结束 解析xml元素(执行多次)
@Override
public void endElement(String uri, String localName, String qName) throws SAXException
if (qName.equals("car"))
System.out.println("一个car标签解析完毕");
if (qName.equals("truck"))
System.out.println("一个truck标签解析完毕");
this.tagName = null;
// 在startElement、endElement 之间调用多次
@Override
public void characters(char[] ch, int start, int length) throws SAXException
if (this.tagName != null)
String data = new String(ch, start, length);// ch[] -> String
if (this.tagName.equals("name"))
System.out.print(data + "\\t");
if (this.tagName.equals("oil"))
System.out.print(Integer.parseInt(data) + "\\t");
if (this.tagName.equals("loss"))
System.out.print(Integer.parseInt(data) + "\\t");
if (this.tagName.equals("brand"))
System.out.println(data);
if (this.tagName.equals("load"))
System.out.println(data);
/**
* SAX 解析
* @param filename 解析文件
*/
public void paresFile(String filename)
try
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
parser.parse(new File(filename), this);
catch (ParserConfigurationException e)
e.printStackTrace();
catch (SAXException e)
e.printStackTrace();
catch (IOException e)
e.printStackTrace();
public static void main(String[] args) throws Exception
new TestSAX().paresFile("src//test//vehicles.xml");
运行结果:
<?xml version="1.0" encoding="UTF-8"?> <boo> <books> <book id="100003"> <bookname>深入理解Java虚拟机:JVM高级特性与最佳实践</bookname> <bookauthor>周志明</bookauthor> <bookprice>79</bookprice> </book> <book id="100004"> <bookname> Java多线程编程核心技术</bookname> <bookauthor>高洪岩</bookauthor> <bookprice>99</bookprice> </book> <book id="100005"> <bookname>Java高并发编程详解:并发核心库+多线程设计</bookname> <bookauthor>汪文君</bookauthor> <bookprice>188</bookprice> </book> </books> </boo>
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;
import java.io.IOException;
public class SaxParseXml extends DefaultHandler
/**
* 解析XML文件开始时调用
* @throws SAXException
*/
public void parseFile(String filename) throws ParserConfigurationException, SAXException, IOException
//(1)创建SAXParserFactory对象
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
//(2)通过SAXParserFactory对象创建SAXParser对象
SAXParser parser = saxParserFactory.newSAXParser();
//(3)创建DefaultHandler的子类
SaxParseXml bookDefaultHandler = new SaxParseXml();
//(4)调用parse()方法
parser.parse(filename,bookDefaultHandler);
@Override
public void startDocument() throws SAXException
super.startDocument();
System.out.println("books2文档开始解析");
/**
* 解析XML文件结束时调用
* @throws SAXException
*/
@Override
public void endDocument() throws SAXException
super.endDocument();
System.out.println("books2文档结束解析");
//解析XML文件中的节点时调用
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException
super.startElement(uri, localName, qName, attributes);
if("book".equals(qName))
//获取所有属性的长度
int length = attributes.getLength();
//遍历属性
for(int i = 0; i < length; i++)
String name = attributes.getQName(i);
String value = attributes.getValue(i);
//System.out.println("属性名:"+name+"\\t属性值:"+value);
System.out.println("编号:"+value);
else if(!"books".equals(qName) && !"book".equals(qName))
//System.out.print("节点名:"+qName+"\\t");
if(qName=="bookname")
System.out.print("书名:");
else if(qName=="bookauthor")
System.out.print("作者:");
else if(qName=="bookprice")
System.out.print("价格:");
//解析XML文件中的节点结束时调用
@Override
public void endElement(String uri, String localName, String qName) throws SAXException
super.endElement(uri, localName, qName);
//获取节点值
@Override
public void characters(char[] ch, int start, int length) throws SAXException
super.characters(ch, start, length);
String value = new String(ch, start, length);
if (!"".equals(value.trim()))
//System.out.println("节点值:" + value);
System.out.println(value);
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException
new SaxParseXml().parseFile("/home/project/books2.xml");
以上是关于解析XML数据的主要内容,如果未能解决你的问题,请参考以下文章
致命错误:未捕获的错误:在解析数据时调用字符串上的成员函数 find()
CDS Sketch Practise ! 今天教你画卡车!
CharacterEncodingFilter详解及源码解析