第二十二章 JAVA眼中的XML--文件写入

第一节 通过DOM方式生成XML文件

这里我们学习如何使用DOM方法生成一个XML文件,还是先打开上节课读取xml的代码。这里生成方法的前两步都是一样的,所以可以把这两步提取出来做一个方法来提高代码的复用率。
打开生成的xml文件,第一行声明有一个standalone=”no”,如果这个standalone=yes,是说明我们当前的xml文件是没有dtd和schema作为它的说明文档的。如果=no说明它是有这两个作为解释说明它的内容允许有哪些值以及值的一些允许的形式,由于我们当前的xml文件是一个很简单的xml文件,它不涉及格式说明要求,所以我们不需要这个standalone,所以说我们应该将它设置成yes并且不显示在我们的第一行声明部分。那如何去掉呢?还有关于生成的xml文件内容怎么换行以提高阅读效果,具体的解决方法都在代码中可以体现出来

public class DOMTest {
    public DocumentBuilder getDocumentBuilder(){
        //这里我们就可以写解析xml文件的代码books.xml文件的位置C:\Users\Administrator\Desktop
        //创建一个DocumentBuilderFactory的对象
        DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
        //创建一个DocumentBuilder的对象,通过上一个对象,dbf.newDocumentBuilder()方法来创建新的对象
        DocumentBuilder db=null;
        try {
            db=dbf.newDocumentBuilder();
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        }
        return db;
    }
    /**
     * 生成xml的方法
     */
    public void createXML() {
        //先创建一个DocumentBuilder对象来接收方法返回值
        DocumentBuilder db = getDocumentBuilder();
        Document document = db.newDocument();//解析是用的parse方法,而生成我们就要换一个方法了,去生成一个新的document,这就等于
        //我们将要放在xml文件中的整个dom树。
        //然后我们要给DOM树增加节点,首先是根节点
        //处理第一行的standalone,为yes,默认不显示。
        document.setXmlStandalone(true);
        Element bookstore = document.createElement("bookStore");
        //向bookstore根节点添加子节点book
        Element book = document.createElement("book");
        //如何向book节点中添加属性呢?
        book.setAttribute("id", "1");
        Element name=document.createElement("name");
        //失效依然是null没有文本
        //name.setNodeValue("小王子");
        name.setTextContent("冰与火之歌");
        book.appendChild(name);
        Element author=document.createElement("author");
        //失效依然是null没有文本
        //name.setNodeValue("小王子");
        author.setTextContent("乔治马丁");
        book.appendChild(author);
        Element year=document.createElement("year");
        //失效依然是null没有文本
        //name.setNodeValue("小王子");
        year.setTextContent("2014");
        book.appendChild(year);
        Element price=document.createElement("price");
        //失效依然是null没有文本
        //name.setNodeValue("小王子");
        price.setTextContent("89");
        book.appendChild(price);
        bookstore.appendChild(book);
        //将根节点(已经包含了book节点)添加在document里
        Element book1 = document.createElement("book");
        //如何向book节点中添加属性呢?
        book1.setAttribute("id", "2");
        Element name1=document.createElement("name");
        //失效依然是null没有文本
        //name.setNodeValue("小王子");
        name1.setTextContent("安徒生童话");
        book1.appendChild(name1);
        Element year1=document.createElement("year");
        //失效依然是null没有文本
        //name.setNodeValue("小王子");
        year1.setTextContent("2004");
        book1.appendChild(year1);
        Element price1=document.createElement("price");
        //失效依然是null没有文本
        //name.setNodeValue("小王子");
        price1.setTextContent("77");
        book1.appendChild(price1);
        Element language=document.createElement("language");
        //失效依然是null没有文本
        //name.setNodeValue("小王子");
        language.setTextContent("English");
        book1.appendChild(language);
        bookstore.appendChild(book1);
        document.appendChild(bookstore);

        //如何将现有的树结构转换成xml文件
        TransformerFactory tff = TransformerFactory.newInstance();
        try {
            Transformer tf=tff.newTransformer();
            //接下来我们就可以利用transformer对象它有一个transform方法,用它来将我们的document树结构转换成xml
            //换行操作
            tf.setOutputProperty(OutputKeys.INDENT,"yes");
            tf.transform(new DOMSource(document), new StreamResult(new File("C:\\Users\\Administrator\\Desktop\\" +
                    "books4.xml")));
            //这里两个参数第一个填我们要转换的内容,也就是填我们的源资源,第二个就是我们要转换的文件,需要有输出流
            //dom提供给我们一个输出流,StreamResult,可以new一个它
        } catch (TransformerConfigurationException e) {
            e.printStackTrace();
        }catch (TransformerException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        DOMTest test1=new DOMTest();
        //test1.xmlParser();
        test1.createXML();
    }
}

第二节 通过SAX方式生成XML文件

SAX生成XML的准备工作,这里我们将之前的SAXTest进行一下修改,将main方法中进行解析xml的方法提取出来作为一个方法,并且已知我们之前进行了对象的赋值存储List,该方法返回一个我们之前存储了Book对象的List,本节的目的就是用这两个对象使用SAX方式生成xml文件。

public void createXML(){
        ArrayList<Book> bookList=SAXParseXML();
        //生成xml
        //1.创建一个TransformerFactory类的对象
        SAXTransformerFactory tff=(SAXTransformerFactory)TransformerFactory.newInstance();
        try {
            //2.通过SAXTransformerFactory对象创建TransformerHandler对象
            TransformerHandler handler=tff.newTransformerHandler();
            //3.通过handler对象创建一个Transformer对象,利用transformer对象我们可以利用它来进行一些xml文件的设置
            Transformer tr=handler.getTransformer();
            //4.用transformer对象我们可以利用它来进行一些xml文件的设置
            tr.setOutputProperty(OutputKeys.ENCODING,"UTF-8");//设置xml的编码
            tr.setOutputProperty(OutputKeys.INDENT,"yes");//设置xml是否换行
            //5.创建一个result对象
            File file=new File("C:\\Users\\Administrator\\Desktop\\books5.xml");
            if(!file.exists()) file.createNewFile();
            Result result=new StreamResult(new FileOutputStream(file));
            //6.创建result对象,并且使其和handler对象关联
            handler.setResult(result);
            //注意:如果将3,4步挪到result后面将是失效的,如果将第六步挪到最后会提示必须先调用result,才可以使用
            //startDocument,这样写会报错
            //7.利用handler对象,进行xml文件内容的编写
            //打开document
            handler.startDocument();
            //
            AttributesImpl attr=new AttributesImpl();
            handler.startElement("","","bookstore", attr);
            for(Book book:bookList){
                //属性
                attr.clear();
                attr.addAttribute("","","id","",book.getId());
                handler.startElement("","","book",attr);
                //创建name节点
                if(book.getName()!=null&&book.getName().trim()!=""){
                    attr.clear();
                    handler.startElement("","","name",attr);
                    handler.characters(book.getName().toCharArray(),0,book.getName().length());
                    handler.endElement("","","name");
                }
                //创建Author节点
                if(book.getAuthor()!=null&&book.getAuthor().trim()!="") {
                    attr.clear();
                    handler.startElement("", "", "author", attr);
                    handler.characters(book.getAuthor().toCharArray(), 0, book.getAuthor().length());
                    handler.endElement("", "", "author");
                }
                //创建year节点
                if(book.getYear()!=null&&book.getYear().trim()!="") {
                    attr.clear();
                    handler.startElement("", "", "year", attr);
                    handler.characters(book.getYear().toCharArray(), 0, book.getYear().length());
                    handler.endElement("", "", "year");
                }
                //创建price节点
                if(book.getPrice()!=null&&book.getPrice().trim()!="") {
                    attr.clear();
                    handler.startElement("", "", "price", attr);
                    handler.characters(book.getPrice().toCharArray(), 0, book.getPrice().length());
                    handler.endElement("", "", "price");
                }
                //创建languager节点
                if(book.getLanguage()!=null&&book.getLanguage().trim()!="") {
                    attr.clear();
                    handler.startElement("", "", "language", attr);
                    handler.characters(book.getLanguage().toCharArray(), 0, book.getLanguage().length());
                    handler.endElement("", "", "language");
                }
                handler.endElement("","","book");
            }
            handler.endElement("","","bookstore");

            //关闭document
            handler.endDocument();
        } catch (TransformerConfigurationException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }catch (IOException e) {
            e.printStackTrace();
        }catch (SAXException e) {
            e.printStackTrace();
        }
    }

注意:如果将准备工作的3,4步挪到result后面将是失效的,如果将第六步挪到最后会提示必须先调用result,才可以使用。

第三节 通过DOM4J方式生成xml文件

什么是RSS?
之前我们已经学习了如何用dom和sax来生成xml文件,接下来我们来学习如何使用dom4j来生成。本节课我们生成的xml文件会和之前有所不同,本节课我们学习如何来生成一个RSS格式的xml文件,那什么是RSS呢?这里是我之前找到的一个RSS源,RSS通常是用来描述和同步网站内容的一种格式,其实它的本质就是XML,我们在RSS源这个页面上右键,查看源代码,可以看到呈现给我们的一个源代码,其实就是一个xml文件,只不过它的格式是有一些特殊的。<rss version="2.0">
RSS格式的XML源码
如果我们生成的内容有特殊符号怎么办?比如说通常用<>来包裹标签,如果内容中也出现<>会出现什么情况,它会自动给我们进行转义,可是我们不希望生成的文本中括号给我们转义,那么很简单,我们可以通过一行代码就可以解决,通过writer.setEscapeText(false);方法设置是否转义。

/**
     *生成xml
     */
    public void cerateXML(){
        //1.创建Document对象,dom4j包下的,代表整个xml文档
        Document document= DocumentHelper.createDocument();
        //2.创建根节点rss
        Element rss=document.addElement("rss");
        //3.向rss节点中添加文本这个属性
        rss.addAttribute("version","2.0");
        //4.生成子节点和节点内容
        Element channel=rss.addElement("channel");
        Element title=channel.addElement("title");
        title.setText("国内最新新闻");
        //5.设置生成xml的格式
        OutputFormat format=OutputFormat.createPrettyPrint();
        //format.setEncoding("GBK");设置编码格式
        //6.生成文件
        try {
            File file=new File("C:\\Users\\Administrator\\Desktop\\lianxi.xml");
            if(!file.exists()) file.createNewFile();
            XMLWriter writer=new XMLWriter(new FileOutputStream(file),format);
            //设置是否转义,默认true代表转义
            writer.setEscapeText(false);
            writer.write(document);
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

第四节 通过JDOM方式生成XML

 /**
     * 生成xml
     */
    public void createXml(){
        //1.生成一个根节点
        Element rss=new Element("rss");
        //2.为节点添加属性
        rss.setAttribute("version","2.0");
        //3.生成一个document对象
        Document document=new Document(rss);
        Element channel=new Element("channel");
        rss.addContent(channel);
        Element title=new Element("title");
        title.setText("国内最新新闻");
        channel.addContent(title);

        //设置格式
        Format ft=Format.getCompactFormat();
        ft.setIndent("");
        ft.setEncoding("GBK");
        //4.创建XMLOutputter对象
        XMLOutputter outputer=new XMLOutputter(ft);
        //5.利用Outputer方法将document转换为xml文档
        try {
            outputer.output(document,new FileOutputStream(new File("demo\\rss.xml")));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

第五节 四种生成方法大PK

四种生成方法的理论对比
就解析而言,DOM基于树结构,SAX是基于事件驱动的,JDOM和DOM4J都是基于底层API,底层API就是指的官方提供给我们的解析方式,就是DOM和SAX。
在DOM生成中,我们DOM生成的DOM树它会驻留在我们的内存中,也就是首先我们会生成一个根节点,然后会在根节点中生成根节点下的子节点。驻留在内存中的好处是什么呢?可以随时删除或者修改,接下来我们也可以针对dom树进行重新排列,方便我们修改。SAX生成是不能走回头路的,如果不会频繁修改建议SAX,修改多的可以考虑DOM。进行生成速度比较的话,DOM慢SAX快,DOM4J次之。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值