Java之xml解析(Sax方式)

一. Sax基本介绍:

Sax(Simple API for XML)采用事件驱动的方式边读边解析文档。例如:在电影院看电影一样,从头到尾看一遍就完了,不能回退(Dom可来来回回读取)
【优点】

  • 只在读取数据时检查数据,不需要保存在内存中。
  • 解析是从头到尾逐行逐#个元素读取内容,但适用于只读的大文档

【缺点】

  • 需要应用程序自己负责TAG的处理逻辑(例如维护父子关系等),文档越复杂程序就越复杂,即不易编码。
  • 单向导航,很难同时访问同一个XML中的多处不同数据。

二. java 编码实现解析xml

使用SAX解析器修改XML文件内容需要先实现一个自定义的Handler,处理XML文件中的事件,然后将事件转换为对XML文件的修改。具体步骤如下:

  1. 创建SAXParserFactory实例并创建SAXParser实例。
  2. 创建一个自定义的Handler类,实现org.xml.sax.helpers.DefaultHandler抽象类。
  3. 重写DefaultHandler类的startElement()和endElement()方法,以及characters()方法,这些方法分别在遇到起始标签、结束标签以及文本节点时被调用。
  4. 在startElement()方法中,记录需要修改的节点。
  5. 在characters()方法中,对节点的文本内容进行修改。
  6. 在endElement()方法中,将修改后的节点写入新的XML文件中。
  7. 最后,通过TransformerFactory和Transformer将修改后的XML文件写入磁盘。
Sax解析流程

在这里插入图片描述

DefaultHandler各方法介绍
NODefaultHandler(事件处理器)参数作用
1public void startDocument ()throws SAXException接收xml文档开头的通知。默认情况下,不执行任何操作。应用程序编写者可以在子类中重写此方法,以便在文档开头执行特定操作(例如分配树的根节点或创建输出文件)。
2public void startElement(String uri,String localName,String qName,Attributes attributes)throws SAXExceptionuri – 命名空间URI,如果该元素没有命名空间URI或未执行命名空间处理,则为空字符串。
localName – 本地名称(无前缀),或空字符串,如果未执行命名空间处理。
qName – 限定名称(带前缀),如果限定名称不可用,则为空字符串。
attributes – 附加到元素的属性。 如果没有属性,它将是一个空的Attributes对象。
接收元素开始的通知。默认情况下,什么也不做。 应用程序编写者可以在子类中覆盖此方法,以在每个元素的开始处采取特定的操作(例如分配新的树节点或将输出写入文件)。
3public void characters(char[] ch,int start,int length)throws SAXExceptionch – 字符数组;
start – 字符数组中的起始位置;
length – 从字符数组中使用的字符数。
接收元素内的字符数据通知。默认情况下,什么也不做。 应用程序编写者可以覆盖此方法以对每个字符数据块采取特定操作(例如将数据添加到节点或缓冲区,或将其打印到文件中)。
4public void endElement(String uri,String localName,String qName)throws SAXExceptionuri – 名称空间URI,或空字符串,如果该元素没有命名空间URI或未命名空间处理。
localName – 本地名称(无前缀),或空字符串,如果未执行命名空间处理。
qName – 限定名称(带前缀),如果限定名称不可用,则为空字符串。
接收元素结尾的通知。默认情况下,什么也不做。 应用程序编写者可以在子类中覆盖此方法,以在每个元素的末尾执行特定操作(例如,完成树节点或将输出写入文件)。
5public 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);
            }
        }
    }

}

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Java中使用SAX解析XML,你可以按照以下步骤进行操作: 1. 导入相关的类和包,如`javax.xml.parsers.SAXParser`和`javax.xml.parsers.SAXParserFactory`。 2. 创建`SAXParserFactory`的实例。 3. 通过调用`SAXParserFactory`的`newSAXParser()`方法创建一个解析器。 4. 获取需要解析XML文档,并创建一个`File`对象来表示该文档。 5. 创建一个自定义的`SAXHandler`类,该类继承自`DefaultHandler`类,并重写需要的回调方法来处理XML元素和数据。 6. 调用解析器的`parse()`方法,传入文件和自定义的`SAXHandler`对象作为参数,开始解析XML文档。 你可以参考以下示例代码: ```java import java.io.File; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; public class TestDemo { public static void main(String[] args) throws Exception { // 1.实例化SAXParserFactory对象 SAXParserFactory factory = SAXParserFactory.newInstance(); // 2.创建解析SAXParser parser = factory.newSAXParser(); // 3.获取需要解析的文档,生成解析器,最后解析文档 File f = new File("books.xml"); SaxHandler dh = new SaxHandler(); parser.parse(f, dh); } } ``` 请注意,上述代码中的`SaxHandler`是一个自定义的类,你需要根据自己的需求来实现该类,以便在解析XML时处理相应的元素和数据。 XML文档如下所示: ```xml <?xml version="1.0" encoding="UTF-8"?> <books> <book id="001"> <title>Harry Potter</title> <author>J K. Rowling</author> </book> <book id="002"> <title>Learning XML</title> <author>Erik T. Ray</author> </book> </books> ``` 希望以上信息能够帮到你。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [java中使用sax解析xml的解决方法](https://download.csdn.net/download/weixin_38747216/12815749)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [在java中使用sax解析xml](https://blog.csdn.net/weixin_33884611/article/details/86303531)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值