文件处理之XML-----DOM方式

来源:互联网 发布:js md5 sha1 消耗时间 编辑:程序博客网 时间:2024/06/06 01:19

关于XML解析的几种方式,可以去看看别人家的博客,这里主要展示DOM,SAX,DOM4J三种方式生成xml和解析xml的示例!
四种生成和解析XML文档的方法详解(介绍+优缺点比较+示例)

DOM方式生成xml:

public static void DomCreateXml() throws Exception {        // 1、创建一个DocumentBuilderFactory的对象        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();        // 2、创建一个DocumentBuilder对象        DocumentBuilder db = dbf.newDocumentBuilder();        // 3、创建一个新的Document        Document document = db.newDocument();        // 创建元素        Element songs = document.createElement("songs");        // 创建子元素(使用一个循环来创建子元素)        for (int i = 0; i < 5; i++) {            // 创建元素            Element song = document.createElement("song");            Element name = document.createElement("name");            // 向name中添加数据            // 如果改变数据可以直接定义三个数组 或者创建一个实体类 吧他们放入集合中再来赋值            name.setTextContent("春天里");            Element time = document.createElement("time");            time.setTextContent("5:20");            Element size = document.createElement("size");            size.setTextContent("30m");            //添加到上一级的元素            song.appendChild(name);            song.appendChild(time);            song.appendChild(size);            songs.appendChild(song);        }        // 添加元素到文档        document.appendChild(songs);        // 保存到项目的 demo/目录下        // 首先创建一个TransformerFactory对象        TransformerFactory tff = TransformerFactory.newInstance();        // 再利用tff创建一个Transformer        Transformer tf = tff.newTransformer();        // xml 换行        tf.setOutputProperty(OutputKeys.INDENT, "yes");        // 关联文档 和 创建xml文件        tf.transform(new DOMSource(document), new StreamResult("demo/dom.xml"));    }

使用DOM创建xml的时候需要注意DOM数的层级关系,因为DOM是w3c的标准,所以DOM具有一定的通用性,在JavaScript中操作html和上面的代码类似,这里就不赘述。下面我们再来看一下如何

DOM方式解析xml:

这里写代码片public static void DomParseXml() throws Exception {        // 1、创建一个DocumentBuilderFactory的对象        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();        // 2、创建一个DocumentBuilder对象        DocumentBuilder db = dbf.newDocumentBuilder();        // 3、通过调用db的parse的方法加载xml文件        Document parse = db.parse(new FileInputStream("demo/dom.xml"));        // 获取到了parse对象之后 就可以进行节点的解析,开始解析song节点        NodeList songs = parse.getElementsByTagName("song");        for (int i = 0; i < songs.getLength(); i++) {            // 通过item定位每一首歌的集合            Node song = songs.item(i);            // 通过song获取当前song节点里面的属性集合            NamedNodeMap attributes = song.getAttributes();            // 输出一下里面的属性            System.out.println(attributes.getLength());            // 遍历属性            for (int j = 0; j < attributes.getLength(); j++) {                // 那一个song节点里某一个属性                Node item = attributes.item(j);                // 打印属性值                System.out.println(item.getNodeName() + " = " + item.getNodeValue() + "");            }            // 遍历子节点            NodeList childNodes = song.getChildNodes();            // 输出一下子节点的长度            System.out.println(childNodes.getLength());            // 遍历子节点并且输出            for (int k = 0; k < childNodes.getLength(); k++) {                // 判断一下是否是空格                if (childNodes.item(k).getNodeType() == Node.ELEMENT_NODE) {                        System.out.println(childNodes.item(k).getNodeName() + " = " +   childNodes.item(k).getTextContent());                }            }        }    }

在获取子节点的值的时候需要注意并不是getNodeVaue()方法,而是getTextContent()方法,当然还可以使用 childNodes.item(k).getFirstChild().getNodeValue()方法获取节点值。

SAX方式生成XML

public static void SAXCreateXml() throws Exception {        // 创建一个xml文件        StreamResult streamResult = new StreamResult(new FileOutputStream("demo/sax.xml"));        // 创建好了xml文件之后需要进行设置 包括设置xml的内容        // 创建SAXTransformerFactory对象        SAXTransformerFactory tff = (SAXTransformerFactory) SAXTransformerFactory.newInstance();        // 通过tff创建TransformerHandler对象        TransformerHandler handler = tff.newTransformerHandler();        // 格式化xml文档        handler.getTransformer().setOutputProperty(OutputKeys.INDENT, "yes");        // 设置handler和xml文档关联        handler.setResult(streamResult);        // 关联了之后我们需要向xml文件中添加元素         // 首先打开document文档        handler.startDocument();        // 方便添加属性        AttributesImpl attr = new AttributesImpl();        // 打开        handler.startElement("", "", "songs", attr);        for (int i = 0; i < 5; i++) {            //这里直接定义字符串  也可自行定义数组或者集合(定义集合需要判断是否为空)            String s1 = "童话镇",s2="4:30 秒",s3="4 M";            // 先清空一下属性            attr.clear();            attr.addAttribute("", "", "id", "", "1");            handler.startElement("", "", "song", attr);            attr.clear();            handler.startElement("", "", "name", attr);            handler.characters(s1.toCharArray(), 0, s1.length());            handler.endElement("", "", "name");            attr.clear();            handler.startElement("", "", "time", attr);            handler.characters(s2.toCharArray(), 0, s2.length());            handler.endElement("", "", "time");            attr.clear();            handler.startElement("", "", "size", attr);            handler.characters(s3.toCharArray(), 0, s3.length());            handler.endElement("", "", "size");            handler.endElement("", "", "song");        }        // 关闭        handler.endElement("", "", "songs");        handler.endDocument();    }

这里我使用的是自己定义的字符串,当然也可自行定义数组或者集合,定义集合的时候需要判断一下是否为空,不要报了空指针。

SAX方式解析XML

main函数

public static ArrayList<Song> SAXParseXml() throws Exception {        // 1、获取一个SAXParserFactory对象        SAXParserFactory factory = SAXParserFactory.newInstance();        // 2、通过factory 创建SAXParser对象        SAXParser parser = factory.newSAXParser();        // 3、parse的对象的parse方法加载xml文件        // 创建一个工具类继承DefaultHandler        SAXHandler saxHandler = new SAXHandler();        parser.parse(new FileInputStream("demo/songs.xml"), saxHandler);        // 输出一下list的长度        System.out.println(saxHandler.getList().size());        List<Song> list = saxHandler.getList();        for (Song s : list) {            System.out.println(s.getId());            System.out.println(s.getName());            System.out.println(s.getTime());            System.out.println(s.getSize());        }        return (ArrayList<Song>) saxHandler.getList();    }

SAXHandler类:

public class SAXHandler extends DefaultHandler {    private List<Song> list ;    private Song song = null;    private String string = null;    // 生成getList方法 输出    public List<Song> getList() {        return list;    }    public SAXHandler() {        this.list =new ArrayList<Song>();    }    @Override    public void startDocument() throws SAXException {        super.startDocument();        System.out.println("开始解析");    }    @Override    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {        // TODO Auto-generated method stub        super.startElement(uri, localName, qName, attributes);        if (qName.equals("song")) {            // 创建实体类song的对象            song = new Song();            // 遍历song            for (int i = 0; i < attributes.getLength(); i++) {                System.out.println(attributes.getQName(i) + " = " + attributes.getValue(i));                System.out.println("\n==========================");                // 把id保存到实体类中                if (attributes.getQName(i).equals("id")) {                    song.setId(attributes.getValue(i));                }            }        } else if (!qName.equals("song") && !qName.equals("songs")) {            System.out.println("节点名:" + qName);        }    }    @Override    public void characters(char[] ch, int start, int length) throws SAXException {        // TODO Auto-generated method stub        super.characters(ch, start, length);        // 必须把节点值定义成全局的变量 否则endElement就很难获取到值        string = new String(ch, start, length);        // 去掉换行        if (!string.trim().equals("")) {            System.out.println("节点值:" + string + "\n");        }    }    @Override    public void endElement(String uri, String localName, String qName) throws SAXException {        // TODO Auto-generated method stub        super.endElement(uri, localName, qName);        if (qName.equals("song")) {            System.out.println("=============结束===============");            // 添加到集合中去            list.add(song);            // 添加到了集合中之后清空一下song            song = null;        } else if (qName.equals("name")) {            song.setName(string);        } else if (qName.equals("time")) {            song.setTime(string);        } else if (qName.equals("size")) {            song.setSize(string);        }    }    @Override    public void endDocument() throws SAXException {        // TODO Auto-generated method stub        super.endDocument();        System.out.println("结束解析");    }}

实体类Song:

package com.entity;public class Song {    private String id;    private String name;    private String time;    private String size;    public String getId() {        return id;    }    public void setId(String id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getTime() {        return time;    }    public void setTime(String time) {        this.time = time;    }    public String getSize() {        return size;    }    public void setSize(String size) {        this.size = size;    }}

上面操作:解析xml文档 —->保存到集合中—->输出
当然你不保存到集合直接输出也是可以的,直接把关于实体类和集合的代码删除可以,只是我们一般都要保存值,然后再取出来,因为我感觉有一定的普遍性,所以就贴出了保存到集合的例子。
SAX方法其实是这四种方式中解析速度是最快的,没错在中小型的xml数据中比dom4j还要快,大型的数据中dom4j是最好的,Hibernate使用dom4j就是个例子。看过开头的那篇博客都知道,SAX也有一些缺点,这里不再赘述。

DOM4J方式生成XML文档

public static void DOM4JCreateXML() throws Exception {        //1、创建document对象         Document document = DocumentHelper.createDocument();        //2、创建根节点        Element rootElement = document.addElement("songs");        //3、创建子元素节点        Element song = rootElement.addElement("song");        Element name = song.addElement("name");        name.setText("今天你要嫁给我");        Element time = song.addElement("time");        time.setText("5:20");        Element size = song.addElement("size");        size.setText("10M");        //4、生成xml文件        XMLWriter xmlWriter = new XMLWriter(                new FileOutputStream("demo/dom4j.xml"),                //格式化                 OutputFormat.createPrettyPrint()                );        //写入到文档        xmlWriter.write(document);        //关闭xmlWriter        xmlWriter.close();    }

如果没有什么特别要求的话,我觉得大家还是使用DOM4J比较好,代码量少,生成的xml文档也美观。另外,DOM4J还可以支持很多复杂的xml文档,本人还没有使用过,如果你知道也可以和我说说,非常欢迎!

DOM4J方式解析XML文档

// 创建SAXReader对象        SAXReader saxReader = new SAXReader();        // 加载books.xml文件并且获取document对象        Document document = saxReader.read(new InputStreamReader(new  FileInputStream("demo/dom4j.xml"), "utf-8"));        //通过document获取根节点        Element rootElement = document.getRootElement();        //通过根节点获取迭代器        Iterator elementIterator = rootElement.elementIterator();        while (elementIterator.hasNext()) {            Element song = (Element) elementIterator.next();            //获取book的属性名及属性值            List<Attribute> attributes = song.attributes();            for (Attribute attr : attributes) {                System.out.println(attr.getName()+" = "+attr.getValue());            }            //对song的子节点名和子节点值进行遍历            Iterator elementIterator2 = song.elementIterator();            while (elementIterator2.hasNext()) {                Element songChild = (Element) elementIterator2.next();                System.out.println("节点名:"+songChild.getName()+"  "+songChild.getStringValue());            }        }    }

这里介绍了三种方式解析XML文档,JDOM的话,本人觉得没有使用的必要,完全可以使用DOM4J方式替代,另外DOM这种方式遇到大文件的时候也处理不好,所以我推荐使用SAX方式和DOM4J方式解析和生成XML文档。最最重要的一点,差点忽略了,DOM方式和SAX是JAVA中自带的,不需要导入额外的JAR包,而JDOM和DOM4都需要导入额外的JAR包。

0 0
原创粉丝点击