首页 > 技术专区 > Java > Java XML 屏幕太窄?试试伸展一下吧 >

Java XML

1. XML简介

XML(EXtensible Markup Language),可扩展标记语言

特点

XML与操作系统、编程语言的开发平台无关

实现不同系统之间的数据交换

作用

数据交互

配置应用程序和网站

2. XML文档结构

<?xml version="1.0" encoding="UTF-8"?>
<books>
    <!--图书信息 -->
    <book id="bk101">
        <author>王珊</author>
        <title>.NET高级编程</title>
        <description>包含C#框架和网络编程等</description>
    </book>
    <book id="bk102">
        <author>李明明</author>
        <title>XML基础编程</title>
        <description>包含XML基础概念和基本作用</description>
    </book>
</books>

3. XML标签

XML文档内容由一系列标签元素组成

<元素名 属性名 = “属性值”>元素内容</元素名>

空元素:

<name>  </name>
<name></name>
<name/>

属性值用双引号包裹

一个元素可以有多个属性

属性值中不能直接包含<、“、&(不建议:‘、>)

4. XML编写注意事项

所有XML元素都必须有结束标签

XML标签对大小写敏感

XML必须正确的嵌套

同级标签以缩进对齐

元素名称可以包含字母、数字或其他的字符

元素名称不能以数字或者标点符号开始

元素名称中不能含空格

5. 转义符

XML中的转义符列表

image.png

当元素中出现很多特殊字符时,可以使用CDATA节,如:

<description>
    <![CDATA[讲解了元素<title>以及</title>的使用]]>
</description>

6. 解析XML技术

image.png

DOM

基于XML文档树结构的解析

适用于多次访问的XML文档

特点:比较消耗资源

SAX

基于事件的解析

适用于大数据量的XML文档

特点:占用资源少,内存消耗小

DOM4J

非常优秀的Java XML API

性能优异、功能强大

开放源代码

7. DTD

DTD即文档类型定义--Document Type Definition 

使每个XML文件可以携带一个自身格式的描述

一个DTD文档可能包含如下内容:

元素的定义规则

元素之间的关系规则

属性的定义规则

编写DTD文档

<?xml version="1.0"?>
<!DOCTYPE poem [
    <!ELEMENT poem (author,title,content) >
    <!ELEMENT author (#PCDATA)>
    <!ELEMENT title (#PCDATA)>
    <!ELEMENT content (#PCDATA)>
]>
<poem>
    <author>王维</author>
    <title>鹿柴</title>
    <content>空山不见人,但闻人语声。返景入深林,复照青苔上。     
    </content>
</poem>

8. DOM解析XML

DOM介绍

文档对象模型(Document Object Model)

DOM把XML文档映射成一个倒挂的树

image.png


常用接口介绍

DOM解析包:org.w3c.domimage.png

访问DOM树节点

DOM解析XML文件步骤:

创建解析器工厂对象

解析器工厂对象创建解析器对象

解析器对象指定XML文件创建Document对象

以Document对象为起点操作DOM树

phone.xml

<?xml version="1.0" encoding="GB2312"?>
<PhoneInfo>
    <Brand name="华为">
        <Type name="P9"/>
    </Brand>
    <Brand name="苹果">
        <Type name="Iphone6"/>
        <Type name="Iphone7"/>
    </Brand>
</PhoneInfo>

ParseXmlDemo.java

package com.liqinglin.test;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;

public class ParseXmlDemo {
    //收藏信息,xml对应的Document对象
    private Document document;

    //获得DOM树,获得Document对象
    public void getDom(){
        //获得解析器工厂
        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();

        try {
            //根据解析器工厂获得解析器
            DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
            //解析器来解析XML文件获得Document对象
            document = documentBuilder.parse("phone.xml");
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    //获取手机品牌及型号相关信息
    public void showInfo(){
        //以Document数起点,先拿到所有的Brand节点
        NodeList brands = document.getElementsByTagName("Brand");
        //遍历brands,从中拿到每一个Brand节点
        for (int i = 0; i < brands.getLength(); i++){
            Node node = brands.item(i);
            Element eleBrand = (Element) node;
            String brandName = eleBrand.getAttribute("name");
            System.out.println(brandName);
            //继续查找,找每个Brands的子节点出来
            NodeList types = eleBrand.getChildNodes();
            for (int j = 0; j < types.getLength(); j++){
                Node typeNode = types.item(j);
                //判断该子节点是否是元素节点
                if(typeNode.getNodeType() == Node.ELEMENT_NODE){
                    Element typeEle = (Element) typeNode;
                    System.out.println("\t" + typeEle.getAttribute("name"));
                }
            }
        }
    }

    //为XML文件添加元素
    public void addEle(){
        //(1)创建<Brand>
        Element brand = document.createElement("Brand");
        //(2)为<Bradn>设置name属性取值为三星
        brand.setAttribute("name", "三星");
        Element type = document.createElement("Type");
        type.setAttribute("name", "NOTE2");
        //将Type作为Brand的子元素
        brand.appendChild(type);
        //将Brand放到PhoneInfo中去
        document.getElementsByTagName("PhoneInfo").item(0).appendChild(brand);
    }

    //保存XML文件(需要借助转换器 源:最新的dom树 --> 目的地:phone.xml,借助的输出流)
    public void saveXML(){
        //转换器工厂
        TransformerFactory factory = TransformerFactory.newInstance();
        //设置缩进
        factory.setAttribute("indent-number", 4);
        try {
            //获取转换器
            Transformer transformer = factory.newTransformer();
            //指定转换格式
            transformer.setOutputProperty(OutputKeys.ENCODING, "GB2312");
            transformer.setOutputProperty(OutputKeys.INDENT, "YES");

            DOMSource source = new DOMSource(document);
            OutputStream out = new FileOutputStream("phone.xml");
            StreamResult result = new StreamResult(new OutputStreamWriter(out, "GB2312"));
            transformer.transform(source, result);
        } catch (TransformerConfigurationException | FileNotFoundException e) {
            e.printStackTrace();
        } catch (TransformerException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
    }

    //修改元素
    public void updateEle(){
        //获取所有的Brand
        NodeList brands = document.getElementsByTagName("Brand");
        for(int i = 0; i < brands.getLength(); i++){
            Node brand = brands.item(i);
            Element brandEle = (Element) brand;
            brandEle.setAttribute("id", i+"");
        }
        this.saveXML();
    }

    //删除 华为手机
    public void deleteEle(){
        //获取所有的Brand
        NodeList brands = document.getElementsByTagName("Brand");
        for(int i = 0; i < brands.getLength(); i++){
            Node brand = brands.item(i);
            Element brandEle = (Element) brand;

            if(brandEle.getAttribute("name").equals("华为")){
                brandEle.getParentNode().removeChild(brandEle);
            }
        }
        this.saveXML();
    }

    public static void main(String[] args) {
        ParseXmlDemo parseXmlDemo = new ParseXmlDemo();

        parseXmlDemo.getDom();
        parseXmlDemo.addEle();
        parseXmlDemo.showInfo();
        parseXmlDemo.updateEle();
        parseXmlDemo.deleteEle();
        parseXmlDemo.saveXML();
    }
}

9. DOM4J

Document:定义XML文档

Element:定义XML元素

Text:定义XML文本节点

Attribute:定义了XML 的属性

……


Dom4jDemo.java

package com.liqinglin.test;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import java.io.*;
import java.util.Iterator;

public class Dom4jDemo {

    private Document document;

    //获得document对象
    public void loadDocument(){
        SAXReader saxReader = new SAXReader();
        try {
            document = saxReader.read(new File("phone.xml"));
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }

    //显示手机的品牌及型号
    public void showInfo(){
        //获取XML根节点
        Element root = document.getRootElement();
        //获取所有的<Brand>
        Iterator eleBrands = root.elementIterator();
        while(eleBrands.hasNext()){
            Element brand = (Element) eleBrands.next();
            System.out.println(brand.attributeValue("name"));
            //获取所有的<Type>
            Iterator eleTypes = brand.elementIterator();
            while(eleTypes.hasNext()){
                Element type = (Element) eleTypes.next();
                System.out.println("\t" + type.attributeValue("name"));
            }
        }
    }

    //增加新的手机信息
    public void addNewPhone(){
        //获取XML根元素
        Element root = document.getRootElement();
        //创建<Brand>
        Element eleBrand = root.addElement("Brand");
        eleBrand.addAttribute("name", "三星");
        //创建<Type>
        Element eleType = eleBrand.addElement("Type");
        eleType.addAttribute("name", "SX123");
    }

    //修改节点
    public void updatePhone(){
        Element root = document.getRootElement();
        Iterator eleBrands = root.elementIterator();
        int id = 0;
        while(eleBrands.hasNext()){
            Element brand = (Element) eleBrands.next();
            id++;
            brand.addAttribute("id", id+"");
        }
        this.saveXML();
    }

    //删除节点
    public void deletePhone(){
        Element root = document.getRootElement();
        Iterator eleBrands = root.elementIterator();
        while(eleBrands.hasNext()){
            Element brand = (Element) eleBrands.next();
            if(brand.attributeValue("name").equals("华为")){
                brand.getParent().remove(brand);
            }
        }
        this.saveXML();
    }

    //修改xml文件
    public void  saveXML(){
        OutputFormat format = OutputFormat.createPrettyPrint();
        //format.setEncoding("GB2312");
        XMLWriter writer = null;
        try {
            writer = new XMLWriter(new OutputStreamWriter(new FileOutputStream("phone.xml")), format);
            writer.write(document);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            try {
                writer.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    public static void main(String[] args) {
        Dom4jDemo dom4jDemo = new Dom4jDemo();
        dom4jDemo.loadDocument();
        dom4jDemo.addNewPhone();
        dom4jDemo.updatePhone();
        dom4jDemo.deletePhone();
        dom4jDemo.saveXML();
        dom4jDemo.showInfo();
    }
}


上一篇:Java 网络编程
下一篇:初识Mysql