[Java]_[初级]_[使用SAX流的方式写入XML文件]

场景

  1. 文件的写入目前没有发现可以增量写入的,只能是完全重新写入。对于大量数据需要写入XML文件,还是和读XML文件一样,不需要生成DOM模型能节省不少的内存和指令。

说明

  1. java标准库里,也是有相关的SAX类来写入数据流,StreamResult(OutputStream)负责把数据写入输出流。
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;

FileOutputStream fo = new FileOutputStream(file);
StreamResult streamResult = new StreamResult(fo);

  1. 之后创建一个TransformerHandler来负责绑定StreamResult并开始写入元素名称,元素值,属性值,子元素等。

  2. Handler还可以设置输出是否带缩进,输出的编码格式。

例子

  1. 这里例子是生成sitemap.xml文件,这里的SitemapMap对象。SitemapReader

SitemapWriter


import Sitemap;
import StringUtils;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;

import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.List;

public class SitemapWriter {

    public boolean writeToFile(File file, List<Sitemap> sitemaps){

        SAXTransformerFactory factory = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
        URL resource = this.getClass().getResource("/");
        String path = resource.getPath();

        boolean result = false;
        try(FileOutputStream fo = new FileOutputStream(file);) {
            TransformerHandler handler = factory.newTransformerHandler();
            Transformer transformer = handler.getTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
                transformer.setOutputProperty(OutputKeys.ENCODING, "utf-8");

            StreamResult streamResult = new StreamResult(fo);
            handler.setResult(streamResult);
            handler.startDocument();

            AttributesImpl attributes = new AttributesImpl();
            attributes.addAttribute("","","xmlns","","http://www.sitemaps.org/schemas/sitemap/0.9");
            attributes.addAttribute("","","xmlns:xhtml","","http://www.w3.org/1999/xhtml");
            handler.startElement("", "", "urlset", attributes);
            attributes.clear();

            // url
            for (int i = 0; i < sitemaps.size(); i++) {
                Sitemap one = sitemaps.get(i);

                handler.startElement("","","url",null);
                handler.startElement("","","loc",null);
                String loc = StringUtils.nullToEmpty(one.getStr("loc"));
                handler.characters(loc.toCharArray(), 0, loc.length());
                handler.endElement("","","loc");

                handler.startElement("","","priority",null);
                String priority = StringUtils.nullToEmpty(one.getStr("priority"));
                handler.characters(priority.toCharArray(), 0, priority.length());
                handler.endElement("","","priority");

                handler.startElement("","","lastmod",null);
                String lastmod = StringUtils.nullToEmpty(one.getStr("lastmod"));
                handler.characters(lastmod.toCharArray(), 0, lastmod.length());
                handler.endElement("","","lastmod");

                handler.startElement("","","changefreq",null);
                String changefreq = StringUtils.nullToEmpty(one.getStr("changefreq"));
                handler.characters(changefreq.toCharArray(), 0, changefreq.length());
                handler.endElement("","","changefreq");
                handler.endElement("","","url");
            }

            handler.endElement("","","urlset");
            handler.endDocument();
            result = true;
        } catch (TransformerConfigurationException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        }

        return result;
    }
}

TestSitemapWriter

import Sitemap;
import SitemapReader;
import SitemapWriter;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import javax.xml.transform.sax.SAXTransformerFactory;
import java.io.File;
import java.net.URL;
import java.util.List;

@RunWith(JUnit4.class)
public class TestSitemapWriter {

    @Test
    public void testSitemapWriter(){
        SAXTransformerFactory factory = (SAXTransformerFactory) SAXTransformerFactory.newInstance();
        URL resource = this.getClass().getResource("/");
        String path = resource.getPath();

        File file = new File(path+"..\\..\\..\\..\\doc\\tests\\xml\\sitemap.xml");
        SitemapReader sr = new SitemapReader();
        if(sr.readAll(file)){
            List<Sitemap> sitemaps = sr.getSitemaps();
            file = new File(path+"\\sitemap.xml");
            SitemapWriter writer = new SitemapWriter();
            writer.writeToFile(file,sitemaps);
        }
    }
}


参考

  1. Java——SAX方式生成XML

  2. SAXTransformerFactory

  3. 以SAX流的方式高效读取XML大文件

你可能感兴趣的:(Java语言特性和标准库,JavaWeb开发实战,java,xml,sax,生成XML,DOM)