XML 基础详解

1.为什么使用XML
(1) 文件
     XML是一项与数据描述和组织有关的技术,因此在学习XML的基本概念之前,我们需要先了解计算机如何存取数据。为此我们把计算机中的数据文件分成两大类:二进制文件和文本文件 。
(2) 二进制文件
     二进制文件是由程序根据自己的编码规则创建的,只有创建这个文件的程序才知道如何解析该文件,所以二进制文件有其应用的限制。
     比如:我们的doc文件就是word根据自身的编码生成的二进制文件。word的软件设计人员设计了不同内容对应的不同编码,当我么能使用word打开doc文档时,word程序会将二进制编码转换为字符,供我们阅读。
      优点 :计算机容易理解、处理速度快、存储效率高。
               可以存储不同类型的数据。
      缺点 :每一类二进制文件都有自己特有的格式,不能跨程序、跨平台使用。
(3) 文本文件
     文本文件实际上也是一个二进制文件,不同的是,文本文件是根据标准的格式组织起来的。 这些标准格式我们习惯称他们为字符集。 常见的字符集 : ASCII、GB2312、ISO-8859-1、UTF-8 。
     由于标准的字符集存在,所以人们可以借助一个文本编辑器就可以轻松的阅读文本文件, 比起二进制文件文本文件更容易分享。
     优点 : 易于使用,可以通过不同程序打开。
     缺点 : 只能保存纯文本,不能保存其他信息。
(4) 标记语言简史:
     文本文件有易用性的特点,但只能存储纯文本,而二进制文件虽然可以存储不同的内容但是通用性较差,如果可以结合二者的优点,岂不快哉?
     为达到上述目的,我们想到的方案是为文本文件中不同的内容都加上一个特殊的标记,这样程序就可以根据不同的标记来识别文档中的内容。 这种思想很早就出现了,根据这种思想最早提出的语言是标准通用标准语言(SGML),但是SGML本身比较复杂,并没有得到很好的推广。
     在SGML的基础上出现HTML,HTML吸收了很多SGML的概念,它使用html标签来标识网页中的不同部分,这样浏览器就可以通过HTML来显示一个个的WEB页面。
     SGML过于复杂,而HTML仅能用来描述网页。不能描述数据,于是XML诞生了。

2.XML简介
(1) 什么是 XML?
     XML 指可扩展标记语言(EXtensible Markup Language) 。
     XML 是一种标记语言,很类似 HTML 。
     XML 的设计宗旨是传输数据,而非显示数据 。
     XML 标签没有被预定义。您需要自行定义标签。
     XML 被设计为具有自我描述性。
     XML 是 W3C 的推荐标准 。
     XML 仅仅是纯文本 : 有能力处理纯文本的软件都可以处理 XML。
(2) XML 与 HTML 的主要差异
     XML 不是 HTML 的替代。
     XML 和 HTML 为不同的目的而设计。
     XML 被设计为传输和存储数据,其焦点是数据的内容。
     HTML 被设计用来显示数据,其焦点是数据的外观。
     HTML 旨在显示信息,而 XML 旨在传输信息。
(3) XML的用途
     框架的配置文件 :Sping ;Hibernate。
     传输数据 :Ajax ;WebService。
     数据的持久化 。
(4) XML的HelloWorld(stu.xml):
<?xml version="1.0" encoding="UTF-8"?>
<students>
  <student id="1">
    <name>孙悟空</name> 
    <age>18</age> 
    <gender>男</gender> 
    <address>花果山</address>
  </student> 
  <student id="2">
    <name>猪八戒</name> 
    <age>28</age> 
    <gender>男</gender> 
    <address>高老庄</address>
  </student> 
  <student id="3">
    <name>沙和尚</name> 
    <age>38</age> 
    <gender>男</gender> 
    <address>流沙河</address>
  </student> 
  <student id="4">
    <name>唐僧</name> 
    <age>16</age> 
    <gender>男</gender> 
    <address>女儿国</address>
  </student> 
</students>
(5) 语法规范
     ① XML文档的第一行是一个xml声明,用来声明xml的版本和字符集
     ②XML文档中有且只有一个根元素
     ③ XML中的标签必须结构完整(成对出现或者是自结束标签)
     ④ XML中的标签不能交叉嵌套
     ⑤ XML中的属性必须有值,且值必须加引号
     ⑥ XML中严格区分大小写
     ⑦ XML的标签名不能以数字开头
(6) XML解析
     XML解析是指通过解析器读取XML文档,解释语法,并将文档转化成对象。
     对XML的一切操作都是由解析开始的,所以解析非常重要。
     Java 平台同时提供了 DOM(Document Object Model)和 SAX(Simple API for XML)。
(7) 技术体系

(8) DOM解析和SAX解析对比:


3.DOM解析
     Document Object Model(文档对象模型): 一次性将整个XML文档全都加载进内存中,生成一棵DOM树, 我们通过对DOM树的操作来解析文档。
(1) 优点:
     DOM解析是一种完全面向对象的解析方式,使用起来比较简单
     DOM解析一次性将整个文档都加载进内存中,可以反复操作文档, 同时它可以对文档进行增删改查的操作。
(2) 缺点:
     一次性将文档都加载进内存中,会占用大量的内存,解析起来性能较差。
(3)  原生DOM解析
     核心类: DocumentBuilderFactory; DocumentBuilder; Document
     主要步骤:
//1.获取工厂类类实例
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//2.获取解析器类实例
DocumentBuilder builder = factory.newDocumentBuilder();
//3.解析xml文档获取document对象
Document document = builder.parse("stu.xml");
(4) 代码示例:
public class TestDOM {
    @Test
    public void testDOM() throws Exception{
        //获取工厂类实例
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        //获取解析器类实例
        DocumentBuilder builder = factory.newDocumentBuilder();
        //解析xml文档获取document对象
        Document document = builder.parse("stu.xml");
        //xml文件中所有的标签和属性都是自定义的
        //id属性在xml中没有任何意义,所以getElementById暂时不能用
        //Element ele = document.getElementById("1");
        //System.out.println(ele);
        //获取全部的student元素
        NodeList stuEles = document.getElementsByTagName("student");
        //遍历stuEles
        for(int i=0 ; i<stuEles.getLength() ; i++){
            //获取student元素
            Element stuEle = (Element) stuEles.item(i);
            //获取学生的id属性值
            String idStr = stuEle.getAttribute("id");
            //获取学生name
            Element nameEle = (Element) stuEle.getElementsByTagName("name").item(0);
            String name = nameEle.getTextContent();
            //获取age gender address
            String ageStr = stuEle.getElementsByTagName("age").item(0).getTextContent();
            String gender = stuEle.getElementsByTagName("gender").item(0).getTextContent();
            String address = stuEle.getElementsByTagName("address").item(0).getTextContent();
            System.out.println(idStr+"--"+name+"--"+ageStr+"--"+gender+"--"+address);
        }
    }
}
4.DOM4J 解析
     使用dom4j必须要导入一个jar包: dom4j-1.6.1.jar
     dom4j是一个开源XML解析包。
     dom4j是一个易用的、开源的库,用于XML,XPath和XSLT。
     dom4j内部支持SAX解析,所以性能比原生的DOM要高。
     dom4j是基于dom的第三方开源的xml解析jar包。
     它应用于Java平台,采用了Java集合框架并完全支持DOM,SAX和JAXP。
(1) dom4j 解析
//创建一个解析器对象
SAXReader reader = new SAXReader();
//解析xml文档来获取document对象
Document document = reader.read("stu.xml");
//DOM4J操作都是通过根元素来进行的,所以我们需要先获取到根元素
Element rootEle = document.getRootElement();

> 常用的方法:
Element getRootElement() 获取根元素
List<Element> elements(String tagName) 根据标签名获取一组元素节点
Element element(String tagName) 根据标签名获取一个元素节点
String attributeValue(String name) 根据属性名获取属性值
String elementText(String tagName) 获取指定的标签中的文本内容
String getText() 获取元素中的文本内容
(2) dom4j 修改
//创建一个漂亮的输出格式
OutputFormat format = OutputFormat.createPrettyPrint();
//创建一个XMLWriter
XMLWriter writer = new XMLWriter(new FileWriter("stu2.xml"),format);
//将document对象写入到文件中
writer.write(document);
//关闭流
writer.close();

> 常用的方法:
Element addElement(Stirng tagName); 向父元素中添加指定的子元素,并返回子元素
Element addAttribute(String name :String value) 向元素中添加属性,并返回当前元素
Element addText(String data) :向元素中添加文本内容,并返回当前元素
DocumentHelper.createDocument():创建一个新的Document
(3) xPath
     xPath用来在xml文档中快速查询元素,也就是说快速获取XML文件中的内容;
     dom4j支持xPath,使用xPath时需要导入一个新的jar包:jaxen-1.1-beta-6.jar
     xPath的具体语法需要对照文档使用。
(4) 代码示例:
public class TestDOM4J {

    //xPath用来在xml文档中快速查询元素
    @Test
    public void testXpath() throws Exception{
        //获取解析器类实例
        SAXReader reader = new SAXReader();
        //解析xml文档获取Document对象
        Document document = reader.read("stu.xml");
        //查询文档中id为3的学生信息
        // /students/student[@id='3']
        //selectNodes()可以根据一个xPath表达式查询一组节点
        //selectSingleNode()根据一个xPath查询一个节点对象
        Element stuEle = (Element) document.selectSingleNode("/students/student[@id='2']");
        //获取学生的信息
        String idStr = stuEle.attributeValue("id");
        String name = stuEle.elementText("name");
        System.out.println(idStr+"--"+name);
    }

    // 修改XML文件(创建新的XML文档)
    @Test
    public void testDOM4J3() throws Exception{
        //创建一个新的Document对象
        Document document = DocumentHelper.createDocument();
        //向Document中添加一个根元素
        Element rootEle = document.addElement("teachers");
        //向根元素中添加子元素
        rootEle.addElement("teacher").addText("罗老师");
        rootEle.addElement("teacher").addText("张老师");
        //创建一个XMLWriter
        XMLWriter writer = new XMLWriter(new FileWriter("teach.xml"), OutputFormat.createPrettyPrint());
        //将Document输出到文档中
        writer.write(document);
        //关闭流
        writer.close();
    }

    // 修改XML文件(已有XML文档)
    @Test
    public void testDOM4J2() throws Exception{
        //获取解析器类实例
        SAXReader reader = new SAXReader();
        //解析xml文档获取document对象
        Document document = reader.read("stu.xml");
        //获取根元素
        Element rootEle = document.getRootElement();
        //向根元素中添加一个student元素
        Element stuEle = rootEle.addElement("student");
        //向stuEle中添加一个id属性
        stuEle.addAttribute("id", "5");
        //向stuEle中添加一个name子元素
        Element nameEle = stuEle.addElement("name");
        //向name中添加一个文本
        nameEle.addText("白骨精");
        //添加age gender address
        stuEle.addElement("age").addText("18");
        stuEle.addElement("gender").addText("女");
        stuEle.addElement("address").addText("白骨洞");
        //创建一个漂亮的输出格式
        OutputFormat format = OutputFormat.createPrettyPrint();
        //创建一个XMLWriter
        XMLWriter writer = new XMLWriter(new FileWriter("stu2.xml"),format);
        //将document对象写入到文件中
        writer.write(document);
        //关闭流
        writer.close();
    }

    //解析XML文件
    @Test
    public void testDOM4J() throws Exception {
        //创建一个解析器对象
        SAXReader reader = new SAXReader();
        //解析xml文档来获取document对象
        Document document = reader.read("stu.xml");
        //DOM4J操作都是通过根元素来进行的,所以我们需要先获取到根元素
        Element rootEle = document.getRootElement();
        //获取所有的student元素
        List<Element> stuEles = rootEle.elements("student");
        //遍历stuEles
        for (Element stuEle : stuEles) {
            //获取id属性值
            //attributeValue()作用,可以根据属性名获取属性值
            String idStr = stuEle.attributeValue("id");
            //获取name值
            Element nameEle = stuEle.element("name");
            String name = nameEle.getText();
            //获取age gender address
            String ageStr = stuEle.element("age").getText();
            //elementText()可以根据标签名,获取标签中间的内容
            String gender = stuEle.elementText("gender");
            String address = stuEle.elementText("address");
            //将属性封装到student对象中
            Student stu = new Student(Integer.parseInt(idStr), name, Integer.parseInt(ageStr), gender, address);
            System.out.println(stu);
        }
    }
}
5.SAX  解析
     Simple API for XML: 基于事件回调的机制,一个一个节点的解析,解析完一个在解析下一个。
(1) 优点:
     一个节点一个节点的解析,不会占用过多的内存,解析性能好。
(2) 缺点:
      基于事件回调的机制,操作起来略复杂。
      只能对文档进行查询的操作。
      sax解析一旦开始就不能手动停止,必须等到整个文档解析结束。
(3) SAX  解析
     核心类: SAXParserFactory; SAXParser; DefaultHandler
//获取工厂类实例
SAXParserFactory factory = SAXParserFactory.newInstance();
//获取解析器类实例
SAXParser parser = factory.newSAXParser();
//解析xml文档
parser.parse("stu.xml", new MyHandler2());
- SAX解析的一切操作都是通过处理器类进行的,一般我们需要去自定一个一个处理器类,这个类需要去继承DefaultHandler。
6.PULL 解析
     为了解决SAX解析一旦开始就不能手动停止的问题,出现了PULL解析,PULL解析时Android内置的解析方式。
     核心类:XmlPullParserFactory;XmlPullParser
//获取工厂类实例
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
//获取解析器类实例
XmlPullParser parser = factory.newPullParser();
//将被解析的文件设置进解析器
parser.setInput(new FileReader("stu.xml"));

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

程序员学习圈

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

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

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

打赏作者

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

抵扣说明:

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

余额充值