W4-xml基础知识一[JavaWeb]

1.xml的简介-extensible markup language:可扩展标记型语言(了解)

  1.1标记型语言:html是标记型语言,使用标签操作

   -不同于html之处:可扩展:html里面的标签是固定的,每个标签都有特定的含义

          标签可以自己定义,可以写中文标签

  1.2 xml用途:

   -html用于显示数据,xml也可以显示数据(不是主要功能)

   -xml主要功能是为了存储数据

  1.3 xml两个版本1.0 1.1版本,1.1版本不能向下兼容

   -是w3c组织发布的技术

2.xml的应用

     2.1 不同的系统之间传输数据,有利于程序的维护

  2.2 用来表示生活中有关系的数据

  2.3 作为配置文件

   -比如连接数据库,需要知道数据库的用户名和密码,数据库名称

     -如果修改数据库的信息,不需要修改源代码,只需要修改配置文件

3. xml的语法

  3.1 xml的文档声明

  -创建一个文件,后缀名是.xml

  -若写xml,第一步必须要有一个文档声明(写了文档声明后,表示写xml文件的内容)

    --<?xml version="1.0" encoding="gbk"?>

    --文档声明必须在第一行第一列

  -属性

    --version:xml的版本1.0(使用) 1.1

    --encoding:xml编码 gbk utf-8 iso8859-1(不包含中文)

    --standalone:是否需要依赖其他文件  yes/no

  -解决中文乱码的问题 

<?version="1.0" encoding="utf-8"?>
<person>
    <name>张三</name>
    <age>20</age>
</person>

    --代码保存到本地硬盘,使用gbk编码保存

    --将“张三”转换到gbk码表里面对应的数字

    --打开xml文件时,使用设置的编码 utf-8

    --在utf-8码表中找到数字对应的文字,出现乱码

    --解决方案:设置保存的编码和打开的编码一致

  3.2 定义元素(标签)

  -标签定义有开始必须要有结束:<person></person>

  -标签没有内容,可以在标签内结束:<aa/>

  -标签可以嵌套,必须要合理嵌套

    --合理嵌套<aa><bb></bb></aa>

    --不合理嵌套<aa><bb></aa></bb>

  -一个xml中,只能有一个根标签,其他标签都是这个标签下面的标签  

  -在xml中把空格和换行都当成内容来解析,下方两段代码含义不同

<aa>11111</aa>
<aa>
    11111
</aa>

  -xml中标签的命名规则

    --xml代码区分大小写

    --标签名称不能以数字或下划线开头

    --标签名称不能以xml、XML、Xml开头

    --标签名称中不能包含空格和冒号

  3.3 定义属性

  -HTML是标记型文档,可以有属性;xml也是标记型文档,可以有属性

  -<person id="aaa"></person>

  -属性定义的要求

    --一个标签上可以有多个属性 

<person id1="aaa" id2="bbb"></person>

    --属性名称不能相同

    --属性名称和属性值使用=,属性值使用引号包起来

    --xml属性的名称规范和元素的名称规范一致

  3.4 注释

  -写法:<!--注释的写法-->

  -注意点:注释不能嵌套,注释也不能放在第一行

  3.5 特殊字符

  -对特殊字符进行转义

    -- <  &lt;

    -- >  &gt;

    -- &  &amp;

    -- "   &quot;

    --'    &apos;

  3.6 CDATA区(了解)

  -可以解决多个字符都需要转义的操作,将需要转义的内容放到CDATA区里面,即不需转义

  -写法  <![CDATA[内容]]>

<![CDATA[<b>if(a>b && b>c){}</b>]]>

    3.7 PI指令(了解)

  -可以在xml中设置样式 

<?xml-stylesheet type="text/css" href="1.css"?>

  -设置样式,只能对英文标签名称起作用,对中文标签不起作用。

  3.8 xml的约束

  -需要约束的原因:比如定义一个person的xml文件,只想在该文件中保存人的信息,比如name、age等,但是如若在xml文件中写了一个标签<猫>,可以正常显示,但是猫不是人的基本信息,需要技术来规定xml中只能出现的元素,这个时候需要约束

  -xml的约束技术:dtd约束和schema约束(看懂)

  3.9 dtd的快速入门

  -创建一个文件 :后缀名 .dtd

  -步骤:   (1)看xml中有多少个元素,有几个元素,在dtd文件中写几个<!ELEMENT>

      (2)判断元素是简单元素还是复杂元素

        --复杂元素为有子元素的元素<!ELEMENT 元素名称 (子元素)>

        --简单元素为没有子元素的元素<!ELEMENT 元素名称 (#PCDATA)>

      (3)在xml文件中引入dtd文件

        <!DATYPE 根元素名称 SYSTEM "dtd文件的路径">

  -浏览器只负责校验xml的语法,不负责校验约束

  -利用myeclipse开发工具校验xml的约束

  3.10 dtd三种引入方式

  -引入外部的dtd文件

  <!DATYPE 根元素名称 SYSTEM "dtd文件的路径">

  -使用内部的dtd文件

<!DOCTYPE 根元素名称[
    <!ELEMENT person (name,age)>
    <!ELEMENT name (#PCDATA)>
    <!ELEMENT age (#PCDATA)>
]>

  -使用外部的dtd文件(网络上的dtd文件)

  <!DOCTYPE  根元素 PUBLIC  “ DTD名称”  “DTD文档的URL”>

  3.11 使用dtd定义元素

  -语法:<!ELEMENT 元素名 约束>

  -简单元素:没有子元素的元素

    --(#PCDATA):约束元素是字符串类型

    --EMPTY:元素为空(没有内容)

    --ANY:任意

  -复杂元素:

    --语法格式:<!ELEMENT 元素名称(子元素序列)>

    --子元素只能出现一次

    --表示子元素出现的次数

      +  :表示一次或者多次

      ?:表示零次或一次

      *  :表示零次或多次

    --子元素直接使用逗号进行隔开,表示子元素出现的顺序

    --子元素直接使用  | 进行隔开,表示元素只能出现其中任意的一个

  

  3.12 使用dtd定义属性

  -语法: <!ATTLIST 元素名称

        属性名称  属性类型  属性的约束

      > 

  -属性类型

    --CDATA:字符串

<!ATTLIST birthday
        ID1 CDATA #REQUIRED
    >

    --枚举:(aa|bb|cc)表示只能在一定的范围内出现值,但是只能每次出现其中的一个(交通信号灯效果)

<!ATTLIST age 
        ID2 (AA|BB|CC) #REQUIRED
    >

    --ID:值只能是字母或者下划线开头

<!ATTLIST name
        ID3 ID #REQUIRED
    >

  -属性的约束

    --#REQUIRED:表示该属性必须出现

    --#IMPLIED:表示该属性可有可无

    --#FIXED:表示一个固定值  #FIXED  "AAA"

         表示属性值必须是AAA

<!ATTLIST sex
        ID4 CDATA #FIXED "ABC"
    >

    --直接值:不写属性,使用该直接值;写属性,使用设置的那个值

<!ATTLIST school 
        ID5 CDATA "www"
    >

  3.13 实体的定义

  -语法: <!ENTITY 实体名称 “实体的值”>

<!ENTITY TEST "HAHAHEHE">

  -使用实体: &实体名称;

<name ID3="ss11">&TEST;</name>

  -注意:定义的实体需要写在内部dtd里面,若写在外部,会导致在某些浏览器中不能得到该内容

<?xml version="1.0" encoding="UTF-8"?>
<!-- <!DOCTYPE person SYSTEM "1.dtd"> -->
<!DOCTYPE person[
    <!ELEMENT person (name+,age?,sex*,school,birthday)>
    <!--<!ELEMENT person (name+|age?|sex*|school)>-->
    <!ELEMENT name (#PCDATA)>
    <!ATTLIST name
        ID3 ID #REQUIRED
    >
    <!ELEMENT age (#PCDATA)>
    <!ATTLIST age 
        ID2 (AA|BB|CC) #REQUIRED
    >
    <!ELEMENT sex EMPTY>
    <!ATTLIST sex
        ID4 CDATA #FIXED "ABC"
    >
    <!ELEMENT school (#PCDATA)>
    <!ATTLIST school 
        ID5 CDATA "www"
    >
    <!ELEMENT birthday (#PCDATA)>
    <!ATTLIST birthday
        ID1 CDATA #IMPLIED
    >
    
    <!ENTITY TEST "HAHAHEHE">
]>
<person>
<name ID3="ss11">&TEST;</name>
<age ID2="AA">20</age>
<sex ID4="ABC"></sex>
<school ID5="a">11111</school>
<birthday ID1="aaa">2015</birthday>
</person>

  3.14 xml的解析的简介(写到java代码)(重要的很)

  -xml是标记型文档

  -js使用dom解析标记型文档:根据HTML的层级结构,在内存中分配一个树形结构,把HTML的标签,属性和文本都封装成对象

                                             document对象、element对象、属性对象、文本对象、node节点对象

  -xml的解析方式:dom和sax

     --dom方式解析:根据xml的层级结构在内存中分配一个树形结构,把xml的标签,属性和文本都封装成对象

            缺点:若文件过大,造成内存溢出

            优点:很方便实现增删改操作

    --sax方式解析:采用事件驱动,边读边解析;从上到下,一行一行的解析,解析到某一个对象,返回对象名称

            缺点:不能实现增删改操作

            优点:如文件过大,不会造成内存溢出,方便实现查询操作

  -想要解析xml,首先需要解析器

    --不同的公司和组织提供了 针对dom和sax方式的解析器,通过api方式提供

      Sum公司针对两种解析器    jaxp

      dom4j组织针对两种解析器 dom4j(实际开发)

      jdom组织针对两种解析器   jdom

  

  3.15 JAXP的api查看

  -jaxp是javase的一部分

  -jaxp解析器是jdk的javax.xml.parsers包里面

    --四个类:分别是针对dom和sax解析使用的类

    --dom:

        DocumentBuilder:解析器类

          ---这个类是抽象类,不能new,此类实例可以通过DocumentBuilderFactory.newDocumentBuilder()方法获取

          ---一个方法,可以解析xml: parse("xml路径") 返回是 Document 整个文档

          ---返回的document是一个接口,父节点是Node,如果在document里面找到到想要的方法,在node里面找

          ---在document里面方法

            * getElementsByTagName(String tagname) 方法得到标签,返回集合NodeList

            *createElement(String tagName)方法创建标签

            *createTextNode(String data)方法创建文本

            ---在node中方法

            *appendChild(Node newChild)把文本添加到标签下面

            *removeChild(Node oldChild)删除节点

            *getParentNode()获取父节点

          ---Nodelist接口中方法

            *getLength()得到集合的长度

            *item(int index) 下标取到具体的值

            *getTextContent()得到元素中的内容

for(int i=0;i<list.getLength();i++){
  list.item(i);
}

        DocumentBuilderFactory:解析器工厂

          ---这个类也是一个抽象类,不能new,newInstance()获取 DocumentBuilderFactory的实例

    --sax:

        SAXParser:解析器类 

        SAXParserFactory:解析器工厂

  3.16 使用jaxp实现查询操作

  -查询xml中所有的name元素的值

  -步骤

       *1.创建解析器工厂
       *2.根据解析器工厂创建解析器
       *3.解析xml返回document
       *4.得到所有的name元素
       *5.返回集合,遍历结合,得到每一个name元素

//创建解析器工厂 alt/:代码提示
        DocumentBuilderFactory builderFactory=DocumentBuilderFactory.newInstance();
        //创建解析器
        DocumentBuilder builder=builderFactory.newDocumentBuilder();
        //解析xml,返回document
        Document document=builder.parse("src/person.xml");
        //得到name元素
        NodeList list=document.getElementsByTagName("name");
        for(int i=0;i<list.getLength();i++){
            Node name1=list.item(i);//得到每一个name元素
            //得到标签里面的内容
            String s=name1.getTextContent();
            System.out.println(s);
        }

  -查询xml中第一个元素的值

  -步骤 

       *1、创建解析器工厂
       *2.根据解析器工厂创建解析器
       *3.解析xml返回document
       *4.得到所有name元素
       *5.返回集合,里面方法item,下标获取具体的元素(集合下标从0开始)
       *6.得到具体的值getTextContent()

//得到解析器工厂
        DocumentBuilderFactory builderFactory=DocumentBuilderFactory.newInstance();
        //创建解析器
        DocumentBuilder builder=builderFactory.newDocumentBuilder();
        //返回document
        Document document=builder.parse("src/person.xml");
        //得到所有name元素
        NodeList list=document.getElementsByTagName("name");
        //返回第一个下标值
        String s=list.item(0).getTextContent();
        System.out.println(s);

  3.17 使用jaxp添加节点

  -在第一个p1末尾添加<sex>nv</sex>

  

public static void addSex()throws Exception{
        /*
         *1、创建解析器工厂
         *2.根据解析器工厂创建解析器
         *3.解析xml返回document
         *4.得到第一个p1
         *        -得到所有p1,使用item方法下标得到
         *5.创建sex标签 createElement
         *6.创建文本createTextNode
         *7.把文本添加到sex下面appendChild
         *8.把sex添加到第一个p1下面
         *9.回写xml
         */
        //创建解析器工厂
        DocumentBuilderFactory builderFactory=DocumentBuilderFactory.newInstance();
        //创建解析器
        DocumentBuilder builder=builderFactory.newDocumentBuilder();
        //返回document
        Document document=builder.parse("src/person.xml");
        //得到第一个p1
        Node p1=document.getElementsByTagName("p1").item(0);
        //创建sex标签
        Element sex=document.createElement("sex");
        //创建文本
        Text nv=document.createTextNode("nv");
        //将文本添加到sex下面
        sex.appendChild(nv);
        //将sex添加到第一个p1下面s
        p1.appendChild(sex);
        //回写xml
        TransformerFactory transformerFactory=TransformerFactory.newInstance();
        Transformer transformer=transformerFactory.newTransformer();
        transformer.transform(new DOMSource(document), new StreamResult("src/person.xml"));
        
    }

  3.18 使用jaxp修改节点

  -修改第一个p1下面的性别为男

public static void modifySex() throws Exception{
        /*
         *1、创建解析器工厂
         *2.根据解析器工厂创建解析器
         *3.解析xml返回document
         *4.得到sex item方法
         *5.修改sex里面的值 setTextContent方法
         *6.回写xml
         */
        //创建解析器工厂
        DocumentBuilderFactory builderFactory=DocumentBuilderFactory.newInstance();
        //创建解析器
        DocumentBuilder builder=builderFactory.newDocumentBuilder();
        //解析xml返回document
        Document document=builder.parse("src/person.xml");
        //得到sex
        NodeList list=document.getElementsByTagName("sex");
        //修改第一个sex里面的值
        list.item(0).setTextContent("nan");
        //回写xml
        TransformerFactory transformerFactory=TransformerFactory.newInstance();
        Transformer transformer=transformerFactory.newTransformer();
        transformer.transform(new DOMSource(document), new StreamResult("src/person.xml"));
    }

  3.19 使用jaxp删除节点

  -删除sex节点

//删除sex节点
    public static void delSex()throws Exception{
        /*
         * 1、创建解析器工厂
         *2.根据解析器工厂创建解析器
         *3.解析xml返回document
         *4.获取sex元素
         *5.获取sex的父节点
         *6.使用父节点删除removeChild方法
         *7.回写xml
         */
        //创建解析器工厂
        DocumentBuilderFactory documentBuilderFactory=DocumentBuilderFactory.newInstance();
        //创建解析器
        DocumentBuilder documentBuilder=documentBuilderFactory.newDocumentBuilder();
        //解析xml 
        Document document=documentBuilder.parse("src/person.xml");
        //获取sex元素
        Node sex=document.getElementsByTagName("sex").item(0);
        //获取sex的父节点
        Node sexf=sex.getParentNode();
        //删除sex节点
        sexf.removeChild(sex);
        //回写xml
        TransformerFactory transformerFactory=TransformerFactory.newInstance();
        Transformer transformer=transformerFactory.newTransformer();
        transformer.transform(new DOMSource(document), new StreamResult("src/person.xml"));
    }

  3.20 使用jaxp遍历节点

  -将xml中所有的元素名称打印出来

//遍历节点,把所有元素名称打印出来
    public static void listElement() throws Exception{
        /*
         * 1、创建解析器工厂
         *2.根据解析器工厂创建解析器
         *3.解析xml返回document
         *
         *===使用递归实现===
         *4.得到根节点
         *5.得到根节点子节点
         *6.得到根节点子节点的子节点
         */
        //创建解析器工厂
        DocumentBuilderFactory documentBuilderFactory=DocumentBuilderFactory.newInstance();
        //创建解析器
        DocumentBuilder documentBuilder=documentBuilderFactory.newDocumentBuilder();
        //解析xml 
        Document document=documentBuilder.parse("src/person.xml");
        //编写一个方法实现遍历操作
        list1(document);
    }
    private static void list1(Node node) {
        //判断是元素类型的时候才打印
        if(node.getNodeType()==Node.ELEMENT_NODE){
            System.out.println(node.getNodeName());            
        }
        // TODO Auto-generated method stub
        //得到一层子节点
        NodeList list=node.getChildNodes();
        //遍历list
        for(int i=0;i<list.getLength();i++){
            //得到每一个子节点
            Node node1=list.item(i);
            //继续得到node1子节点
            list1(node1);
        }
    }
原文地址:https://www.cnblogs.com/ERFishing/p/10972379.html