一篇习得XML

Posted thinmoon

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一篇习得XML相关的知识,希望对你有一定的参考价值。

一、什么是XML

  • XML 指可扩展标记语言(EXtensible Markup Language)
  • XML 是一种标记语言,很类似 html
  • XML 的设计宗旨是传输数据,而非显示数据
  • XML 标签没有被预定义。您需要自行定义标签
  • XML 被设计为具有自我描述性。
  • XML 是 W3C 的推荐标准

二、html与xml的区别

  • XML 不是 HTML 的替代。

  • XML 和 HTML 为不同的目的而设计:

  • XML 被设计为传输和存储数据,其焦点是数据的内容

    ? HTML 被设计用来显示数据,其焦点是数据的外观 。
    ? HTML 旨在显示信息,而 XML 旨在传输信息。
    ? HTML语法比较松散,xml语法严格
    ? HTML所有标签都是预先定义好的, 使用固定的标签,展示不同的内容

  • ? XML当中的标签都是自己定义

  • ? XML用处,数据存储、配置文件、数据传输
    ?

三、XML的基本语法

1、文档声明


可以添加以下属性

  • version版本号,固定1.0
  • encoding指定文档的码表 默认iso-8859-1
  • standalone指定文档是否独立yes或no是否可以引用其它文件

注:文档声明必须放在第一行

2、规则

  1. 所有 XML 元素都须有关闭标签

  2. XML 标签对大小写敏感

  3. XML 必须正确地嵌套

  4. XML 文档必须有根元素

  5. XML 的属性值须加引号

  6. 实体引用

    在 XML 中,一些字符拥有特殊的意义。如果你把字符 "<" 放在 XML 元素中,会发生错误,这是因为解析器会把它当作新元素的开始。这样会产生 XML 错误:为了避免这个错误,请用实体引用来代替 "<" 字符:

    以下是5 个预定义的实体引用

    &lt;    <   小于
    &gt;    >   大于
    &amp;   &   和号
    &apos;  '   单引号
    &quot;  "   引号
  7. 元素命名规则

    xml中的元素其实就是标签,名称可以含字母、数字以及其他的字符但是类似于其他语言一样,不能够以数字或标点符号开始,也不能够以字符“xml”、“XML”、“Xml”开始,并且名称中不能包含空格。

  8. 引用CDATA输出数据内容

    <![CDATA[数据内容]]>

    里面的数据会原样展示不会解析

  9. xml元素中同样可以有属性

    <?xml version="1.0" encording="utf-8"?>
    <team>
     <person id="1001">
         <name>wen</name>
         <gender>男</gender>
     </person>
     <person id="1002">
         <name>wenss</name>
         <gender>男</gender>
     </person>
    </team>

四、XML约束

xml约束规定了文档当中只能写写那些标签,并且会给出一些提示。主要分为DTD约束与schema两类约束

1、DTD

  • 内部dtd
    在xml当中定义的dtd,开发中不建议使用

  • 外部dtd
    在外部文件当中单独定义的dtd,扩展名为.dtd
    本地:<!DOCTYPE 需要约束的名称 SYSTEM "需要约束的名.dtd">
    网络:<!DOCTYPE students PUBLIC "命名空间" "student.dtd">

  • 约束语法

    技术图片

例如:

web-app.dtd

<!ELEMENT web-app (servlet*,servlet-mapping*,wel-file-list?)>
<!ELEMENT servlet (servlet-name,description?,(servlet-class|jsp-file))>
<!ELEMENT servlet-name (#PCDATA)>
<!ELEMENT wel-file-list (welcome-file+)>

web.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE web-app SYSTEM  "web-app.dtd">

<web-app>

<servlet>
    <servlet-name></servlet-name>
    <servlet-class>aaa</servlet-class>
</servlet>

<servlet>
    <servlet-name>aaa</servlet-name>
    <jsp-file>aaa</jsp-file>
</servlet>

<servlet-mapping></servlet-mapping>

<wel-file-list>
    <welcome-file>aaa</welcome-file>
</wel-file-list>

</web-app>

student.dtd

<!ELEMENT students (student*) >
<!ELEMENT student (name,age,sex)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ELEMENT sex (#PCDATA)>
<!ATTLIST student number ID #REQUIRED>

student.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE students SYSTEM  "student.dtd">
<students> 
  <student number="a001"> 
    <name>张三</name>  
    <age>18</age>  
    <sex>男</sex> 
  </student>  
  <student number="a002"> 
    <name>李四</name>  
    <age>20</age>  
    <sex>男</sex> 
  </student>  
  <student number="a0003">
    <name>王五</name>
    <age>30</age>
    <sex>男</sex>
  </student>
</students>

弊端:在标签当中存放的内容不知道是什么类型,写的都是汉字或英文数字等等,这种约束不严谨

2、schema

schema是一种既能够约束标签又能够约束标签中的类型的约束

  1. 使用过程

    1. 编写根标签
    2. 引用约束地址 xsi:schemaLocation="默认空间 约束地址.xsd"
    3. 引用实例名称空间 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. 默认名称空间 xmlns="http://www.it666.cn/xml"
  2. 语法

    ? 技术图片

    技术图片

如上图一般schema分为复杂标签简单标签

复杂标签标签(complexType)当中还有子标签
简单标签标签(simpleType)当中没有子标签

五、XML解析

1、XML文档结构

不难看出xml就是一种树形结构,我们可以对上述students例子画出一个示意图如下

技术图片

  • student.xml Document : 文档节点 xml文件
  • students Element : 元素节点 使用<>的标签
  • number Attr : 属性节点 元素上属性名=“属性值”
  • zs Text : 文本节点 元素之间的内容

2、DOM

  1. 什么是DOM

    DOM:Document Object Model:文档对象模型,把文档中的成员描述成一个个对象.
    使用Java代码操作XML 或者 js代码操作HTML

  2. DOM解析的特点

    在加载的时候,一次性的把整个XML文档加载进内存,在内存中形成一颗树(Document对象).以后使用代码操作Document,其实操作的是内存中的DOM树,和本地磁盘中的XML文件没有直接关系.由于操作的是内存当中的dom,磁盘中xml当中的内容并没有变,要进行同步,让两边保持一致。当然查询不需要同步,只有数据变化的时候,才需要同步
    缺点:若XML文件过大,可能造成内存溢出.

  3. DOM解析步骤

    1. 创建解析器工厂
    2. 通过解析器工厂得到解析器
    3. 通过解析器得到document对象
    4. 获取具体的节点内容
    // 1.创建解析器工厂
    DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
    // 2.通过解析器工厂得到解析器
    DocumentBuilder db = dbf.newDocumentBuilder();
    // 3.通过解析器得到document对象
    Document doc = db.parse("src/com/xml/parse/student.xml");
    // 4.获取具体的节点内容
    NodeList list = doc.getElementByTagName("name");
    Node name = list.item(1);
    System.out.printlen(name.getTextContent());

    上述代码为java获取student.xml中的name 输出结果为李四

  4. DOM修改元素内容

    1. 获取所有指定节点

    2. 获取要修改的节点

    3. 修改元素内容

    4. 从内存写到文档做同步操作

    // 修改元素的内容
     static void updateElem(Document doc) throws TransformerFactoryConfigurationError, Exception {
    
         // 1.获取所有指定节点
         NodeList ageList = doc.getElementsByTagName("age");
         // 2.获取要修改的节点
         Node ageNode = ageList.item(1);
         // 3.修改元素内容
         ageNode.setTextContent("300");
         // 4.从内存写到文档做同步操作
         Transformer tf = TransformerFactory.newInstance().newTransformer();
         tf.transform(new DOMSource(doc), new StreamResult("src/com/xml/parse/student.xml"));
     }

    上述java代码先获取了节点名为age的节点并且取第1个值(0开始算),将第一个节点内容修改为300。如前文所说,我们现在所操纵的是内存中的xml树并不是真正的xml文件,所以我们还需要做第四步同步操作。同步操作与解析操作类似,我们首先需要创建一个传输工厂(TransformerFactory.newInstance()),然后创建一个传输器(tf),再通过传输器进行传输。tf.transform(xmlSource, outputTarget)传输器有两个参数,第一个为你要输出的new DOMSource(doc)源,第二个为new StreamResult(“src/com/xml/parse/student.xml”)流(从内存到文件一般使用流)。

  5. DOM添加元素

    1. 创建一个节点

    2. 设置元素内容

    3. 获取要添加元素的父结点

    4. 在父节点中添加节点

    5. 从内存写到文档做同步操作

    // 添加节点
    static void addElem(Document doc) throws Exception, TransformerFactoryConfigurationError {
        // 1.创建一个节点
        Element addressEle = doc.createElement("address");
        // 2.设置元素内容
        addressEle.setTextContent("地址1");
        // 3.获取要添加元素的父结点
        Node stuNode = doc.getElementsByTagName("student").item(0);
        // 4.添加节点
        stuNode.appendChild(addressEle);
        // 5.从内存写到文档做同步操作
        Transformer tf = TransformerFactory.newInstance().newTransformer();
        tf.transform(new DOMSource(doc), new StreamResult("src/com/xml/parse/student.xml"));
    }
  6. DOM删除元素

    1. 获取一个节点

    2. 获取该节点的父节点,从父节点当中移除

    3. 从内存写到文档做同步操作

    // 删除节点
     static void delElem(Document doc) throws Exception, TransformerFactoryConfigurationError {
         // 1.获取一个节点
         Node addressNode = doc.getElementsByTagName("address").item(0);
         // 2.获取该节点的父节点,从父节点当中移除
         addressNode.getParentNode().removeChild(addressNode);
         // 3.从内存写到文档做同步操作
         Transformer tf = TransformerFactory.newInstance().newTransformer();
         tf.transform(new DOMSource(doc), new StreamResult("src/com/xml/parse/student.xml"));
     }
  7. DOM添加元素属性

    1. 获取要添加属性的节点

    2. 把获取的节点强制转换成element

    3. 设置属性

    4. 从内存写到文档做同步操作

    static void addElemPro(Document doc) throws Exception, TransformerFactoryConfigurationError {
         //1.获取要添加属性的节点
         Node stu = doc.getElementsByTagName("student").item(1);
         //2.把获取的节点强制转换成element
         Element ele = (Element)stu;
         //3.设置属性
         ele.setAttribute("ID", "00001");
         //4.从内存写到文档做同步操作
         Transformer tf = TransformerFactory.newInstance().newTransformer();
         tf.transform(new DOMSource(doc), new StreamResult("src/com/xml/parse/student.xml"));    
     }

3.DOM4j

  1. DOM4j简介

    DOM4J是dom4j.org出品的一个开源XML解析包,dom4j是一个十分优秀的JavaXML API,具有性能优异、功能强大和极其易使用的特点,它的性能超过sun公司官方的dom技术,同时它也是一个开放源代码的软件,越来越多的Java软件都在使用dom4j来读写XML,特别值得一提的是连Sun的JAXM也在用dom4j。这已经是必须使用的jar包, Hibernate也用它来读写配置文件。

  2. DOM4j解析步骤

    1. 下载Dom4j的jar包

    2. 在工程根目录当中创建一个文件夹为lib

    3. 编译jar包

    4. 创建SAXReader

    5. 读取指定路径的xml

     SAXReader reader = new SAXReader();
        Document doc = reader.read("srccomxmldom4jstudent.xml");
    1. 获取所有指定标签内容

      1. 创建SAXReader

      2. 获取根元素

      3. 获取根元素下所有的元素

      4. 遍历每一个子元素

      5. 获取指定名称的元素

      6. 获取标签当中的文本

    static void test() throws Exception {
         //获取所有指定标签内容
            //1.创建SAXReader
         SAXReader reader = new SAXReader();
            Document doc = reader.read("srccomxmldom4jstudent.xml");
            //2.获取根元素
            Element rootElement = doc.getRootElement();
            //3.根据名称获取根元素下的所有标签
            List<Element> stuList = rootElement.elements("student");
            //4.遍历每一个子元素
            for (Element stuEle : stuList) {
             //5.获取指定名称的元素
              //Element nameEle = stuEle.element("name");
              //System.out.println(nameEle.getText());
                //6.获取标签当中的文本
             //根据指定标签获取内容
             String name = stuEle.elementText("name");
             String age = stuEle.elementText("age");
             String sex = stuEle.elementText("sex");
             System.out.println(name);
             System.out.println(age);
             System.out.println(sex);
             String num = stuEle.attributeValue("number");//获取属性值
             System.out.println(num);
             System.out.println("------");
    
         }
     }
    1. 添加元素

    1.创建SAXReader
    2.获取根元素
    3.给根元素添加元素和属性,并返回添加的元素

//1.创建SAXReader
        SAXReader reader = new SAXReader();
        Document doc = reader.read("srccomxmldom4jstudent.xml");
        //2.获取根元素
        Element rootElement = doc.getRootElement();
        //3.给根元素添加元素和属性,并返回添加的元素
        Element stuEle = rootElement.addElement("student").addAttribute("number", "a0003");
        stuEle.addElement("name").setText("王五");     
        stuEle.addElement("age").setText("30");  
        stuEle.addElement("sex").setText("男");   
        
         // Pretty print the document to System.out
        OutputFormat format = OutputFormat.createPrettyPrint();
        Writer wr = new OutputStreamWriter(new FileOutputStream("src/com/xml/dom4j/student.xml"),"UTF-8");
        XMLWriter writer = new XMLWriter(wr, format);
        writer.write( doc );
        wr.close();

END...

以上是关于一篇习得XML的主要内容,如果未能解决你的问题,请参考以下文章

xml Eclipse模板(代码片段)检查参数并最终抛出IllegalArgumentException

需要示例代码片段帮助

从 XML 声明片段获取 XML 编码:部分内容解析不支持 XmlDeclaration

杂谈 | 习得性无助&习得性乐观

创建片段而不从 java 代码实例化它

如何组合绑定片段而不将它们包装在 XML 文字中