文章目录
一. Sax基本介绍:
Sax(Simple API for XML)采用事件驱动的方式边读边解析文档。例如:在电影院看电影一样,从头到尾看一遍就完了,不能回退(Dom可来来回回读取)
【优点】
- 只在读取数据时检查数据,不需要保存在内存中。
- 解析是从头到尾逐行逐#个元素读取内容,但适用于只读的大文档
【缺点】
- 需要应用程序自己负责TAG的处理逻辑(例如维护父子关系等),文档越复杂程序就越复杂,即不易编码。
- 单向导航,很难同时访问同一个XML中的多处不同数据。
二. java 编码实现解析xml
使用SAX解析器修改XML文件内容需要先实现一个自定义的Handler,处理XML文件中的事件,然后将事件转换为对XML文件的修改。具体步骤如下:
- 创建SAXParserFactory实例并创建SAXParser实例。
- 创建一个自定义的Handler类,实现org.xml.sax.helpers.DefaultHandler抽象类。
- 重写DefaultHandler类的startElement()和endElement()方法,以及characters()方法,这些方法分别在遇到起始标签、结束标签以及文本节点时被调用。
- 在startElement()方法中,记录需要修改的节点。
- 在characters()方法中,对节点的文本内容进行修改。
- 在endElement()方法中,将修改后的节点写入新的XML文件中。
- 最后,通过TransformerFactory和Transformer将修改后的XML文件写入磁盘。
Sax解析流程
DefaultHandler各方法介绍
NO | DefaultHandler(事件处理器) | 参数 | 作用 |
---|---|---|---|
1 | public void startDocument ()throws SAXException | 接收xml文档开头的通知。默认情况下,不执行任何操作。应用程序编写者可以在子类中重写此方法,以便在文档开头执行特定操作(例如分配树的根节点或创建输出文件)。 | |
2 | public void startElement(String uri,String localName,String qName,Attributes attributes)throws SAXException | uri – 命名空间URI,如果该元素没有命名空间URI或未执行命名空间处理,则为空字符串。 localName – 本地名称(无前缀),或空字符串,如果未执行命名空间处理。 qName – 限定名称(带前缀),如果限定名称不可用,则为空字符串。 attributes – 附加到元素的属性。 如果没有属性,它将是一个空的Attributes对象。 | 接收元素开始的通知。默认情况下,什么也不做。 应用程序编写者可以在子类中覆盖此方法,以在每个元素的开始处采取特定的操作(例如分配新的树节点或将输出写入文件)。 |
3 | public void characters(char[] ch,int start,int length)throws SAXException | ch – 字符数组; start – 字符数组中的起始位置; length – 从字符数组中使用的字符数。 | 接收元素内的字符数据通知。默认情况下,什么也不做。 应用程序编写者可以覆盖此方法以对每个字符数据块采取特定操作(例如将数据添加到节点或缓冲区,或将其打印到文件中)。 |
4 | public void endElement(String uri,String localName,String qName)throws SAXException | uri – 名称空间URI,或空字符串,如果该元素没有命名空间URI或未命名空间处理。 localName – 本地名称(无前缀),或空字符串,如果未执行命名空间处理。 qName – 限定名称(带前缀),如果限定名称不可用,则为空字符串。 | 接收元素结尾的通知。默认情况下,什么也不做。 应用程序编写者可以在子类中覆盖此方法,以在每个元素的末尾执行特定操作(例如,完成树节点或将输出写入文件)。 |
5 | public void endDocument () throws SAXException | 接收xml文档结束的通知。默认情况下,不执行任何操作。应用程序编写者可以在子类中重写此方法,以便在文档末尾执行特定操作(例如完成树或关闭输出文件)。 |
XML与java对象之间的转换
1.xml文件的内容
<?xml version="1.0" encoding="UTF-8"?>
<root>
<person id="1">
<name>Tom</name>
<age>20</age>
</person>
<person id="2">
<name>Mary</name>
<age>25</age>
</person>
</root>
2.XML与java对象之间的转换code
package test_sax;
import java.io.File;
import java.io.FileOutputStream;
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;
public class Test {
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
// 创建SAXParser实例
SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
SAXParser saxParser = saxParserFactory.newSAXParser();
// 创建自定义的Handler
CustomHandler handler = new CustomHandler();
// 解析XML文件(顺带里面包含了打印xml文件的内容)
saxParser.parse(new File("C:\\Users\\mats\\IdeaProjects\\xmlParses\\src\\resource\\xml\\sax_test.xml"), handler);
// 将修改后的XML文件写入磁盘
FileOutputStream fos = new FileOutputStream("C:\\Users\\mats\\IdeaProjects\\xmlParses\\src\\resource\\xml\\sax_test_new.xml");
fos.write(handler.getXmlContent().getBytes());
fos.close();
System.out.println("XML文件修改成功!");
}
private static class CustomHandler extends DefaultHandler {
private StringBuilder xmlContent = new StringBuilder();
private String currentElement;
public String getXmlContent() {
return xmlContent.toString();
}
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
System.out.println("<"+qName+">");
for(int i=0;i<attributes.getLength();i++){
System.out.println(attributes.getQName(i) + ":"
+ attributes.getValue(i));
}
currentElement = qName;
// 添加开始标记
xmlContent.append("<").append(qName);
for (int i = 0; i < attributes.getLength(); i++) {
String attributeName = attributes.getQName(i);
String attributeValue = attributes.getValue(i);
xmlContent.append(" ").append(attributeName).append("=\"").append(attributeValue).append("\"");
}
xmlContent.append(">");
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
System.out.println("<"+qName+">");
currentElement = null;
// 添加结束标记
xmlContent.append("</").append(qName).append(">");
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
System.out.println(new String(ch, start, length));
if (currentElement != null && currentElement.equals("age")) {
// 修改age节点的文本内容
xmlContent.append("80");
} else {
xmlContent.append(ch, start, length);
}
}
}
}