zoukankan      html  css  js  c++  java
  • JAVA基础XML的解析


    一、XML的概述

       XML的全名为可扩展标记语言(Extensible Markup Language),XML的作用为:1、传输,2、存取数据,3、软
    件的配置文件。传输现在都用更轻量的Json,而存储则用数据库。所以软件的配置文件是现在的XML的主要用途。
    现在的一些主流框架都是使用XML进项配置的。

    (一)XML的基本语法

      1、XML的文档声明:通常出现在XML的第一行第一列的位置!
      写法:
        <?xml 属性名=”属性值” 属性名=”属性值” ...?>
        * version :必须的. 使用”1.0”
        * encoding :字符集. 是使用浏览器打开的时候采用的默认的字符集的编码.
        * standalone :描述XML文档是否需要依赖其他的文件.
      举例:<?xml version="1.0" encoding="UTF-8"?>
      2、XML的注释
      写法:
        <!-- XML的注释 -->
      3、XML的元素:xml中的元素其实就是一个个的标签 - a: 包含标签体(<>成对儿出现),b: 不包含标签体
    (<元素名 属性/>)
      举例:

      a: 

    1 <student>
    2    <name>zhangsan</name>
    3    <age>18</age>
    4 </student>

      b:

    1  <student
    2     name="zhangsan"
    3     age="18"
    4 />

      元素的命名规范:
        * 严格区分大小写;<a><A>
        * 只能以字母或下划线开头;abc _abc
        * 不能以xml(或XML、Xml等)开头;
        * 名称字符之间不能有空格或制表符;
        * 名称字符之间不能使用冒号;
      4、XML元素中的属性:一个元素可以有多个属性,每个属性都有它自己的名称和取值。
      写法:
        * 属性值一定要用引号(单引号或双引号)引起来。
        * 属性名称的命名规范与元素的命名规范相同
        * 元素中的属性是不允许重复的
      5、XML的特殊字符和CDATA区
      特殊字符:

      CDATA区的写法:
        <![CDATA[ 内容 ]]>

    二、XML的约束

      在XML中都是用户自定义的标签,若出现小小的错误,软件程序将不能正确地获取文件中的内容而报错。
    (如:Tomcat),所以就可以编写一个文档来约束一个XML的书写规范,这个文档称之为约束。XML的约束就是
    用来约束XML的文档中可以出现哪些标签,不能出现哪些标签,标签中是否有顺序,出现的次数。XML的约束
    包括2种:1、DTD,2、Schema。
      两者的区别:
        * 语法的不同,DTD的语法自成一体而Schema的语法则和XML类似。
        * Schema具有命名空间
        * Schema具有更强强的语义和约束
        * Schema能够更好地被解析器解析

    (一)DTD约束

      1、DTD中定义元素:在DTD文档中使用ELEMENT关键字来声明一个XML元素。
      语法:
        <!ELEMENT 元素名称 使用规则>
      元素的一些约束规则:
        * (#PCDATA):指示元素的主体内容只能是普通的文本.(Parsed Character Data)
        * EMPTY:用于指示元素的主体为空。比如<br/>
        * ANY:用于指示元素的主体内容为任意类型。
        * (子元素):指示元素中包含的子元素
        * 如果子元素用逗号分开,说明必须按照声明顺序去编写XML文档
        * 如果子元素用"|"分开,说明任选其一。
        * 用+(至少一次)、
            *(可有可无,零次、一次或多次)、
           ?(可以有也可以无,有的话只能有一次。零次或一次)来表示元素出现的次数
      2、DTD中定义属性:在DTD文档中使用ATTLIST关键字来为一个元素声明属性。
      写法:
        <!ATTLIST 元素名
        属性名1 属性值类型 设置说明
        属性名2 属性值类型 设置说明
        ......
        >
      属性的类型和约束:
        * CDATA:表示属性的取值为普通的文本字符串
        * ENUMERATED (DTD没有此关键字):表示枚举,只能从枚举列表中任选其一
        * ID:表示属性的取值不能重复
        * #REQUIRED:表示该属性必须出现
        * #IMPLIED:表示该属性可有可无
        * #FIXED:表示属性的取值为一个固定值。语法:#FIXED "固定值"
      例子:

    1 <?xml version="1.0" encoding="UTF-8"?>
    2 <!--根元素有且只能有一个 -->
    3 <!ELEMENT 例子 (数+)>
    4 <!ELEMENT 数 (1,2,3,4)>
    5 <!ELEMENT 1 (#PCDATA)>
    6 <!ELEMENT 2 (#PCDATA)>
    7 <!ELEMENT 3 (#PCDATA)>
    8 <!ELEMENT 4 (#PCDATA)>

      3、DTD的引用方式
      * 内部引用DTD:
        <!DOCTYPE persons [

        ]>
      * 外部引用DTD:
      * 本地DTD:
        <!DOCTYPE persons SYSTEM "***.dtd">
      * 网络DTD:
        <!DOCTYPE persons PUBLIC "url" "***.dtd">

    (二)Schema约束

       一个XML Schema文档通常称之为模式文档(约束文档),遵循这个文档书写的xml文件称之为实例文档。
    Schema约束自身就是一个XML文件,但它的扩展名通常为.xsd。Schema支持名称空间。名称空间:可以理
    解为JAVA里的package,约束文档:可以理解为一个JAVABean类,实例文档:就是通过JAVABean类创建的实
    例对象。
      可以通过命名空间来分辨出约束文档(W3C的命名空间:xmlns="http://www.w3.org/2001/XMLSchema")
    ,实例文档(W3C的命名空间:xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance")W3C的命名空间
    后缀名为instance的为实力文档。
      举例:
      *Schema文件

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.xmldemo.com"
     3 elementFormDefault="qualified">
     4 <element name="persons">
     5 <!-- 复杂元素 -->
     6 <complexType>
     7 <!-- 有序的,最大值不限定,最小值为一 -->
     8 <sequence maxOccurs="unbounded" minOccurs="1">
     9 <element name="person">
    10 <complexType>
    11 <sequence>
    12 <!-- 简单表签 -->
    13 <element name="name" type="string"></element>
    14 <element name="age" type="int"></element>
    15 <element name="sex" type="string"></element>
    16 </sequence>
    17 <!-- 属性,在有序和复杂元素之间 -->
    18 <attribute name="id" type="int" />
    19 </complexType>
    20 </element>
    21 </sequence>
    22 </complexType>
    23 </element>
    24 </schema>

      *实例文档

    1 <?xml version="1.0" encoding="UTF-8"?>
    2 <p:persons xmlns:p="http://www.xmldemo.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    3 xsi:schemaLocation="http://www.xmldemo.com schame.xsd ">
    4 <p:person>
    5 <p:name>p:name</p:name>
    6 <p:age>0</p:age>
    7 <p:sex>p:sex</p:sex>
    8 </p:person>
    9 </p:persons>

      写的好约束文件可以使用eclipse自动引入:
    1、

    2、

    三、XML的解析

      XML的解析一共有2种方式:DOM解析:(DOM:Document Object Model)SAX解析:(Simple Api for XML)
        * DOM:文档对象模型。这种方式是W3C推荐的处理XML的一种方式。
        * SAX:这种方式不是官方标准,属于开源社区XML-DEV,几乎所有的XML解析器都支持它。
      两者的解析方式的优缺点
        * DOM解析是一次把DOM树都加载到内存里进行解析,可以对其进行增删改,但是当解析的XML比较大的
    时候可能会造成内存溢出。
        * SAX解析是以事件驱动的方式一行一行进行解析的,不会造成内存的溢出,但是不能对XML进行修改。
      针对这两种解析的方式,不同的公司提供了不同的API的实现
        * JAXP :SUN公司提供的一套XML的解析的API.
        * JDOM :开源组织提供了一套XML的解析的API-jdom.
        * DOM4J :开源组织提供了一套XML的解析的API-dom4j.
        * pull :主要应用在Android手机端解析XML.
      java中常用的API为DOM4J。

    (一)DOM4J

       DOM4J的常用的构造和方法:
        * 创建SAXReader对象:new SAXReader()
        * 设置读取路径返回Document对象对XML进行操作:
          reader.read(要读取XML的路径);
        * 创建OutputFormat对象设定输出格式: OutputFormat.createPrettyPrint()
        * 根据输出路径和输出格式创建输出对象:
          new XMLWriter(new FileOutputStream(输出路径, 输出格式);
      DOM4J的常用方法:
        * 获取根元素对象(根标签):
          返回值类型 - Element,调用对象 - Document getRootElement();
        * 获取所有的子元素:
          返回值类型 - List ,调用对象 - Element elements();
        * 根据指定的元素名称来获取相应的所有的子元素:
          返回值类型 - List ,调用对象 - Element elements(String name);
        * 根据指定的子元素名称,来获取子元素中的文本:
          返回值类型 - String ,调用对象 - Element elementText(String name);
        * 获取当前元素对象的文本:
          返回值类型 - String ,调用对象 - Element getText();
        * 设置当前元素对象的文本:
          返回值类型 - void ,调用对象 - Element setText(String text);
        * 添加当前元素对象的文本:
          返回值类型 - Element ,调用对象 - Element addText(String text);
        * 根据指定的属性名称获取其对应的值:
          返回值类型 - String ,调用对象 - Element attributeValue(String name);
        * 根据指定的属性名称和值进行添加或者修改:
          返回值类型 - Element ,调用对象 - Element addAttribute(String name,String value);
        * 删除某一元素(需父类对象删除子元素):
          返回值类型 - void ,调用对象 - Element remove(Element element);
        * 在目标节点中添加新的节点:
          返回值类型 - Element ,调用对象 - Element addElement(String name);
        * 创建一个新的元素对象:
          返回值类型 - Element,调用对象 - DocumentHelper DocumentHelper.createElement(String name);

    (二)示例代码

      * 目标XML文件:

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 
     3 <State Code="37" Name="河南" description="郑州" GDP="99999亿" YY="你YY个啥劲儿">
     4 <City>
     5 <Name>郑州</Name>
     6 <Region>高薪区</Region>
     7 </City>
     8 <City>普吉岛</City>
     9 <City>三门峡</City>
    10 <City>安阳</City>
    11 <City>南阳</City>
    12 <City>北京</City>
    13 </State>

      * 工具类:

     1 public class Dom4jUtils {
     2 //私有构造
     3 private Dom4jUtils() {
     4 super();
     5 // TODO Auto-generated constructor stub
     6 }
     7 //创建Document对象
     8 public static Document creatDocument() throws Exception {
     9 SAXReader reader = new SAXReader();
    10 Document document = reader.read("src\\com\\xmldemo\\city.xml");
    11 return document;
    12 }
    13 //创建输出对象
    14 public static void write(Document d) throws Exception {
    15 OutputFormat format = OutputFormat.createPrettyPrint();
    16 XMLWriter writer = new XMLWriter(new FileOutputStream("src\\com\\xmldemo\\city.xml"), format);
    17 writer.write(d);
    18 }
    19 }

      * 一顿操作:

      1 /**添加或修改属性,如果没有该属性就添加有的话就更新
      2 * @throws Exception
      3 */
      4 private static void method07() throws Exception {
      5 Document document = Dom4jTUtils.creatDocument();
      6 Element rootElement = document.getRootElement();
      7 //为根元素添加YY属性和值
      8 Element element = rootElement.addAttribute("YY", "你YY个啥劲儿");
      9 Dom4jTUtils.write(document);
     10 }
     11 
     12 /**打印某一节点的属性
     13 * @throws Exception
     14 */
     15 private static void method06() throws Exception {
     16 Document document = Dom4jTUtils.creatDocument();
     17 Element rootElement = document.getRootElement();
     18 //获取Name属性的值
     19 String value = rootElement.attributeValue("Name");
     20 System.out.println(value);
     21 }
     22 
     23 /**在某一标签位置添加新标签
     24 * @throws Exception
     25 */
     26 private static void method05() throws Exception {
     27 Document document = Dom4jTUtils.creatDocument();
     28 Element rootElement = document.getRootElement();
     29 // 创建一个新元素对象
     30 Element createElement = DocumentHelper.createElement("City");
     31 //为此元素设置值
     32 createElement.setText("普吉岛");
     33 //遍历
     34 List<Element> list = rootElement.elements();
     35 //将此节点加入到list集合的指定位置
     36 list.add(1, createElement);
     37 //写回
     38 Dom4jTUtils.write(document);
     39 }
     40 
     41 
     42 /**像某已指定元素添加元素
     43 * @throws Exception
     44 */
     45 private static void method04() throws Exception {
     46 Document document = Dom4jTUtils.creatDocument();
     47 Element rootElement = document.getRootElement();
     48 //在Root节点下添加一个新节点"City"
     49 Element addElement = rootElement.addElement("City");
     50 //为节点添加文本
     51 addElement.addText("北京");
     52 //写回
     53 Dom4jTUtils.write(document);
     54 }
     55 
     56 
     57 /**删除某一元素
     58 * @throws Exception
     59 */
     60 private static void methed03() throws Exception {
     61 Document document = Dom4jTUtils.creatDocument();
     62 Element rootElement = document.getRootElement();
     63 List<Element> list = rootElement.elements();
     64 //获取要删除元素的父元素(删除只能由父亲删除儿子)
     65 Element parent = list.get(2).getParent();
     66 //删除
     67 parent.remove(list.get(2));
     68 //将document写回
     69 Dom4jTUtils.write(document);
     70 }
     71 
     72 /**修改某一标签的文本
     73 * @throws Exception(为了方便抛出大的异常)
     74 */
     75 private static void medom02() throws Exception {
     76 Document document = Dom4jTUtils.creatDocument();
     77 Element rootElement = document.getRootElement();
     78 List<Element> list = rootElement.elements();
     79 //设置第三个元素的文本
     80 list.get(2).setText("青青草原");
     81 //使用工具类将document写回XML文档
     82 Dom4jTUtils.write(document);
     83 }
     84 
     85 /**获取第一个元素的Name属性
     86 * @throws Exception(为了方便抛出大的异常)
     87 */
     88 private static void method() throws Exception {
     89 //使用工具类创建Document对象
     90 Document document = Dom4jTUtils.creatDocument();
     91 //获得根节点
     92 Element element = document.getRootElement();
     93 //获得根节点下的所有元素节点
     94 List<Element> elements = element.elements();
     95 //获取第一个节点的Name属性文本
     96 String name = elements.get(0).elementText("Name");
     97 System.out.println(name);
     98 }
     99 
    100 
    101 /**用递归的方式遍历所有元素
    102 * @param elements 根节点
    103 */
    104 public static void run(Element elements) {
    105 //打印每个元素的名字
    106 System.out.println(elements.getName());
    107 //获取每个节点
    108 List<Element> elements2 = elements.elements();
    109 //递归调用
    110 for (Element object : elements2) {
    111 run(object);
    112 }
    113 }
    我们在键盘上留下的余温,也将随时代传递到更远的将来~
  • 相关阅读:
    linux 复 带进度条
    frp配置
    zookeeper_service 出错 java.lang.NoClassDefFoundError: org/I0Itec/zkclient/exception/ZkNoNodeException
    zookeeper_service 出错 ........... are only available on JDK 1.5 and higher
    推荐eclipse插件Properties Editor
    使用ab对nginx进行压力测试
    Linux搭建Snmp服务
    第一个python程序
    如何执行Python代码
    pycharm 的调试模式 MAC版
  • 原文地址:https://www.cnblogs.com/0813lichenyu/p/7743135.html
Copyright © 2011-2022 走看看