zoukankan      html  css  js  c++  java
  • 标记语言XML

    标记语言概述


    标记语言,是一种将文本(Text)以及文本相关的其他信息结合起来,展现出关于文档结构和数据处理细节的电脑文字编码。一部分是标记,一部分是标记中的内容,两部分构成标记语言   <标记>..内容..</>格式.

    当今广泛使用的标记语言是超文本标记语言,可扩展标记语言标记语言广泛应用于网页和网络应用程序。

    1. 超文本标记语言HTML(Hyper Text Markup Language)

        Html是标记语言的一种,是典型的标记语言。标记用来对内容进行定义和修饰,内容是数据的本质。普通的标记语言-->Html中用到的所有标记都是事先制定好的,自己不能增加标记定义,只能用已经定义好的标记。 (如 <a></a>表示超链接)

    2. 可扩展的标记语言XML(eXtensible Markup Language)

        可扩展的标记语言-->可以自己定义标记并赋予意义。

         XML的作用:用于数据存储和数据描述

        使用场景        

        a、利用xml充当配置文件

        b、用于不同系统间的数据交换(XML可使用不同系统和平台)

        c、利用XML存储一些少量数据(大量数据需要使用数据库)

    3. Xml和Html语言由同一种父语言SGML(Standard Generalized Markup Language,标准通用标记语言)发展出来的两种语言。

    4. 解析器  解析器(比如:XML SPY与用于解析XML文件) ,浏览器 ,MyEclipse

    5. W3C(World Wide Web Consortium)

      W3C: 开源的语言协会,万维网联盟(World Wide Web Consortium)

        HTML和XML都是W3C制定的语言规则

        官网:www.w3.org

        学习网站:http://www.w3school.com.cn/

    XML语法规则


    XML文件扩展名为.xml;XML文件由第一行指令和元素构成

    指令

    XML声明,负责指定xml文件的编码和xml版本。写在XML的第一行<?xml version="1.0" encoding="UTF-8"?> 不要修改。version:语法的版本号  encoding:文字的编码,能写中文

    元素(Element

    元素由标记和其中的内容组成  <标记名称>内容</标记名称>

    1. 根元素       最外层的元素叫根元素 ,一个XML文件有且只有一个根元素

    2. 叶子元素    最里层的(没有子元素的)元素叫叶子元素

    3. 空元素       没有内容的元素叫空元素,比如<a></a>,可以简写为:<a /> 。有标记,没内容

    4. 普通元素    标记+内容+结束标记

    5. 元素必须遵循的语法规则

       1)所有的标记都必须有结束  2)开始标记和结束标记必须成对出现  3)元素必须正确嵌套<a><b>c</b></a> (正确) <a><b>c</a></b> (错误)  4)标记的大小写敏感 Hello 和 hello不是同一个标记  5有且只能有一个根元素

    标记

    标记名字可以随意指定,可以用中文也可以用英文

    1. 标记包括开始标记和结束标记  2. 开始标记和结束标记必须成对出现,所有的标记都必须有结束  3. 标记的大小写敏感

    注释

    格式:<!-- 注释的内容-->  编译器将忽略注释  Html和XML注释方式相同

    属性(定义在开始标记中的键值对)

    1. 格式:属性="属性值"

    2. 要求:属性必须有值,属性值必须用引号引起来,单引号或双引号都可以,但必须一致

    3. 属性是隶属于某个元素,<标记名称 属性名=“属性值”>内容</标记内容>,属性可以写多个,属性名不能重复

    实体引用(转义字符)

    如果元素内容遇到下面几种特殊字符,可以使用实体替代

    小于号(<): less than --> &lt ;

    大于号(>): great than --> &gt ;

    And符号(&): &amp;

    双引号(“): &quot;

    单引号(‘): &apos;

    注意这些转义字符都是以&开头,以;结尾的 。<,&字符必须用实体,其他几个建议使用

    文本域

    格式: < ! [ CDATA [ 文本内容 ] ] >  文本域中的实体引用都被忽略,所有内容被当成一整块文本数据对待

    <![CDATA[
        一本好书,没<<笑傲江湖>>好看,比<<Thinking in java>>好看
    ]]> 

    规则小结

    1) 必须有唯一的根元素

    2) xml标记大小写敏感

    3) 标记必须配对出现,有开始有结束

    4) 元素必须被正确嵌套

    5) 属性必须有值,值必须用引号引括起来

    6) 如果遵循所有的规则,称作格式良好的xml文件(well-formed)

    使用XML文件描述数据的例子

    1. 早期属性文件描述数据的方式

      url = jdbc:oracle:thin@192.168.0.26:1521:tarena

       dbUser = openlab

       dbPwd = open123

    2. 现在使用xml表示方式

       <datasource id="db_oracle">

         <property name="url">jdbc:thin@192.168.0.26:1521:tarena</property>

         <property name="dbUser">openlab</property>

         <property name="dbPwd">open123</property>

        </datasource>

    DTD(文档类型定义Document Type Difinition /Schema


    DTD和Schema都是用于限定XML格式的技术。可以限制XML使用那些标记,标记出现顺序,标记嵌套关系,有哪些属性等。有效的xml文件 = 格式良好的xml文件 + 有DTD或Schema规则 + 遵循DTD或Schema的规则

    DTD/Schema的由来

    行业交换数据时要求xml文件格式相同,所以需要大家遵守规范的xml文件格式。

    A学校的XML文件中

    <计算机书籍>
      <书名 isbn="1234">XML的前世今生</书名>
      <价格>65</价格>
      <简介>一本好书</简介>
      <作者>李毅</作者>
    </计算机书籍>

    B学校的XML文件中

    <Computer_book>
        <isbn>1234</isbn>
        <bookname author="李毅">XML的前世今生</bookname>
        <price>65</price>
        <brief>一本好书</brief>
    </Computer_book>

    这两个文件数据相同,但结构不同,无法交换数据

    DTD技术

    Document Type Definition文本类型定义,可以定义一个XML标记,出现顺序等规则。

    1. 定义元素和标记

    <!ELEMENT 标记名 (子标记名或#PCDATA)>

    定义dept标记,该标记内部可以使用dname和loc子元素

    <!ELEMENT dept (dname,loc)>

    定义dname标记,该标记只能包含文本内容

    <!ELEMENT dname (#PCDATA)>

    定义dept标记,该标记内部只能用dname或loc之一

    <!ELEMENT dept (dname | loc)>

    定义一个loc空元素

    <!ELEMENT loc EMPTY>

    2. 元素出现次数的定义

        *允许出现0到多次. <!ELEMENT depts (dept*)>

        +允许出现1到多次.

        ?允许出现0次或1次

    定义package元素,里面可以出现0到多次的interceptors和action,但action必须在interceptors之后

    <!ELEMENT package (interceptors*,action*)>

    3. 定义属性

    <!ATTLIST 标记名 属性 CDATA 默认值>

    4. DTD使用方法

    在需要限定的XML中,利用下面指定引入。SYSTEM:个人或小范围应用,PUBLIC:某个组织或国际社团使用。浏览器显示的时候,DTD内容不显示

    <!DOCTYPE 根元素名  SYSTEM|PUBLIC "dtd文件位置">

    5.案例

    dept.dtd文件内容    

    <!ELEMENT DEPTS (DEPT)*>
    <!ELEMENT DEPT (DNAME,LOC)>
    <!ELEMENT DNAME (#PCDATA)>
    <!ELEMENT LOC (#PCDATA)>
    <!ATTLIST DEPT DEPTNO CDATA #REQUIRED>

    dept.xml文件内容

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE DEPTS SYSTEM "depts.dtd">
    <DEPTS>
      <DEPT DEPTNO="10">     <DNAME>ACCOUNTING</DNAME>     <LOC>NEW YORK</LOC>   </DEPT>   <DEPT DEPTNO="20">     <DNAME>RESEARCH</DNAME>     <LOC>DALLAS</LOC>   </DEPT>
      <DEPT DEPTNO="30">     <DNAME>SALES</DNAME>     <LOC>CHICAGO</LOC>   </DEPT> </DEPTS>

    mybatis的xml配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="xxx.xx">
         ...
    </mapper>

    Schema技术

    Schema技术可以实现DTD的定义功能。一个xml只能引用一个DTD,如果引入多个DTD遇到相同标记时会产生混淆。而Schema在引入时需要指定命名空间名,可以通过命名空间名区分。

    Java API解析XML文件


    Java和xml有很多共同点(比如跨平台、不厂商无关),目前为止java对xml的解析较其他语言更完善

    两种解析方式

    1. DOM(Document Object Model 文档对象模型)

    关键字:树(Document)

    优点: 把xml文件在内存中构造树形结构,可以遍历和修改节点

    缺点: 如果文件比较大,内存有压力,解析的时间会比较长

    2. SAX(Simple API for Xml 基于XML的简单API)

    关键字:流(Stream)

    把xml文件作为输入流,触发标记开始,内容开始,标记结束等动作

    优点: 解析可以立即开始,速度快,没有内存压力

    缺点: 不能对节点做修改

    JDOM / DOM4J

    目前市场上常用的2种解析XML文件的API。dom4j-1.6.1.jar 结合了DOM和SAX两种解析方式的优点

    dom4j工具使用步骤

    a、引入dom4j.jar开发包

    b、利用dom4j提供的API

        Document对象:文档树对象

        doc.getRootElement()获取树根节点元素

        elements("标记名"):获取子节点元素(复数)

        element("标记名"):获取子节点元素(单数)

        getText():获取节点的文本值

        attributeValue("属性名"):获取属性值

        setText(val):修改节点文本值

        remove(子节点):删除子节点元素

        setAttributeValue("属性名","属性值"):修改属性值

        addAttributeValue()添加属性值

    案例

    第一步:引入jar包,pom配置

    <!-- dom4j -->
    <dependency>  
        <groupId>dom4j</groupId>  
        <artifactId>dom4j</artifactId>  
        <version>1.6.1</version>  
    </dependency> 

    第二步:util工具类

    package com.org.qin.common.xml;
    public class Book {
        private String id;
        private String name;
        private String author;
        private String price;
    
        @Override
        public String toString() {
            return this.id + ":" + this.name + ":" + this.author + ":" + this.price;
        }
    }
    package com.org.qin.common.xml;
    import java.io.File;
    import java.io.FileOutputStream;
    import java.io.FileWriter;
    import java.io.OutputStream;
    import java.util.ArrayList;
    import java.util.List;
    import org.dom4j.Document;
    import org.dom4j.DocumentHelper;
    import org.dom4j.Element;
    import org.dom4j.io.OutputFormat;
    import org.dom4j.io.SAXReader;
    import org.dom4j.io.XMLWriter;
    public class XmlUtil {
        /**
         * 生成xml文件
         * 
         * @param xmlFile
         * @param bookList
         * @throws Exception
         */
        public static void toXMLFlie(String file, List<Book> bookList) throws Exception {
    
            Document doc = DocumentHelper.createDocument(); // 创建一个空白的XML文档
            Element root = doc.addElement("book-list"); // 添加一个元素,返回值是刚刚添加的元素
    
            for(Book book : bookList){
                Element bookElement = root.addElement("book");
                bookElement.addElement("id").setText(book.getId());
                bookElement.addElement("name").setText(book.getName());
                bookElement.addElement("author").setText(book.getAuthor());
                bookElement.addElement("price").setText(book.getPrice());
            }
    
            /**
             * 这个XML文档存储在内存里, 把XML文档写到文件里,xmlFile
             * OutputFormat:输出格式
             * OutputFormat.createCompactFormat:默认的,紧凑格式,好
             * OutputFormat.createPrettyPrint:常写的格式,传入很多空格字符,不好
             */
            OutputFormat format = OutputFormat.createPrettyPrint();
            XMLWriter writer = new XMLWriter(new FileWriter(file), format);
            writer.write(doc);
            writer.close();
        }
    
        /**
         * 读取xml文件,生成list对象。注意:写这个程序的一定知道XML文档的结构
         * 
         * @param xmlFile
         * @return
         * @throws Exception
         */
        @SuppressWarnings("unchecked")
        public static List<Book> parseXmlToBookList(String xmlFile) throws Exception {
    
            SAXReader reader = new SAXReader(); // 用于读取XML文档SAXReader
            Document doc = reader.read(new File(xmlFile)); // Document 用于封装解析后的XML数据
            Element root = doc.getRootElement(); // 得到根元素,Element用于封装元素
            List<Element> bookElements = root.elements("book");// 返回根元素下名为book的所有节点
    
            List<Book> bookList = new ArrayList<Book>();
            for(Element ele : bookElements){
                Book book = new Book();
                book.setId(ele.element("id").getText());
                book.setName(ele.element("name").getText());
                book.setAuthor(ele.element("author").getText());
                book.setPrice(ele.element("price").getText());
                bookList.add(book);
            }
            return bookList;
        }
    
        /**
         * 修改xml文件内容
         * 
         * @param xmlFile
         */
        @SuppressWarnings("unchecked")
        public static void updateXmlText(String xmlFile) throws Exception {
            SAXReader reader = new SAXReader();
            Document doc = reader.read(new File(xmlFile));
            Element root = doc.getRootElement(); // 找到根元素books
            List<Element> bookElements = root.elements("book"); // 从books下找所有的book
    
            // 循环找出id=1002的book元素
            for(Element ele : bookElements){
                String id = ele.element("id").getText();
                // 如果是10001删除book节点
                if("10001".equals(id)){
                    root.remove(ele);// 从books节点中将book移除
                }
                // 如果是10002修改price值
                else if("10002".equals(id)){
                    // 定位book的price子元素
                    Element price = ele.element("price");
                    // 修改price文本值
                    price.setText("60");
                }
            }
    
            // 将内存中文档树对象状态更新到xml文件中
            OutputStream os = new FileOutputStream(xmlFile);
            XMLWriter writer = new XMLWriter(os);
            writer.write(doc);// 将doc文档对象输出
            writer.flush();
            writer.close();
        }
    
        public static void main(String[] args) throws Exception {
            List<Book> bookList = new ArrayList<Book>();
            // for(int i = 0; i < 5; i++){
            // Book book = new Book();
            // book.setId("1000" + i);
            // book.setName("bookName" + i);
            // book.setAuthor("bookAuthor" + i);
            // book.setPrice("20.1" + i);
            // bookList.add(book);
            // }
    
            // 测试生成xml文件
            // XmlUtil.toXMLFlie("d:/books.xml", bookList);
    
            // 解析xml文件
            bookList = XmlUtil.parseXmlToBookList("d:/books.xml");
            System.out.println(bookList);
    
            // 更新xml文件
            XmlUtil.updateXmlText("d:/books.xml");
            bookList = XmlUtil.parseXmlToBookList("d:/books.xml");
            System.out.println(bookList);
        }
    }

    XPATH


    XPATH:相当于XML的SQL语句,从XML中取出我们想要的数据。功能:可以快速定位文档树对象的节点

    在dom4j.jar包基础上引入jaxen-1.1-beta-6.jar,然后利用selectNodes("xpath表达式");selectSingleNode("xpath表达式");

    xpath表达式语法:

    //节点名 : 定位任意位置的节点元素对象

    /节点名 : 定位指定名字的根节点元素

    /节点1/节点2 : 定位根节点1下面的节点2

    //节点名[子节点名='文本值'] :利用子元素内容做条件定位节点

    //节点名[@属性名='属性值'] :利用属性做条件定位节点

    public static void main(String[] args) throws Exception {
            SAXReader reader = new SAXReader();
            Document doc = reader.read(new File("d:/books.xml"));
            List<Element> list = doc.selectNodes("/book-list/book/price");
            for(Element e : list){
                System.out.println(e.getText());
            }
            list = doc.selectNodes("/book-list/book[price<=200]/price");
            for(Element e : list){
                System.out.println(e.getText());
            }
    }

    “/book-list/book/price":节点路径XPTH,找什么样的节点

    Book[ 筛选条件],筛选条件可以有:first()  last()  postion()==>定哪些元素要哪些元素不要

    eg:book[ potion()>1 and postion()<4]:第2,3个元素  Book[ price<200 and price>100]

     

     

  • 相关阅读:
    RESTful API规范
    SOAP和RESTful 框架的 简介、对比和区别
    @requestBody 与@requestparam详解
    关于“Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.”
    post和get、PostMapping、GetMapping和RequestMapping
    强引用、软引用、弱引用、虚引用及方法区的垃圾回收策略
    jvm运行时数据区域
    HBase入门
    各种http报错的报错的状态码的分析
    maven配置多个镜像
  • 原文地址:https://www.cnblogs.com/qin-derella/p/6549611.html
Copyright © 2011-2022 走看看