XML的编写

XML

什么是XML

XML是一个可扩展标记语言。XML和操作系统编程语言的开发平台无关,可以实现不同系统之间的数据交换。

  • XML的规范

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

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

属性值用引号包裹

一个元素可以有多个属性

属性值不可以直接包含< &

不建议使用的字符" ’ >

使用IDEA新建一个XML文件,先尝试编写一个XML文件:

<?xml version="1.0" encoding="UTF-8" ?>
<books>
    <!--图书信息-->
    <book id="b001">
        <title>图书1</title>
        <author>张三</author>
    </book>
    <book id="b002">
        <title>图书2</title>
        <author>李四</author>
    </book>
    <!--可以代表空元素-->
    <book></book>
</books>

同时也可以在IDEA中查看编写XML文档的结构

请添加图片描述
也可以在浏览器中预览编写好的xml文件。

如何编写格式良好的XML

  • XML中的转义符列表
    具体参考XML的转义符列表
    当元素中出现了很多的特殊字符时,可以使用CDATA节,CDATA是不应该由XML解析器解析的文本数据
<![CDATA[输出第一本<book></book>图书信息]]>

XML的编写注意事项:

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

XML标签对大小写敏感

XML必须是正确的嵌套

同级标签以缩进对齐

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

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

元素名称不可以包含空格

<?xml version="1.0" encoding="UTF-8" ?>
<books>
    <!--图书信息-->
    <book id="b001" width="&lt;20">
        输出第一本&lt;book&gt;&lt;/book&gt;图书信息
        <title>图书1</title>
        <author>张三</author>
    </book>
    <book id="b002">
        <![CDATA[输出第一本<book></book>图书信息]]>
        <title>图书2</title>
        <author>李四</author>
    </book>
    <!--可以代表空元素-->
    <book></book>
</books>
<?xml version="1.0" encoding="UTF-8" ?>
<clothSizes>
    <!--衣服尺码和身高对比信息-->
    <size range="height&lt;165">S</size>
    <size range="165&lt;height&lt;170">M</size>
    <size range="170&lt;height&lt;175">L</size>
    <size range="175&lt;height&lt;180">XL</size>
    <size range="180&lt;height&lt;185">XXL</size>
</clothSizes>
<?xml version="1.0" encoding="UTF-8" ?>
<studentScores>
    <student>
        <name>王显明</name>
        <expectedScore>78</expectedScore>
        <score>88</score>
    </student>
    <student name="宋佳" expectedScor="80" score="90"/>
</studentScores>

在一个XML文档或者是多个XML文档中可能会有命名冲突的问题,这是十分常见的,那么怎么解决这种问题呢?

  • XML命名空间的作用

可以解决在复杂 大型的XML文件中,出现名称相同 但是含义不同的元素,还可以在一个文档中定义多个命名空间

<cameras xmlns:canon="http://www.canon" xmlns:nikon="http://www.nikon.com"></cameras>

默认的命名空间

没有指定前缀的命名空间就会作为页面中的元素的默认命名空间

除非在标签中使用其他命名空间的前缀,否则解析器都会认为元素是在默认命名空间下存在

一个文档中只可以有一个默认的命名空间

DOM解析XML技术

  • DOM

基于XML文档树结构的解析
适用于多次访问的XML文档
特点:比较消耗资源

  • DOM4J

非常优秀的java xml API
性能优异 功能强大
开放源代码

  • SAX

基于事件的解析
适用于大数据量的XML文档
特点:占用的资源少,内存消耗小

DOM是文档对象模型,DOM把XML文档映射成一个倒挂的树

  • 常用的接口的介绍
    DOM解析包:org.w3c.dom
    请添加图片描述

  • DOM解析XML文件的步骤

创建解析器工厂对象
解析器工厂对象创建解析器对象
解析器对象指定XML文件创建Document对象
以Document对象为起点操作DOM树

  • 保存XML文件

获得TransformerFactory对象
创建Transformer对象 设置输出属性
创建DOMSource对选哪个 包含XML信息
创建StreamResult对象 包含保存文件的信息
将XML保存在指定文件中

新建一个XML文件是收藏信息.xml

<?xml version="1.0" encoding="UTF-8" ?>
<PhoneInfo>
    <Brand name="华为">
        <Type name="Mate30 Pro"/>
        <Type name="P30 Pro"/>
        <Type name="nova 6"/>
    </Brand>
    <Brand name="苹果">
        <Type name="iPhone11 pro"/>
    </Brand>
</PhoneInfo>

编写java代码解析XML文档

package XML;

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.File;
import java.io.IOException;

//对XML文件的全部解析工作(查看 增加 修改 删除 保存)
public class ParseXMLDemo {
    //全局变量:Document对象
    Document document = null;

    //解析XML文件获取相应的Document对象
    public void getDocument() {
        //解析器工厂(DocumentBuilderFactory)
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        try {
            //解析器(DocumentBuilder)
            DocumentBuilder builder = factory.newDocumentBuilder();
            document = builder.parse("收藏信息.xml");
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        }
    }

    //获取手机品牌和型号
    public void showInfo() {
        //获取手机的品牌
        NodeList brands = document.getElementsByTagName("Brand");
        //循环获取每一个手机品牌节点
        for (int i = 0; i < brands.getLength(); i++) {
            Node node = brands.item(i);
            //把品牌节点转换为品牌元素
            Element eleBrand = (Element) node;
            //获取每一个品牌元素的name属性
            System.out.println(eleBrand.getAttribute("name"));
            //获得每个品牌节点下面的子节点(型号)
            NodeList types = eleBrand.getChildNodes();
            for (int j = 0; j < types.getLength(); j++) {
                //拿出每一个型号节点
                Node typeNode = types.item(j);
                //判断型号节点是否为元素,如果是ELEMENT_NODE,再转换为元素
                if (typeNode.getNodeType() == Node.ELEMENT_NODE) {
                    //型号节点转换为型号元素
                    Element eleType = (Element) typeNode;
                    //获取型号元素的name属性
                    System.out.println("\t" + eleType.getAttribute("name"));
                }
            }
        }
    }

    //添加新的节点
    public void add() {
        //创建新的品牌节点
        Element elementBrand = document.createElement("Brand");
        //为品牌节点创建name属性
        elementBrand.setAttribute("name", "三星");
        //创建新的型号节点
        Element elementType = document.createElement("Type");
        //为型号节点创建name属性
        elementType.setAttribute("name", "Galaxy Fold");
        //把型号节点作为品牌节点的子节点添加进去
        elementBrand.appendChild(elementType);
        //把三星新的品牌节点(带有子节点型号的)加到元素PhoneInfo中去
        document.getElementsByTagName("phoneInfo").item(0).appendChild(elementBrand);
        //保存XML
        this.saveXML("new.xml");
    }

    //保存XML文件-->path:目的地
    public void saveXML(String path) {
        //转换器工厂
        TransformerFactory factory = TransformerFactory.newInstance();
        //转换器
        try {
            Transformer transformer = factory.newTransformer();
            //设置输出格式(编码 缩进)
            //transformer.setOutputProperty(OutputKeys.ENCODING,"gb2312");
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
            //源
            DOMSource source = new DOMSource(document);
            //目的
            StreamResult result = new StreamResult(new File(path));
            //完成XML文件保存
            transformer.transform(source, result);
        } catch (TransformerConfigurationException e) {
            e.printStackTrace();
        } catch (TransformerException e) {
            e.printStackTrace();
        }
    }

    //实现XML节点的修改,Brand标签添加一个id属性
    public void update() {
        //获取所有的Brand元素
        NodeList brands = document.getElementsByTagName("Brand");
        for (int i = 0; i < brands.getLength(); i++) {
            Node brand = brands.item(i);
            Element eleBrand = (Element) brand;
            //为每一个Brand元素设置id属性
            eleBrand.setAttribute("id", i + "");
        }
        //保存XML
        this.saveXML("new.xml");
    }

    //实现XML节点的删除 删除所有Brand为华为的节点
    public void delete() {
        //获取所有的Brand节点
        NodeList brands = document.getElementsByTagName("Brand");
        //遍历所有的Brand节点 找出华为
        for (int i = 0; i < brands.getLength(); i++) {
            Node brand = brands.item(i);
            Element eleBrand = (Element) brand;
            if (eleBrand.getAttribute("name").equals("华为")) {
                eleBrand.getParentNode().removeChild(eleBrand);
            }
        }
        //保存XML
        this.saveXML("new.xml");
    }

    public static void main(String[] args) {
        ParseXMLDemo parseXMLDemo = new ParseXMLDemo();
        parseXMLDemo.getDocument();
//        parseXMLDemo.add();
//        parseXMLDemo.update();
        parseXMLDemo.delete();
        parseXMLDemo.showInfo();
    }
}

JSON

JSON是一种轻量级的文本数据交换格式,具有自我描述性,比XML传输速度快
JSON最初用来表示javascript中的对象,但目前已经独立于javascript,成为最常用的数据格式之一。

JSON的语法格式
  • 两种数据结构:对象和数组

大括号内为对象
中括号中是数组

  • 对象中的数据由名称/值对构成

值得类型可以是字符串 数字 布尔值 null 数组 对象
数据之间由逗号分割开来

  • 数据中的数据类型同名称/值对中值的类型
{
	"name":"jason",
	"age":20,
	"skill":["java","python"]
}

使用fastjson解析JSON

package Kind;

import java.util.List;

public class Student {
    private String name;
    private int age;
    private List<String> skills;

    public Student() {
    }

    public Student(String name, int age, List<String> skills) {
        super();
        this.name = name;
        this.age = age;
        this.skills = skills;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", skills=" + skills +
                '}';
    }

    public List<String> getSkills() {
        return skills;
    }

    public void setSkills(List<String> skills) {
        this.skills = skills;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
package Test;

import Kind.Student;
import com.alibaba.fastjson.JSON;

import java.util.ArrayList;
import java.util.List;

//完成学员对象和JSON字符串的互相转换
public class FastJSONDemo {
    public static void main(String[] args) {
        //对象转换为JSON字符串
        List<String> skills = new ArrayList<>();
        skills.add("java");
        skills.add("python");
        skills.add("linux");
        Student student = new Student("Jason", 20, skills);
        String stuJSON = JSON.toJSON(student).toString();
        System.out.println(stuJSON);
        //JSON字符串转换为对象
        String json = "{\"skills\":[\"java\",\"python\",\"linux\"],\"name\":\"Jason\",\"age\":20}\n";
        Student stu = JSON.parseObject(json, Student.class);
        System.out.println("转换为学生对象:" + stu.getName() + "-" + stu.getAge() + "-" + stu.getSkills());
    }
}

DOM4J解析XML文件

DOM4J有一些接口比较常用:

Document接口:定义XML文档
Element接口,定义XML元素
Text接口,定义XML文本节点
Attribute接口:定义了XML属性

DOM4J解析收藏信息.xml文件

package XML;

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.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Iterator;

//借助DOM4J的方式来解析收藏信息.xml
public class DOM4JXML {
    //全局的Document
    Document document = null;

    //获取Document对象,为全局的Document赋值
    public void getDocument() {
        //通过解析器解析XML文件,获取Document
        SAXReader saxReader = new SAXReader();
        try {
            document = saxReader.read(new File("E:\\file\\code\\java\\javacode\\src\\XML\\收藏信息"));
        } catch (DocumentException e) {
            e.printStackTrace();
        }
    }

    public void showPhoneInfo() {
        //获取根节点
        Element root = document.getRootElement();
        //获取根节点下面的子节点,进行遍历
        for (Iterator itBrand = root.elementIterator(); itBrand.hasNext(); ) {
            Element brand = (Element) itBrand.next();//遍历迭代器中的每一个Brand节点
            //显示品牌:brand的name属性
            System.out.println("手机品牌:" + brand.attributeValue("name"));
            //获取品牌下的手机型号
            for (Iterator itType = root.elementIterator(); itType.hasNext(); ) {
                Element type = (Element) itType.next();//遍历迭代器中的每一个Type节点
                System.out.println("\t型号:" + type.attributeValue("name"));
            }
        }
    }

    //添加新的手机收藏信息(品牌和型号)
    public void add() {
        //获取XML的根节点
        Element root = document.getRootElement();
        //为根节点添加一个Brand元素,name赋值为三星
        Element brand = root.addElement("Brand");
        brand.addAttribute("name", "三星");
        //为brand元素添加Type元素 Type元素name属性赋值为Glaxy Fold
        Element type = brand.addElement("Type");
        type.addAttribute("name", "Glaxy Fold");
        //保存XML
        this.saveXML("new.xml");
    }

    public void saveXML(String path) {
        //创建一个XMLWriter对象,相当于DOM解析中的转换器
        try {
            //输出保存时的格式
            OutputFormat format = OutputFormat.createPrettyPrint();
            //format.setEncoding("GBK");
            XMLWriter writer = new XMLWriter(new FileWriter(path), format);
            writer.write(document);
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //修改手机收藏信息,为Brand元素设置ID属性
    public void update() {
        //获取XML的根元素
        Element root = document.getRootElement();
        //获取根元素下面的所有Brand子元素 遍历
        int id = 0;
        for (Iterator itBrands = root.elementIterator(); itBrands.hasNext(); ) {
            Element brand = (Element) itBrands.next();
            //为Brand元素设置ID属性
            id++;
            brand.addAttribute("id", id + "");
        }
        //保存XML文件
        this.saveXML("new.xml");
    }

    public void delete() {
        //获取XML的根元素
        Element root = document.getRootElement();
        //获取所有的Brand子元素 遍历
        for (Iterator itBrands = root.elementIterator(); itBrands.hasNext(); ) {
            Element brand = (Element) itBrands.next();
            //判断Brand的name属性是否是华为 如果是 则删除
            if (brand.attributeValue("name").equals("华为")) {
                //由父节点进行删除
                brand.getParent().remove(brand);
            }
        }
        //保存XML文档
        this.saveXML("new.xml");
    }

    //显示手机收藏信息
    public static void main(String[] args) {
        DOM4JXML dom4JXML = new DOM4JXML();
        dom4JXML.getDocument();
        dom4JXML.add();
        dom4JXML.update();
        dom4JXML.delete();
        dom4JXML.showPhoneInfo();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_45671732

你们鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值