• XML


    XML语法

    XML的基本语法

    XML必须有关闭标签
    区分大小写
    属性需要有引号
    标签必须正确嵌套

    Xml文件的组成部分

    文档声明
    元素
    元素的属性
    注释
    CDATA区
    特殊字符
    处理指令(PI:Processing Instruction)

    XML的文档声明

    文档声明:出现在XML的第一行第一列的位置。

    写法
      <?xml 属性名=”属性值” 属性名=”属性值” ...?>
      version   :必须的. 使用”1.0”
      encoding  :字符集. 是使用浏览器打开的时候采用的默认的字符集的编码
      standalone    :描述XML文档是否需要依赖其他的文件

    xml的元素

    什么是元素

    xml中的元素其实就是一个个的标签
    标签分为两种
      a: 包含标签体
      理解: 简括号全部成对儿出现, 所有的数据都用一对儿简括号存储
                <student>
                    <name>zhangsan</name>
                    <age>18</age>
                </student>

      b: 不包含标签体
      理解: 只有最外层的一个简括号,括号用/标识结束, 内部的数据都用属性来编写
                <student
                    name="zhangsan"
                    age="18"
                />

    标签(元素的书写规范)

    严格区分大小写;<p><P>
    只能以字母或下划线开头;abc _abc
    不能以xml(或XML、Xml等)开头----W3C保留日后使用;
    名称字符之间不能有空格或制表符;
    名称字符之间不能使用冒号 : (有特殊用途)

    XML的属性

    属性的名称规范与元素一致,属性需要使用引号!

    元素中属性的注意事项
    一个元素可以有多个属性,每个属性都有它自己的名称和取值。
    属性值一定要用引号(单引号或双引号)引起来。
    属性名称的命名规范与元素的命名规范相同。
    元素中的属性是不允许重复的。
    在XML技术中,标签属性所代表的信息也可以被改成用子元素的形式来描述。
    例如:
    <?xml version="1.0" encoding="UTF-8"?>
    <students>
        <student name="zhangsan" age="18" />
        <student>
            <name>zhangsan</name>
            <age>18</age>
        </student>
    </students>

    XML的注释

    <!-- 被注释的内容 -->
    注释不能嵌套定义

    XML的CDATA区

    使用 CDATA 来避免输出标签文本时,过多的转义。
    XML的CDATA区:(CDATA:Character Data)
    <![CDATA[  内容  ]]>

    <students>
        <student>
            <name>zhangsan</name>
            <url>
                <![CDATA[
                    <cnblogs>www.cnblogs.com</cnblogs>
                    <baidu>www.baidu.com</baidu>
                ]]>
            </url>
        </student>
        
        <student>
            <name>zhangsan</name>
            <url>
                &lt;cnblogs&gt;www.cnblogs.com&lt;/cnblogs&gt;
            </url>
        </student>
    </students>
    CDATA和转义符

    XML的约束

    用来规范XML的写法。

    XML的约束的种类及区别?
        DTD(Document Type Definition 文档类型定义) 和 Schema
        区别:
            1.DTD语法是自成一体的.Schema语法就是XML的语法.
            2.Schema的语法就是XML的语法所以更容易被解析器所解析.
            3.Schema支持名称空间.
            4.Schema有比DTD更加强大的语义和语法的约束.

    DTD的语法

    DTD的引入方式

        内部的DTD:
            <!DOCTYPE persons [  ]>

        外部的DTD:
            一种本地DTD:
            <!DOCTYPE persons SYSTEM "unknown.dtd">
            一种网络DTD:
            <!DOCTYPE persons PUBLIC "//UNKNOWN/" "unknown.dtd">

    DTD的语法

    语法细节
    在DTD文档中使用ELEMENT关键字来声明一个XML元素。
    •   语法:<!ELEMENT 元素名称 使用规则>
    使用规则:
    •   (#PCDATA):指示元素的主体内容只能是普通的文本.(Parsed Character Data)
    •   EMPTY:用于指示元素的主体为空。比如<br/>
    •   ANY:用于指示元素的主体内容为任意类型。
    •   (子元素):指示元素中包含的子元素
    •   定义子元素及描述它们的关系:
    –   如果子元素用逗号分开,说明必须按照声明顺序去编写XML文档。
    •   如: <!ELEMENT FILE (TITLE,AUTHOR,EMAIL)>
    –   如果子元素用"|"分开,说明任选其一。
    •   如:<!ELEMENT FILE (TITLE|AUTHOR|EMAIL)>
    –   用+、*、?来表示元素出现的次数
    •   如果元素后面没有+*?:表示必须且只能出现一次
    •   +:表示至少出现一次,一次或多次
    •   *:表示可有可无,零次、一次或多次
    •   ?:表示可以有也可以无,有的话只能有一次。零次或一次

    <?xml version="1.0" encoding="UTF-8"?>
    <!ELEMENT 书架(书+)>
        <!ELEMENT 书 (书名,作者,售价)>
        <!ELEMENT 书名 (#PCDATA)>
        <!ELEMENT 作者 (#PCDATA)>
        <!ELEMENT 售价 (#PCDATA)>
    DTD例子


    定义属性
    •   在DTD文档中使用ATTLIST关键字来为一个元素声明属性。
    •   语法:
            <!ATTLIST 元素名
                属性名1 属性值类型 设置说明
                属性名2 属性值类型 设置说明
                …
            >
    •   属性值类型:
    –   CDATA:表示属性的取值为普通的文本字符串
    –   ENUMERATED (DTD没有此关键字):表示枚举,只能从枚举列表中任选其一,如(鸡肉|牛肉|猪肉|鱼肉)
    –   ID:表示属性的取值不能重复
    •   设置说明
    –   #REQUIRED:表示该属性必须出现
    –   #IMPLIED:表示该属性可有可无
    –   #FIXED:表示属性的取值为一个固定值。语法:#FIXED "固定值"
    直接值:表示属性的取值为该默认值

    <!ATTLIST 商品
            类别 CDATA #REQUIRED
            颜色 CDATA #IMPLIED
    >
    <?xml version = "1.0" encoding="GB2312" standalone="yes"?>
        <商品 类别="服装"颜色="黄色" />
    
    
    实例代码2
    <?xml version = "1.0" encoding="GB2312" standalone="yes"?>
    <!DOCTYPE 购物篮 [
       <!ELEMENT 购物篮 (肉+)>
        <!ELEMENT 肉 EMPTY>
        <!ATTLIST 肉 品种 ( 鸡肉 | 牛肉 | 猪肉 | 鱼肉 ) "鸡肉">
    ]> 
    <购物篮>
        <肉 品种="鱼肉"/>
        <肉 品种="牛肉"/>
        </>
    </购物篮>
    DTD元素属性例子

    DTD约束示例

    1.在xml下面创建demo1.dtd文件,代码如下
    <?xml version="1.0" encoding="UTF-8"?>
    <!ELEMENT persons (person+)> <!-- person节点可以出现一次或多次-->
    <!ELEMENT person (name|age|sex)*> <!-- name,age,sex节点可以出现 零次或多次, 且name,age,sex顺序随意-->
    <!ELEMENT name (#PCDATA)> <!-- name节点里面的内容放文本内容即可 -->
    <!ELEMENT age (#PCDATA)>
    <!ELEMENT sex (#PCDATA)>
    
    <!ATTLIST person id ID #REQUIRED> <!-- person属性是id,这个id必须存在,且id值是唯一的 -->
    
    
    2.在demo1.xml文件引入demo1.dtd约束,代码如下
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE persons SYSTEM  "demo1.dtd"> <!-- 引入dtd约束 -->
    <!-- XML的注释 -->
    <persons>
        <person id="p1">
            <name>李旭华</name>
            <age>38</age>
            <sex>男&lt;</sex>
        </person>
        <person id="p2">
            <name>李冠希</name>
            <age>28</age>
            <sex>男</sex>
        </person>
    </persons>
    DTD约束xml

    Schema约束

    Schema约束自身就是一个XML文件,但它的扩展名通常为.xsd。
    一个XML Schema文档通常称之为模式文档(约束文档),遵循这个文档书写的xml文件称之为实例文档。
    XML Schema对名称空间支持得非常好。

    名称空间: 相当于package。       
    约束文档: 编写好的Person类。
    实例文档: 通过Person类创建对象。

    约束文档:
    <?xml version='1.0' encoding='UTF-8' ?> 
    <xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema' 
                         //标准的名称空间
                          targetNamespace='http://www.cnblogs.com'
                            //将该schema文档绑定到http://www.cnblogs.com名称空间
                    >
        <xs:element name='书架' >
            <xs:complexType>
                <xs:sequence maxOccurs='unbounded' >
                    <xs:element name='书' >
                        <xs:complexType>
                            <xs:sequence>
                                <xs:element name='书名' type='xs:string' />
                                <xs:element name='作者' type='xs:string' />
                                <xs:element name='售价' type='xs:string' />
                            </xs:sequence>
                        </xs:complexType>
                    </xs:element>
                </xs:sequence>
            </xs:complexType>
        </xs:element>
    </xs:schema>
    
    实例文档:
    <?xml version="1.0" encoding="UTF-8"?>
    <cnblogs:书架 xmlns:cnblogs="http://www.cnblogs.com"
                    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                    xsi:schemaLocation="http://www.cnblogs.com book.xsd">
        <cnblogs:>
            <cnblogs:书名>JavaScript网页开发</cnblogs:书名>
            <cnblogs:作者>二狗子</cnblogs:作者>
            <cnblogs:售价>28.00元</cnblogs:售价>
        </cnblogs:书>
    </cnblogs:书架>
    
    
    名称空间:
    <cnblogs:书架 xmlns:cnblogs="http://www.cnblogs.com"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.cnblogs.com book.xsd">
    使用默认名称空间
        基本格式:
        xmlns="URI"  
        举例:
        <书架 xmlns="http://www.it315.org/xmlbook/schema"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://www.it315.org/xmlbook/schema book.xsd">
            <>
            <书名>JavaScript网页开发</书名>
            <作者>马杀鸡</作者>
            <售价>28.00元</售价>
            </>
        <书架>
    schema案例

    Schema约束示例

    1.创建demo2.xsd文件,代码如下
    <?xml version="1.0" encoding="UTF-8"?>
    <!-- 
        名称空间:一个XML只能引入一个DTD约束文档.使用了Schema约束XML文档,一个XML可以引入多个Schame的约束!!!
                          如果再多个Schema文档中定义了相同的属性名称 该怎么办?
          * 名称空间类似于java中的package.通过名称空间区分 标签或属性来自于哪个文档的!!!通常名称空间唯一的不重复的即可.一般情况下使用一个URL地址表示一个名称空间.
    
        xmlns               :xml name sapace .代表当前的文档应用的名称空间.
        targetNameSpace     :目标名称空间.
        elementFormDefault  :确定被约束文档书写的严谨程度
     -->
    <schema 
        xmlns="http://www.w3.org/2001/XMLSchema" 
        targetNamespace="http://www.boomoom.com/ee25" 
        xmlns:tns="http://www.example.org/demo2" 
        elementFormDefault="qualified">
    
        <!-- 复杂标签 -->
        <element name="persons">
            <!-- 复杂类型 -->
            <complexType>
                <sequence maxOccurs="unbounded" minOccurs="1">
                    <element name="person">
                        <complexType>
                            <sequence>
                                <!-- 简单标签 -->
                                <element name="name" type="string"></element>
                                <element name="age" type="int"></element>
                                <element name="sex" type="string"></element>
                            </sequence>
                            <attribute name="id" type="string" use="required"></attribute>
                        </complexType>              
                    </element>
                </sequence>
            </complexType>
        </element>
    </schema>
    
    2.创建demo2.xml文件,具体代码如下
    <?xml version="1.0" encoding="UTF-8"?>
    <!-- XML的注释 -->
    <persons
        xmlns:aa="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://www.cnblogs.com/ee25"
        aa:schemaLocation="http://www.boomoom.com/ee25 demo2.xsd"
    >
        <person id="p1">
            <name>李旭华</name>
            <age>38</age>
            <sex>男</sex>
        </person>
    
        <person id="p2">
            <name>李冠希</name>
            <age>28</age>
            <sex>男</sex>
        </person>
    </persons>
    Schema约束XML

    XML的解析的方式

    DOM解析:DOM:Document Object Model.
    SAX解析:Simple Api for XML.

    DOM和SAX的区别

    DOM 是一次性将文档加载到内存,形成树形结构进行解析。
    优点:对 XML 进行增删改的操作。
    缺点:如果文档特别大,容易导致内存溢出。

    SAX是事件驱动的方式,一行一行进行解析的。
    优点:如果文档特别大,不会导致内存溢出。
    缺点:不能文档进行增删改的操作。

    DOM4J

     DOM4J:开源组织提供了一套XML的解析的API。

    DOM4J的入门案例步骤

    1、导入jar包.dom4j-1.6.1.jar
    2、创建解析器
    3、解析文档获得代表文档的Document对象.
    4、获得跟节点.
    5、从跟节点下查找其他的节点.

    @Test
        /**
         * 获得元素的内容:查询的操作.
         */
        public void demo1() throws Exception{
            // 创建解析器
            SAXReader reader = new SAXReader();
            // 解析XML的文档
            Document document = reader.read("xml/demo1.xml");
            // 获得跟节点
            Element root = document.getRootElement();
            System.out.println(root.getName());
            // 查找跟节点下的子节点. element() elements();
            Element pElement = root.element("person"); // 查找的是第一个person元素
            // root.elements("person").get(1); // 查找的是第二个person元素
            Element nElement = pElement.element("name");
            Element aElement = pElement.element("age");
            Element sElement = pElement.element("sex");
            System.out.println(nElement.getText());
            System.out.println(aElement.getText());
            System.out.println(sElement.getText());
        }
    dom4j解析样例

    XPath

    dom4j支持XPath的jar包.
      jaxen-1.1-beta-6.jar
    dom4j的XPath支持的API:
      List document.selectNodes(String xPath);
      Node document.selectSingleNode(String xPath);

        @Test
        /**
         * DOM4J的XPath的写法:
         */
        public void demo2() throws Exception{
            // 创建解析器:
            SAXReader reader = new SAXReader();
            // 解析XML返回Document对象.
            Document document = reader.read("xml/demo1.xml");
            /*List<Node> list = document.selectNodes("//name");
            for (Node node : list) {
                Element element = (Element) node;
                System.out.println(element.getText());
            }*/
            
            List<Node> list = document.selectNodes("//person['@id']");
            for (Node node : list) {
                Element element = (Element) node;
                System.out.println(element.attributeValue("id"));
            }
        }
    代码实现

    DOM4J解析XML

    1.创建一个webapps文件夹,把html等文件放入,创建一个conf文件,把server.xml文件放入,server.xml配置文件如下:
    <?xml version="1.0" encoding="UTF-8"?>
    <Server>
        <Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
    </Server>
    
    2.在MyServer中的代码如下:
    public class MyServer { 
        public static void main(String[] args) throws Exception {
            // 解析XML:
            // 创建解析器
            SAXReader reader = new SAXReader();
            // 解析XML文档:
            Document document = reader.read("conf/server.xml");
            Element element = (Element)document.selectSingleNode("//Connector['@port']");
            String port = element.attributeValue("port");
            // ServerSocket 对象可以监听端口
            ServerSocket serversocket = new ServerSocket(Integer.parseInt(port));
            //ServerSocket serversocket = new ServerSocket(8888);
            while(true) {
                Socket socket = serversocket.accept();  // 等待客户端的连接请求,一旦有请求过来,就结束阻塞,返回客户端对象
                //System.out.println(socket.getInetAddress());
                // 一旦有客户来访问, 就另开一个新线程去提供服务, main线程继续等待下一个客户的连接
                new Thread(new MyService(socket)).start();
            }
        }
    }
    
    3.在MyService中的代码如下:
    public class MyService implements Runnable{
        private Socket socket;
        public MyService(Socket socket) throws Exception {
            this.socket = socket;
        }
    
        @Override
        public void run() {
            // 提供服务
            try{
                InputStream in = socket.getInputStream();
                BufferedReader reader = new BufferedReader(new InputStreamReader(in));
                String firstLine = reader.readLine();
                System.out.println(firstLine);
                String path = firstLine.split(" ")[1];
                System.out.println(path);
                // 从文件读, 往浏览器写 
                File file = new File("webapps"+path);
                FileInputStream fis = new FileInputStream(file);
    
                OutputStream os = socket.getOutputStream();
                os.write("HTTP/1.1 200 OK
    ".getBytes());
                os.write("
    ".getBytes());
                byte[] buffer = new byte[1024];
                int len = 0;
                while ((len = fis.read(buffer))!=-1) {
                    os.write(buffer, 0, len);
                }
                socket.close();
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }
    dom4j解析xml

    DOM4J的常用方法

    Dom4JDemo:

    package com.boomoom;
    
    import java.io.IOException;
    import java.util.List;
    
    import org.dom4j.Document;
    import org.dom4j.DocumentHelper;
    import org.dom4j.Element;
    
    /*
     * Dom4J的常用方法:
     *      Document
     *           Element getRootElement() :获取根元素对象(根标签)
     *      Element
     *           List elements() :获取所有的子元素
     *           List elements(String name):根据指定的元素名称来获取相应的所有的子元素
     *           Element element(String name):根据指定的元素名称来获取子元素对象,如果元素名称重复,则获取第一个元素 
     *           String elementText(String name) :根据指定的子元素名称,来获取子元素中的文本
     *           String getText() :获取当前元素对象的文本
     *           void setText(String text):设置当前元素对象的文本
     *           String attributeValue(String name):根据指定的属性名称获取其对应的值
     *           public Element addAttribute(String name,String value):根据指定的属性名称和值进行添加或者修改
     *           addElement
     *      DocumentHelper
     *          static Element  createElement(String name)    
     */
    public class Dom4JDemo {
        public static void main(String[] args) throws Exception  {
            //7、操作XML文件属性:打印State的Name
            //8、添加属性:State: GDP="1w亿"
            Document document = Dom4JUtils.getDocument();
            //获取根元素
            Element rootElement = document.getRootElement();
            //添加新的属性和对应的值
            rootElement.addAttribute("GDP", "1w亿");
            //写回文件
            Dom4JUtils.write2XML(document);
        }
    
        private static void method7() throws Exception {
            //7、操作XML文件属性:打印State的Name
            Document document = Dom4JUtils.getDocument();
            //获取根元素
            Element rootElement = document.getRootElement();
            //根据属性名称获取值
            String value = rootElement.attributeValue("Name");
            System.out.println(value);
        }
    
        private static void method6() throws Exception, IOException {
            //5、向指定元素节点上增加同级元素节点:在洛阳前面,添加一个<City>三门峡</City>
            //创建一个新的元素对象
            Element cityElement = DocumentHelper.createElement("City");
            //设置文本
            cityElement.setText("三门峡");
            Document document = Dom4JUtils.getDocument();
            //获取根元素
            Element rootElement = document.getRootElement();
            //获取根元素下所有的子元素
            List<Element> es = rootElement.elements();
            //将新的元素添加到子元素列表中
            es.add(1, cityElement);
            
            //写会文件
            Dom4JUtils.write2XML(document);
        }
    
        private static void method5() throws Exception, IOException {
            //4、向指定元素节点中增加子元素节:添加一个新城市<City>南阳</City>
            Document document = Dom4JUtils.getDocument();
            //获取根元素
            Element rootElement = document.getRootElement();
            //添加元素
            Element cityElement = rootElement.addElement("City");
            //设置文本
            cityElement.setText("南阳");
            //写回文件
            Dom4JUtils.write2XML(document);
        }
    
        private static void method4() throws Exception, IOException {
            //6、删除指定元素节点:删除元素开封 
            Document document = Dom4JUtils.getDocument();
            //获取根元素
            Element rootElement = document.getRootElement();
            //获取根元素下的所有子元素
            List<Element> es = rootElement.elements();
            Element cityElement = es.get(1);
            //无法自杀,找他爹
            Element parentElement = cityElement.getParent();
            parentElement.remove(cityElement);
            //写回文件
            Dom4JUtils.write2XML(document);
        }
    
        private static void method3() throws Exception, IOException {
            //3、修改某个元素节点的主体内容:信阳-->安阳
            Document document = Dom4JUtils.getDocument();
            //获取根元素
            Element rootElement = document.getRootElement();
            //获取根元素下的所有子元素
            List<Element> es = rootElement.elements();
            //根据索引可以获取指定的元素
            Element cityElement = es.get(3);
            //修改文本
            cityElement.setText("安阳");
            //写回文件
            Dom4JUtils.write2XML(document);
        }
    
        private static void method2() throws Exception {
            //2、遍历所有元素节点:打印他们的元素名称。
            //获取根元素
            Document document = Dom4JUtils.getDocument();
            Element rootElement = document.getRootElement();
            treeWalk(rootElement);
        }
        
        public static void treeWalk(Element element) {
            //输出元素的名称
            System.out.println(element.getName());
            
            //获取指定元素的所有子元素
            List<Element> es = element.elements();
            for (Element e : es) {
                treeWalk(e);
            }
        }
    
        private static void method() throws Exception {
            //1、得到某个具体的节点内容:打印"郑州"
            Document document = Dom4JUtils.getDocument(); 
            //获取根元素
            Element rootElement = document.getRootElement();
            //获取根元素下的所有子元素
            List<Element> elements = rootElement.elements();
            //根据索引获取第一个City元素
            Element cityElement = elements.get(0);
            //根据子元素的名称来获取子元素的文本
            String text = cityElement.elementText("Name");
            System.out.println(text);
        }
    }
    Dom4JDemo

    Dom4JUtils:

    package com.boomoom;
    
    import java.io.FileOutputStream;
    import java.io.IOException;
    
    import org.dom4j.Document;
    import org.dom4j.io.OutputFormat;
    import org.dom4j.io.SAXReader;
    import org.dom4j.io.XMLWriter;
    
    public class Dom4JUtils {
        
        public static Document getDocument() throws Exception {
            SAXReader reader = new SAXReader();
            Document document = reader.read("src/com/boomoom/city.xml");
            return document;
        }
        
        public static void write2XML(Document document) throws IOException {
            OutputFormat format = OutputFormat.createPrettyPrint();
            //format.setEncoding("UTF-8");//默认的编码就是UTF-8
            XMLWriter writer = new XMLWriter( new FileOutputStream("src/com/boomoom/city.xml"), format );
            writer.write( document );
        }
    }
    Dom4JUtils

    city.xml

    <?xml version="1.0" encoding="UTF-8"?>
    
    <State Code="37" Name="河南" 
        description="郑州" GDP="1w亿"> 
      <City> 
        <Name>郑州</Name>  
        <Region>高薪区</Region> 
      </City>  
      <City>三门峡</City>  
      <City>洛阳</City>  
      <City>安阳</City>  
      <City>南阳</City> 
    </State>
    city.xml
  • 相关阅读:
    hdu 2019 数列有序!
    hdu 2023 求平均成绩
    HDU 5805 NanoApe Loves Sequence (思维题) BestCoder Round #86 1002
    51nod 1264 线段相交
    Gym 100801A Alex Origami Squares (求正方形边长)
    HDU 5512 Pagodas (gcd)
    HDU 5510 Bazinga (字符串匹配)
    UVALive 7269 Snake Carpet (构造)
    UVALive 7270 Osu! Master (阅读理解题)
    UVALive 7267 Mysterious Antiques in Sackler Museum (判断长方形)
  • 原文地址:https://www.cnblogs.com/boomoom/p/10421400.html
Copyright © 2020-2023  润新知