首页 > 学院 > 开发设计 > 正文

xml语法、DTD约束xml、Schema约束xml、DOM解析xml

2019-11-14 15:05:05
字体:
来源:转载
供稿:网友

今日大纲

1、什么是xml、xml的作用

2、xml的语法

3、DTD约束xml

4、Schema约束xml

5、DOM解析xml

1、什么是xml、xml的作用

1.1、xml介绍

在前面学习的html语言,html是超文本标记语言,使用html语言规定好的标签来封装文本数据。而html使用的标签html语言规定好的,每个标签都有自己特定的功能。

xml语言,可扩展的标记语言,这门语言它没有定义任何的标记,而标记是由使用者自己来定义,但是由于标签名称以及属性名称都由用户自己来命名,导致别人在使用的时候很不方便。有给xml语言定义了一些约束文档,这些约束文档就专门用来约束当前这个xml中能够书写的具体的标签以及属性等信息。

1.2、xml的作用

  

xml作用:  1、存储和传输复杂的关系模型数据  2、作为配置文件存在,xml中主要配置的一些具有复杂的层级关系的数据,PRoperties文件中主要配置的一些key和value这样的数据。  在软件系统中,作为配置文件使用  为提高系统的灵活性,它所启动的模块通常由其配置文件决定  例如一个软件在启动时,它需要启动A、B两个模块,而A、B这两个模块在启动时,又分别需要A1、A2和B1、B2模块的支持,为了准确描述这种关系,此时使用XML文件最为合适不过。  <soft>         <A>                <A1></A1>                <A2></A2>         </A>         <B>                <B1></B1>                <B2></B2>         </B>  </soft>

2、xml的语法

2.1、文档声明

来声明当前的xml类型。<?xml   ?>  在这个尖括号中书写标签的属性来声明当前的xml类型限定。属性:版本号   字符编码   是否是独立存在的xml文档<?xml version=”1.0” encoding=”编码表” standalone=”yes|no” ?>例如:<?xml version=”1.0”  encoding=”UTF-8” ?>在定义xml的文档声明时 <?之间不能有空白的内容        ?> 它们之间也不能有空格中间书写的属性使用空格隔开。

2.2、元素(标签)

xml中的标签也分成单标签和双标签。注意在xml所有的标签必须闭合。xml中的标签区别大小写。<a1>   <A1>表示2个不同的标签。xml中的标签可以嵌套,但是不能交差嵌套。<a1><b1></b1></a1><a1><b1></a1></b1>xml的标签只能有一个根标签。同时xml标签中的空白内容也会被解析成文本内容。<网址>www.itcast.cn</网址>标签不能以数字开始,不建议以下划线开始,同时在标签名中不要使用冒号。标签名可以是中文,但是一定指定能够识别中文的码表。但不建议书写中文。

2.3、属性

在定义标签的时候,可以在标签上书写属性,属性是由key和alue值组成。属性名书写的时候也遵守标签名的规则。属性值也不能以数字开始。属性和值之间使用=连接,属性值可以使用单引号也可以使用双引号。<user uid=”u001” name=”zhang’san”></user>另外:在xml技术中,标签属性所代表的信息,也可以改为用子元素的形式来描述,如:<input><type>text</type></input>

2.4、注释

xml中的注释和html注释相同。<!--  这里书写具体的注释内容  -->在eclipse中可以使用ctrl + shift + c 给每行添加注释,也可以使用ctrl + shift + /  添加注释  ctrl + shift + / 取消注释注释不能加在声明中及声明前。

2.5、文本和特殊字符

在编写XML文件时,有些内容可能不想让解析引擎解析执行,而是当作原始内容处理。遇到此种情况,可以把这些内容放在CDATA区里,对于CDATA区域内的内容,XML解析程序不会处理,而是直接原封不动的输出。语法:<![CDATA[ 内容 ]]>    <![CDATA[        <itcast>            <br/>        </itcast>    ]]>对于一些单个字符,若想显示其原始样式,也可以使用转义的形式予以处理。

 

2.6、特殊指令

处理指令,简称PI (processing instruction)。处理指令用来指挥解析引擎如何解析XML文档内容。例如,在XML文档中可以使用xml-stylesheet指令,通知XML解析引擎,应用CSS文件显示xml文档内容。    <?xml-stylesheet type="text/css" href="1.css"?>处理指令必须以“<?”作为开头,以“?>”作为结尾,XML声明语句就是最常见的一种处理指令。

2.7、xml语法规则总结:

所有xml元素必须有闭合标签;Xml标签区分大小写;Xml必须正确地嵌套顺序;Xml文档必须有根元素(且只有一个);Xml属性值须加引号特殊字符必须转义——CDATA;Xml中的空格、回车换行会被解析!

3、DTD约束xml

3.1、约束介绍

  由于xml的标签由用户自己定义,因此在开发的时候,每个人都可以根据自己的需求来定义xml标签,这样导致项目中的xml难以维护,因此需要使用一定的规范机制来约束xml文件中的标签书写。

3.2、DTD约束快速入门 

  第一步:先自己定义一个xml文件

<?xml version="1.0" encoding="UTF-8"?><users>    <user>        <name>zhangsan</name>        <age>23</age>        <addr>shanghai</addr>    </user>    <user>        <name>lisi</name>        <age>24</age>        <addr>beijing</addr>    </user></users>

  第二步:书写DTD文件来约束xml文件

  DTD文件在定义的时候,扩展名就是dtd。

  在xml文件中有多少个标签,就在dtd中书写多少个ELEMENT标签

<?xml version="1.0" encoding="UTF-8" ?><!ELEMENT users (user+) ><!ELEMENT user (name,age,addr) ><!ELEMENT name (#PCDATA) ><!ELEMENT age (#PCDATA)><!ELEMENT addr (#PCDATA)>

3.3、DTD引入方式

DTD主要用来约束xml文件,DTD可以单独写在文件中,也可以直接定义在xml中,可以在xml中引入第三方的公共DTD。外部DTD的引入方式:外部DTD主要指的一个独立的DTD文件。首先要书写DTD文件,然后在要被约束的xml文件中引入。<!DOCTYPE 文档根结点 SYSTEM "DTD文件的URL">文档根结点 指的是当前xml中的根标签。SYSTEM  引入的系统中存在文件"DTD文件的URL" DTD存放的位置引入公共的DTD:<!DOCTYPE 文档根结点 PUBLIC "DTD名称" "DTD文件的URL">文档根结点 指的是当前xml中的根标签。PUBLIC  表示当前引入的DTD是公共的DTD在xml中直接书写DTD<!DOCTYPE  根标签名 [具体的标签的约束]>
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE users[    <!ELEMENT users (user+) >        <!ELEMENT user (name,age,addr) >        <!ELEMENT name (#PCDATA) >        <!ELEMENT age (#PCDATA) >        <!ELEMENT addr (#PCDATA) >    ]><users>    <user>        <name>zhangsan</name>        <age>23</age>        <addr>shanghai</addr>    </user>    <user>        <name>lisi</name>        <age>24</age>        <addr>beijing</addr>    </user></users>

3.4、DTD的语法介绍

3.4.1、元素

当定义DTD约束xml时候,这时需要在DTD中使用ELEMENT来定义当前xml中可以出现的标签名称。格式:<!ELEMENT 标签名 约束>  约束来限定当前标签中可以有的子标签,或者当前标签中可以书写的内容在定义标签名的时候,约束中可以使用一些符号标签具体出现次数?    零次或者一次*  零次或者多次+    一次或者多次   users (user+)   表示当前的users标签下可以有一个或者多个user标签,   用来限定当前的子标签出现的顺序user (name,age,addr)  user标签下只能有name age addr 子标签,并且必须按照name  age  addr的顺序书写|  user (name|age,addr) user下可以name或者age ,但必须有addr,并且addr必须name或age后面#PCDATA        表明该元素可包含任何字符数据,但不能在其中包含任何子元素。只有 PCDATA 的元素通过圆括号中的 #PCDATA 进行声明EMPTY    表明该元素不能有任何子元素或文本,仅可以使用属性。ANY        表该元素中可以包含任何DTD中定义的元素内容 如:<!ELEMENT note ANY><!ELEMENT age EMPTY >  当前的age标签是个空标签,它不能有文本内容。

3.4.2、属性

在xml中的标签上是可以书写属性的,在DTD中就需要对属性进行约束。格式:<!ATTLIST 标签名 属性名 属性的类型  属性的约束>如果一个标签上有多个属性<!ATTLIST 标签名 属性名 属性的类型  属性的约束                                  属性名 属性的类型  属性的约束  属性名 属性的类型  属性的约束><标签名 属性1=””  属性2=””  属性3=”” >
属性的类型:CDATA  属性的value值可以是文本数据(值1 | 值2 | 值3....   )  表示当前的属性的value值只能是当前括号中的值ID 表示唯一。对当前标签上的id属性进行限定,并且同一个xml中id不能重复 类型    描述CDATA    值为字符数据 (character data)(en1|en2|..)    此值是枚举列表中的一个值ID    值为唯一的 idIDREF    值为另外一个元素的 idIDREFS    值为其他 id 的列表NMTOKEN    值为合法的 XML 名称NMTOKENS    值为合法的 XML 名称的列表ENTITY    值是一个实体ENTITIES    值是一个实体列表NOTATION    此值是符号的名称xml:    值是一个预定义的 XML 值
属性的约束:REQUIRED 属性是必须书写的Implied 属性是可选得#fixed value 属性的value是固定的值   “值”  代表属性的默认值user name CDATA  fixed “zhangsan”<user name=”zhangsan”>user name CDATA “张三”<user />
属性的类型和约束的组合:CDATA   REQUIREDCDATA   ImpliedCDATA   fixedCDATA  “值” (值1 | 值2 | 值3....   )  REQUIREDID   REQUIRED

3.4.3、实体

实体用于为一段内容创建一个别名,以后在XML文档中就可以使用别名引用这段内容了。在DTD定义中,一条<!ENTITY …>语句用于定义一个实体。实体可以理解成java中预先定义好的一个常量,然后xml文件中就可以引入当前这个定义的实体。
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE users[    <!ELEMENT users (user+) >        <!ELEMENT user (name,age,addr) >        <!ELEMENT name (#PCDATA) >        <!ELEMENT age EMPTY >        <!ELEMENT addr (#PCDATA) >        <!ATTLIST user id ID #REQUIRED >    <!ENTITY  abc "上海传智播客123123">]><users>    <user id="u001">        <name>zhangsan</name>        <age></age>        <addr>&abc;</addr>    </user>    <user id="u002">        <name>lisi</name>        <age/>        <addr>&abc;</addr>    </user></users>

4、Schema约束xml

4.1、xml Schema介绍

Schema它也来约束xml文件的,DTD在约束xml的时候一个xml中只能引入一个DTD,同时DTD它无法对属性以及标签中的数据做数据类型的限定。Schema它是用来代替DTD来约束xml。Schema文件本身就是使用xml文件书写的,同时它对需要约束的xml中的数据有严格的限定。学习Schema主要来学习W3C组织定义的如何在Schema中去约束xml的标签以及属性,还有属性的数据类型,以及标签中子标签的顺序。要定义一个Schema文件,这时它的扩展名必须是.xsd。在这个文件中根元素必须是schema。使用Schema来约束xml,Schema在书写的时候,只需要使用W3C组织提前定义的限定标签的,以及限定的属性的那个标签即可。

4.2、Schema快速入门

  第一步:书写xml文件

<?xml version="1.0" encoding="UTF-8"?><books>    <book>        <name>JavaWEB</name>        <author>老毕</author>        <price>182</price>    </book>    <book>        <name>SSH</name>        <author>老于</author>        <price>152</price>    </book></books>

  第二步:定义schema文件

在定义Schema文件的时候,由于这个Schema文件本身就是xml,它也要受到别的约束。而这个约束是W3C组织提前定义好的,在Schema文件中需要提前引入进来在根标签中使用属性进行进入:<schema  xmlns="http://www.w3.org/2001/XMLSchema"   引入W3C定义的schema书写的规范targetNamespace="http://www.itcast.org/book" 给当前的Schema文件起名字(命名空间)作用是当哪个xml要引入这个schema约束的时候,必须通过当前targetNamespace 后面书写的uri地址来引入
<?xml version="1.0" encoding="UTF-8"?><schema xmlns="http://www.w3.org/2001/XMLSchema"     targetNamespace="http://www.itcast.org/book"     elementFormDefault="qualified">    <element name="books">        <complexType>            <sequence>                <element name="book">                    <complexType>                        <sequence>                            <element name="name"></element>                            <element name="author"></element>                            <element name="price"></element>                        </sequence>                    </complexType>                </element>            </sequence>        </complexType>    </element></schema>

  第三步:在xml文件中引入当前的这个Schema

<books xmlns="http://www.itcast.org/book"   它是schema文件中的targetNamespace 属性后面的值        xsi:schemaLocation="http://www.itcast.org/book book.xsd"   这个是在引入当前的schema文件的真实路径        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   说明当前的xml是schema一个实例文档>

4.3、Schema的名称空间

在定义Schema文件的时候,需要在<schema>根标签中使用targetNamespace  属性定义当前schema定义名称(只是一个分配的名字,根本没有指向任何文件),在被约束的xml文件中先根据这个名称引入当前的schema文件,然后在使用xsi:schemaLocation=””    引入具体的schema文件。(因为targetNamespace属性定义的schema名称,只是一个名称而已,所以在xml文件中需要通过schemaLocation来声明指定所遵循的Schema文件的具体位置)(xsi:schemaLocation 使用它引入某个schema时,先要使用名称空间, 空格 ,文件名)名称空间主要功能是用于来elementFormDefault="qualified|unqualified"   在schema中书写qualified ,在限定xml中的定义的标签名必须使用定义的名称空间。unqualified 要求根元素必须使用名称空间,而子元素不能使用名称空间。

4.4、Schema中的标签解释

  Book2.xsd

<?xml version="1.0" encoding="UTF-8"?><schema xmlns="http://www.w3.org/2001/XMLSchema"     targetNamespace="http://www.itcast2.org/book"     elementFormDefault="qualified">    <element name="books">  <!--name代表当前的xml中可以书写标签名称  type数据类型-->        <complexType ><!-- complexType 当前的element声明的标签是复杂标签时 ,需要使用complexType来声明子标签-->            <sequence>  <!-- 复杂标签是指有属性,或者有子标签,或者有属性有子标签的标签                                 简单标签是指只有文本内容的标签                                <name>zhangsan</name>  简单标签                                <name id="u001"></name>  复杂标签                                sequence 代表当前子标签的顺序                            -->                <element name="book" maxOccurs="unbounded">                    <complexType mixed="true"><!—mixed属性值为true,book元素间就可以出现字符文本数据了-->                        <sequence>                            <element name="name"></element>                            <element name="author"></element>                            <element name="price" type="integer"></element>                            <any></any>                        </sequence>                    </complexType>                </element>            </sequence>        </complexType>    </element></schema>

  Name.xsd

<schema xmlns="http://www.w3.org/2001/XMLSchema"     targetNamespace="http://www.example.org/name"     elementFormDefault="qualified">    <element name="name"></element></schema>

  Book2.xml

<?xml version="1.0" encoding="UTF-8"?><aa:books xmlns:aa="http://www.itcast2.org/book"    xmlns:bb="http://www.example.org/name"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://www.itcast2.org/book book2.xsd                         http://www.example.org/name name.xsd"    >    <aa:book>        aa:sjdlkfjlkdsjflk            <aa:name >JavaWEB</aa:name>        <aa:author >老毕</aa:author>        <aa:price>182</aa:price>        <bb:name>sdgs</bb:name>    </aa:book></aa:books>

5、DOM解析xml

5.1、Java中的解析技术介绍

w3c组织在定义xml的时候,就规范了如何去解析xml文件,其中就定义了使用dom技术来解析xml文件。DOM:Document Object Medel。文档对象模型。w3c给出的dom解析,第一步是先把整个xml文件加载到内存,然后在内存中形成了一颗dom树。特点:    一次将所有数据全部加载到内存中;    对xml文档中每个节点都当成一个Node对象处理。包括元素、文本、属性。    缺点就是当文档数据量很大时,对内存有占用很大,所以不适合解析大量的数据。

5.2、DOM解析

  Xml文档的属性结构

DOM解析是把整个xml文档加载到内存中,然后形成一个dom树,这样就可以获取树中的所有标签,属性,文本内容。Java实现了相应的dom解析技术:  使用Java提供的Dom技术来解析xml文件    DocumentBuilderFactory:这个是一个工厂类,主要负责生产一个解析xml的解析器对象      newDocumentBuilder()静态方法可以获取到一个用于解析xml的解析器对象          DocumentBuilderFactory.newDocumentBuilder();          获取到了DocumentBuilder对象    DocumentBuilder 这个类可以从xml中获得DOM对象          使用parse方法解析一个文件路径,就可以得到当前xml文件对象  解析xml文件首先要获取到xml文件对象即就是Document对象

5.3、DOM获取节点、属性、文本数据

// 获取DOM标签的信息    @Test    public void get() throws Exception {        // 获取工厂实例对象        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();        // 获取解析器对象        DocumentBuilder db = dbf.newDocumentBuilder();        // 解析xml获取dom对象        Document dom = db.parse("book.xml");        // 获取根元素:        Node node = dom.getFirstChild();        // 获取标签的名字        System.out.println(node.getNodeName());        // 获取到每个标签对象,都是一个element的实例对象        Element root = (Element) node;        // 获取books下面的所有book标签        NodeList nl = root.getElementsByTagName("book");        for (int i = 0; i < nl.getLength(); i++) {            // 获取到每个book标签对象            Element book = (Element) nl.item(i);            // NodeList book_child = book.getChildNodes();            Element name = (Element) book.getElementsByTagName("name").item(0);            Element author = (Element) book.getElementsByTagName("author")                    .item(0);            Element price = (Element) book.getElementsByTagName("price")                    .item(0);            // 获取name标签下的文本值            System.out.println(name.getTextContent());            // 获取标签上的属性值            System.out.println(name.getAttribute("id"));            // 获取author标签下的文本值            System.out.println(author.getTextContent());            // 获取price标签下的文本值            System.out.println(price.getTextContent());            System.out.println("-------------------");        }    }

5.4、修改xml中的数据

/*     * 修改dom中标签的信息     * 把books中的第二个book标签中的price的值改为100     *      */    @Test    public void update() throws Exception {        // 获取工厂实例对象        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();        // 获取解析器对象        DocumentBuilder db = dbf.newDocumentBuilder();        // 解析xml获取dom对象        Document dom = db.parse("book.xml");        //使用dom树直接根据标签名获取对应的标签对象        Element book = (Element) dom.getElementsByTagName("book").item(1);        //获取price标签        Element price = (Element) book.getElementsByTagName("price").item(0);        price.setTextContent("100");        System.out.println(price.getTextContent());                //把修改的整个dom树重新写到文件中        TransformerFactory tff = TransformerFactory.newInstance();        //获取转换器        Transformer transformer = tff.newTransformer();        //和文件关联出去结果对象        StreamResult sr = new StreamResult("book.xml");        //把dom转成原始数据对象        DOMSource ds = new  DOMSource(dom);        //保存数据        transformer.transform(ds, sr);    }

当要把修改后的xml中的数据保存到xml中需要使用Transformer 类中的transform方法

 TransformerFactory这个工厂负责生产一个把dom树写到文件中的对象

 Transformer 负责把一个dom写到文件中。

总结:

Java提供的dom操作方式:

第一步:需要获取到相应的工厂

第二步:根据工厂获取相应的工具或者解析器对象

第三步:根据解析器获取dom对象,再操作dom树中的节点,或者是获取到相应的工具,然后使用工具对dom树进行保存等操作


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表