一、JAXP
JAXP概述
JAXP作用
JAXP提供的与解析XML相关的类
二、使用SAX解析器解析XML文档
SAX采用事件机制的方式来解析XML文档,这是一种快速读写XML数据的方式
使用SAX解析器解析XML文档流程
JAXP为SAX解析器提供两组API,一般情况下用第二组API
SAX解析事件
SAXParser解析XML文档的方法
SAX解析器解析XML文档的实现思路
下面我们通过实例来解析这样一个XML文档:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<书籍列表>
<计算机书籍 xmlns:muke="http://www.muke.com">
<muke:name>Java思想</muke:name>
<作者 xmlns:author="http://xinhua.com">
<author:name>小王</author:name>
</作者>
<价格>79.00</价格>
</计算机书籍>
<计算机书籍>
<书名 name="Spring">Spring指南</书名>
<作者>小李</作者>
<价格>89.00</价格>
</计算机书籍>
<!--空元素,不能接受文本,但可以使用属性-->
<名著 书名="三国" 价格="0"/>
<!--特殊字符处理 如何显示小于号-->
<比较符>1+1<3</比较符> <!--1、使用实体引用-->
<比较符>1+1<![CDATA[1+1<3]]>3</比较符> <!--使用CDATA标记-->
</书籍列表>
解析该XML文档的Java代码如下:
1、主方法
public class SAXParse {
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
//创建SAX解析器工厂
SAXParserFactory factory = SAXParserFactory.newInstance();
//通过SAX解析器工厂实例获取SAX解析器实例
SAXParser parser = factory.newSAXParser();
//使用SAX解析器解析XML文档
parser.parse("G://javaweb//jsp//SAXParse//firstxml.xml", new MuKeHandler());
}
}
2、自定义一个类MuKeHandler继承自DefaultHandler类,并重写该类部分方法
package com.muke.sax.handler;
import org.xml.sax.Attributes;
import org.xml.sax.helpers.DefaultHandler;
public class MuKeHandler extends DefaultHandler {
//定义一个变量来保存当前正在处理的元素名称
private String currentTag;
//处理文本数据时调用该方法,返回的ch是存放文本数据的数组 文本数据就是<>ASD</>中的ASD
@Override
public void characters(char[] ch, int start, int length) {
//使用public String(char value[], int offset, int count)实例化出文本数据的String对象
String content = new String(ch, start, length);
if (content.trim().length() > 0) {
//若文本数据有值,输出当前文本数据及其元素名称
System.out.println("<" + currentTag + ">元素的值是:" + content.trim());
}
}
//解析文档结束时调用的方法
@Override
public void endDocument() {
System.out.println("解析XML文档结束");
}
//解析元素(节点)结束时调用的方法
@Override
public void endElement(String uri, String localName, String qName) {
System.out.println("解析元素" + qName + "结束");
}
//解析文档开始时调用该方法
@Override
public void startDocument() {
System.out.println("解析XML文档开始");
}
//元素(节点)开始时调用该方法
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) {
System.out.println("开始解析元素" + qName);
//保存当前正在处理的元素(节点)
currentTag = qName;
if (attributes.getLength() > 0) {
//若当前处理的元素(节点)有属性
System.out.println("<" + currentTag + ">元素的属性如下");
//输出当前元素所有的属性及属性值
for (int i = 0; i < attributes.getLength(); i++) {
//attributes.getQName(int index) 获取属性名,参数index为属性在这个元素中的位置
System.out.println(attributes.getQName(i) + "---->" + attributes.getValue(i));
}
}
}
}
运行结果如下:
解析XML文档开始
开始解析元素书籍列表
开始解析元素计算机书籍
<计算机书籍>元素的属性如下
xmlns:muke---->http://www.muke.com
开始解析元素muke:name
<muke:name>元素的值是:Java思想
解析元素muke:name结束
开始解析元素作者
<作者>元素的属性如下
xmlns:author---->http://xinhua.com
开始解析元素author:name
<author:name>元素的值是:小王
解析元素author:name结束
解析元素作者结束
开始解析元素价格
<价格>元素的值是:79.00
解析元素价格结束
解析元素计算机书籍结束
开始解析元素计算机书籍
开始解析元素书名
<书名>元素的属性如下
name---->Spring
<书名>元素的值是:Spring指南
解析元素书名结束
开始解析元素作者
<作者>元素的值是:小李
解析元素作者结束
开始解析元素价格
<价格>元素的值是:89.00
解析元素价格结束
解析元素计算机书籍结束
开始解析元素名著
<名著>元素的属性如下
书名---->三国
价格---->0
解析元素名著结束
开始解析元素比较符
<比较符>元素的值是:1+1
<比较符>元素的值是:<
<比较符>元素的值是:3
解析元素比较符结束
开始解析元素比较符
<比较符>元素的值是:1+1
<比较符>元素的值是:1+1<3
<比较符>元素的值是:3
解析元素比较符结束
解析元素书籍列表结束
解析XML文档结束
SAX生成XML文档
使用SAX生产处理者生成XML文档流程
生成XML的代码如下:
public class BuildXMLMain {
public static void main(String[] args) throws TransformerConfigurationException, SAXException {
//创建保存XML的结果流对象
Result resultXML = new StreamResult(new File("G://javaweb//jsp//SAXParse//firstxml1.xml"));
//获取sax生成工厂对象实例
SAXTransformerFactory saxTransformerFactory = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
//获取SAX生产处理者对象实例
TransformerHandler transformerHandler = saxTransformerFactory.newTransformerHandler();
transformerHandler.setResult(resultXML);
//获取SAX生成器
Transformer transformer = transformerHandler.getTransformer();
//生成XML文档的时候允许生成额外的空格
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
//开始生成XML文档
transformerHandler.startDocument();
AttributesImpl attributes = new AttributesImpl();//若元素有属性可以使用attributes.addAttribute
//生成文档元素 public void startElement (String uri, String localName, String qName, Attributes atts)
transformerHandler.startElement("", "", "书籍列表", attributes);
transformerHandler.startElement("", "", "计算机书籍", attributes);
transformerHandler.startElement("", "", "书名", attributes);
//向元素中添加文本数据 public void characters (char ch[], int start, int length)
transformerHandler.characters("Java思想".toCharArray(), 0, "Java思想".length());
//结束元素的生成 public void endElement (String uri, String localName, String qName)
transformerHandler.endElement("", "", "书名");
transformerHandler.startElement("", "", "作者", attributes);
transformerHandler.characters("小王".toCharArray(), 0, "小王".length());
transformerHandler.endElement("", "", "作者");
transformerHandler.startElement("", "", "价格", attributes);
transformerHandler.characters("79.00".toCharArray(), 0, "79.00".length());
transformerHandler.endElement("", "", "价格");
transformerHandler.endElement("", "", "计算机书籍");
//第二本书
transformerHandler.startElement("", "", "计算机书籍", attributes);
transformerHandler.startElement("", "", "书名", attributes);
transformerHandler.characters("Spring指南".toCharArray(), 0, "Spring指南".length());
transformerHandler.endElement("", "", "书名");
transformerHandler.startElement("", "", "作者", attributes);
transformerHandler.characters("小李".toCharArray(), 0, "小李".length());
transformerHandler.endElement("", "", "作者");
transformerHandler.startElement("", "", "价格", attributes);
transformerHandler.characters("89.00".toCharArray(), 0, "89.00".length());
transformerHandler.endElement("", "", "价格");
transformerHandler.endElement("", "", "计算机书籍");
//
transformerHandler.endElement("", "", "书籍列表");
//结束文档生成
transformerHandler.endDocument();
}
}
最终生成的文档如下:
<?xml version="1.0" encoding="UTF-8"?><书籍列表><计算机书籍><书名>Java思想</书名><作者>小王</作者><价格>79.00</价格></计算机书籍><计算机书籍><书名>Spring指南</书名><作者>小李</作者><价格>89.00</价格></计算机书籍></书籍列表>