zoukankan      html  css  js  c++  java
  • XML技术详解

    XML

    1.XML概述

    XML可扩展标记语言是一种基于文本的语言用作应用程序之间的通信模式,是一个非常有用的描述结构化信息的技术。XML工具使得转化和处理数据变得十分容易,但同样也要领域相关的标准和代码库才能有效的使用XML,而JAVA则提供了极好的支持和丰富的库来解析、修改以及查询XML文档。

    如果你已经学习过了XML,那么你就会发现,XML的语法和HTML的语法十分类似,两者的不同之处在于:XML的标签并不是预先定义好的,而是可以自定义标签,这也是它被称作可扩展标记语言的原因,应当注意的是,自定义的XML标签应当像JAVA中定义变量那样,见名知意。

    XML可以用于任何技术进行数据的存储和传输。不过,XML同样拥有很明显的缺点,那就是内容比较冗杂。

    下面是一个XML的栗子(表示字体以及字号):

    <configuration>
        <title>
            <font>
                <name>Helvetica</name>
                <size>35</size>
            </font>
        </title>
        <body>
            <font>
                <name>times roman</name>
                <size>16</size>
            </font>
        </body>
    </configuration>

    2.XML文档的结构

    • XML文档拥有一个文档头:
    <?xml version="1.0" encoding="utf-8">

    虽说文档头是可选的,但是最好要将文档头写在XML文档中。

    • 文档头之后是文档类型定义:
    <!DOCTYPE web-app PUBLIC ....>

    文档类型的作用是用来保护文档,但不是必须的。

    • 最后是文档的正文,包含根元素,根元又素包括其他元素
    <title>
            <font>
                <name>Helvetica</name>
                <size>35</size>
            </font>
        </title>
        <body>
            <font>
                <name>times roman</name>
                <size>16</size>
            </font>
        </body>

    元素可以有子元素、文本元素,或者两者皆有。如下:

    <font>
        Helevetia
        <size>35</size>
    </font>

    但最好规避使用两者皆有的情况,这样做的好处是可以简化解析过程,后面我们就会见到这种情况。

    XMl元素还可以包含属性,如:

    <font name="Helevetia" size="36 pt"></font>

    貌似你会觉得这种用法会比下面的用法简单一些:

    <font>
        <name>Helevetia</name>
        <size>36</size>
    </font>

    但是,如果按照第一种做法,解析的时候会增加解析的难度,因为我们要解析的是“36 pt”而不是36。
    为了避免这种麻烦,我们采取下面这样的做法:

    <font>
        <name>Helevetia</name>
        <size unit="pt">36</szie>
    </font>

    这样会简单很多,如果不明白,不用着急,接下来我们可以仔细体会。另外,我们常用的经验是,属性只应该作为值的解释,而不应该作为值。

    3.解析XML文档

    要处理一个XML文档,就要对它进行解析。解析器首先读入一个文件,确认这个文件拥有正确的格式,然后将其分解成各种元素,然后程序就能够访问这些元素了。

    JAVA库中有两种XML解析器:

    • 树形解析器(DOM):将读入的XML文档转换成树形结构
    • 流机制解析器(SAX):读入XML文件时生成对应的事件

    我们首先介绍DOM的使用,因为这种方式能够满足我们大多数的需求:

    1. DOM使用方式
      • 创建一个DocumentBuilder对象
    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    DocumentBuilder builder = factory.newDocumentBuilder();
    • 从文件中读入文档
    File f = ...
    Document doc = builder.prase(f);
    1. 具体方法
      • getDocumentElement:启动对文档内容的分析,返回根元素
    Element root = doc.getDocumentElement;
    • getTagName:返回标签名称
    • getChildNodes:得到元素的子元素,返回NodeList集合
    NodeList children = root.getChildNodes();

    如需遍历所有子元素,会用的上getLength方法获取总项数

    • getFirstChild:获取该节点的第一个子节点
    • getLastChild:获取该节点的最后一个节点

    以上两个方法在没有获取到值的时候返回null

    • getNextSibling:获取该节点的下一个兄弟节点
    • getPreviousSibling:获取该节点的上一个兄弟节点
    • getParentNode:获取父节点
    • getNodeName:返回该节点的名字
    • getNodeValue:返回该节点的值

    3.验证XML文档

    使用DOM方式来操作XML文档时,会有大量的编程和错误检查,不但需要处理文档中的空白字符,还要检查是否与预期的一样。但是,XML能够自动校验某个XML文档是否具有正确的结构。

    我们也可以自己指定文档的结构,可以使用文档类型定义以及XML Schema定义,这就相当于一种规则,指定了每个元素的合法元素和属性。例如下面这个文档类型定义:

    <!ELEMENT font(name,size)>

    这个定义规定了font元素必须有两个子元素。
    值得注意的是,XML Schema能表达更加复杂的验证条件。

    1. 文档类型定义

      • 将定义纳入XML文档
        <?xml version="1.0"?>
        <!DOCTYPE configuration[
            <!ELEMNET configuration...>
        >

      这是一个文档类型定义的写法。

      我们将规则使用[]作为规范的限定,文档类型必须匹配根节点的名称!这里的缺点很明显,一旦规则很多,那么就会使得[]变得十分庞大。

      • 不同类型的规则

        • ELEMENT:指定某个元素可以拥有什么样子的子元素
          <!ELEMENT document (title,(introduce...))>

        当一个元素中存在文本时,只有两种情况是合法的。一种是只包含文本,另一种是包含任意顺序的文本和标签的组合,其他情况均不合法。

      有了文档类型的定义,调用方法来解析XML文件的时候,就不必再考虑如何消除文本的空白字符问题了。

    2. XML Schema

      如果希望在XML中使用Schema,就需要在根元素中添加属性:

      <xsd:element name="font">
          <xsd:sequence>
              <xsd:element name="name" type="xsd:String"/>
              <xsd:element name="size" type="xsd:int">
          </xsd:sequence>
      </xsd:element>

    4.使用XPath定位信息

    我们如果想定位下面这段XMl文件中的size值,使用遍历当然可以,但是非常麻烦,我们可以直接使用XPath表达式来进行定位。

    <font>
        <name>Helevetia</name>
        <size>36</size>
    </font>

    表达式为:/font/size 这样就可以得到size的值了。

    具体内容参考JAVA核心技术卷2.

    5.使用命名空间

    命名空间的主要作用就是避免名字冲突,这种做法在JAVA中十分常见

    <xsd:element name="font">
        <xsd:sequence>
            <xsd:element name="name" type="xsd:String"/>
            <xsd:element name="size" type="xsd:int">
        </xsd:sequence>
    </xsd:element>

    这里的xsd就是一种命名空间。

    6.流机制解析

    流机制解析器主要应用在:文档很大,处理算法简单,可以在运行时解析结点,不必看到完整的解析树。

    1. 使用SAX解析器

    XML是基于事件的解析器,在解析XML文档时不会创建解析树。

    观察第4节中的内容,解析器在解析时会产生下面的调用:

    (1) startElement 元素名:font
    (2) startElement 元素名:name
    (3) characters   内容:Helevetia
    (4) endElement   元素名:name
    (5) startElement 元素名:size
    (6) characters   内容:36
    (7) endElement   元素名:size
    (8) endElement   元素名:font

    2.使用StAX解析器

    StAX是一种“拉解析器”,我们只需要使用最基本的循环就可以迭代出所有的事件

    利用java库中的一些方法就可以实现这些操作,请参阅javaAPI

    7.生成XML文档

    我们可以使用文档内容来构建一棵DOM树,然后写出树中的所有内容。

    1. 不带命名空间的文档

    首先得到一个空白的文档:

    Document doc = builder.newDocment();

    使用Document类的createElement方法构建文档元素:

    Element rootElement = doc.createElement(rootName);

    还可以使用createTextNode创建文本节点:

    Text textNode = doc.createTextNode(text);

    以及其他的一些操作。

    2.带命名空间的文档

    带命名空间文档与没有命名空间文档的生成区别在于:需要将生成器工厂设置成命名空间敏感的,然后再创建生成器。

    生成节点的方法是createElementNS来创建所有的节点

    创建完成后,我们就可以写出文档了。

    本文参考:

        JAVA核心技术卷2:xml
    

    感谢您的阅读,欢迎指正博客中存在的问题,也可以跟我联系,一起进步,一起交流!

    微信公众号:进击的程序狗
    邮箱:roobtyan@outlook.com
    个人博客:https://roobtyan.github.io

  • 相关阅读:
    作业四:结对编程项目---四则运算
    作业三: 代码规范、代码复审、PSP
    自动生成四则运算题目
    源程序版本管理软件和项目管理软件的优缺点
    学习进度表
    第一周随笔
    对之前问题的回答
    结对编程——四则运算
    PSP
    代码复审
  • 原文地址:https://www.cnblogs.com/roobtyan/p/9576737.html
Copyright © 2011-2022 走看看