XML
1.XML和DTD以及Schema 一、XML的简介 XML是指可扩展的标记语言,它是一种标记语言,很类似于HTML。它被设计的宗旨是传输数据,而非显示数据。 XML标签没有被预定义,需要用户自行定义标签。 XML技术是W3C组织发布的,目前遵循的是W3C组织于2000年发布的XML1.0规范。 XML被广泛认为是继Java之后再Internet上最激动人心的新技术。 二、XML技术用于解决什么问题? 在现实生活中存在大量有关系的数据,如下图所示。 问题:这样的数据该如何表示并交给计算机处理呢? XML语言出现的根本目的在于描述如上图所示那种有关系的数据。 XML是一种通用的数据交换格式。 在XML语言中,它允许用户自定义标签。一个标签用于描述一段数据;一个标签可分为开始标签和结束标签,在起始标签之间,又可以使用其他标签描述其他数据,一次来是你先数据关系的描述。 XML中的数据必须通过软件程序来解析执行或显示,如IE等;这样的继续程序称之为Parser(解析器)。 <?xmlversion="1.0"encoding="UTF-8"?> <中国> <北京> <海淀></海淀> <丰台></丰台> </北京> <山东> <济南></济南> <青岛></青岛> </山东> <湖北> <武汉></武汉> <荆州></荆州> </湖北> </中国> 三、XML常见应用 XML技术除了用于保存有关系的数据之外,它还经常用作软件的配置文件,以描述程序模块之间的关系。 在一个软件系统中,通过XML配置文件可以提高系统的灵活性。即程序的行为是通过XML文件来配置的,而不是硬编码。 数据交换:不同语言之间用来交换数据。 四、XML的语法 一个XML文件分为如下几部分内容: 文档声明 元素 属性 注释 CDATA字节、特殊字符 处理指令(没用) 五、XML语法之文档声明 在编写xml文档的时候,需要先使用文档声明来声明此文件是一个XML文档,并且必须出现在文档的第一行,并且必须指定。 最简单的语法<?xml version="1.0"?> 用encoding属性说明文档所使用的字符编码。保存在磁盘上的文件编码要与声明的编码一致。如:<?xml version="1.0" encoding="utf-8"?> 用standalone属性说明此文档是否独立,即是否依赖其他文档。如:<?xml version="1.0" standalone="yes" ?>,其中yes表示不引用外部的文件,no表示需要引用。(不常用)。 <?xmlversion="1.0"encoding="UTF-8"?> <中国> <北京> <海淀></海淀> <丰台></丰台> </北京> <山东> <济南></济南> <青岛></青岛> </山东> <湖北> <武汉></武汉> <荆州></荆州> </湖北> </中国> 六、xml语法之元素 xml元素指xml文件中出现的标签。一个标签分为起始和结束标签(不能省略)。一个标签有如下几种书写形式 包含标签主体:<tag>content</tag> 不含标签主体:<tag/> 一个标签中可以嵌套若干子标签,但所有标签必须合理的嵌套,不允许有交叉嵌套。 一个xml文档必须有且仅有一个根标签,其他标签都是这个根标签的子标签或后代标签。 对于xml标签中出现的所有空格和换行,xml解析程序都会当做标签内容进行处理。例如:下面两段内容的意义是不一样的。 第一段: <网址>http://www.baidu.com/</网址> 第二段: <网址> http://www.baidu.com/ </网址> 由于在xml中,空格和换行都作为原始内容被处理,所以,在编写xml文件时,使用换行和缩进等方式让源文件中的内容清晰可读的“良好”书写习惯可能要被迫改变。 一个xml元素可以包含字母、数字以及其他一些可见字符,但必须遵守下面的一些规范: 区分大小写。 不能以数字或“-”开头。 不能以xml开头。 不能包含空格。 名称中间不能包含冒号。 七、xml语法之属性 一个元素可以有多个属性,每个属性都有他自己的名称和取值。 属性值一定要用引号(单引号或双引号)引起来。 属性名称的命名规范和元素的命名规范相同。 元素中的属性是不允许重复的。 在xml技术中,标签属性所代表的信息也可以被改成用子元素的形式来描述。 八、xml语法之注释 xml中的注释语法为:<!-- 这是注释 --> 注意注释是不能嵌套的。 九、xml语法之转义字符 对于一些单个字符,若想显示其原始样式,也可以使用转义的形式予以处理。
十、xml语法之CDATA区 CDATA区是Character Data的缩写。 作用:把标签当做普通文本内容。 语法: <![CDATA[内容]]> 十一、xml语法之处理指定(没用) 处理指定,简称PI。 作用:用来指挥软件如何解析xml文档。 语法:必须以“<?”开头,以“?>”结尾。 常用处理指令: xml声明: <?xmlversion="1.0"encoding="utf-8"?> xml-stylesheet指令: 作用:指示xml文档所使用的css样式xsl。 <?xml-stylesheettype="text/css"href="#css的地址"?> 十二、xml语法规则总结 所有xml元素都必须有关闭标签。 xml标签对大小写敏感。 xml必须正确的嵌套。 xml文档必须有且仅有一个根元素。 xml的属性值必须加引号。 特殊字符必须转义。 xml中的空格、回车换行解析时会被保留。 十三、xml约束之DTD的起源 为什么需要约束?? xml都是用户自定义的标签,如果出现小小的错误,软件程序将不能正确的获取文件中的内容而报错。(如Tomcat等) xml技术中,可以编写一个文档来约束一个xml的书写规范,这个文档称之为约束。 两个概念: 格式良好的xml: 遵循xml语法的xml。 有效的xml:遵循约束文档的xml。 总之:约束文档定义了在xml中允许出现的元素名称、属性及元素出现的顺序等等。 十四、xml约束概述 什么是xml约束? 在xml技术里面,可以编写一个文档来约束一个xml文档的书写规范,称为xml约束。 常用的约束技术? xml DTD xml Schema 十五、DTD快速入门 book.dtd <?xmlversion="1.0"encoding="UTF-8"?> <!ELEMENT书架(书+)> <!ELEMENT书(书名,作者,售价,简介)> <!ELEMENT书名(#PCDATA)> <!ELEMENT作者(#PCDATA)> <!ELEMENT售价(#PCDATA)> <!ELEMENT简介(#PCDATA)> book.xml <?xmlversion="1.0"encoding="UTF-8"?> <!DOCTYPE书架SYSTEM"book.dtd"> <书架> <书> <书名>javaweb开发大全</书名> <作者>王二</作者> <售价>79.9</售价> <简介>这非常不错哦</简介> </书> </书架> 快速入门的步骤: 需要出现哪些标签? 在DTD的文件中编写元素 <!ELEMENT 元素名称 元素类型> 判断元素是否是简单还是复杂元素? 如果是简单元素:(#PCDATA) 代表的是字符串 如果是复杂元素:(子节点) 需要在book.xml引入DTD的文件 <!DOCTYPE 根节点 SYSTEM "DTD文件的地址"> 十六、DTD与xml文档关联的三种方式 DTD约束即可以作为一个单独的文件编写,也可以在XML文件内编写 使用内部DTD <!DOCTYPE 根节点 [DTD的代码]> 使用外部DTD <!DOCTYPE 根节点 SYSTEM "DTD的地址"> 使用网络DTD <!DOCTYPE 根节点 PUBLIC "DTD的名称" "DTD的地址"> 十七、DTD之定义元素 在DTD文档中使用ELEMENT关键字来声明一个XML元素。 语法:<!ELEMENT 元素名称 使用规则> 使用规则: (#PCDATA):指示元素的主体内容只能是普通的文本。 EMPTY:用于指示元素的主体内容为空。比如<br/> ANY:用于指示元素的主体内容为任意类型。 (子元素):用于指示元素中包含的子元素。 定义子元素及描述它们的关系: 如果子元素用逗号隔开,说明必须按照声明顺序去编写XML文档。 <!ELEMENT FILE (TITLE,AUTHOR,EMAIL) 如果子元素用“|”隔开,则说明任选其一。 <!ELEMENT FILE (TITLE|AUTHOR|EMAIL) 用+、*、?来表示元素出现的次数 如果元素后面没有+、*、?,表示必须且出现一次。 +:表示至少出现一次,一次或多次。 *:表示可有可无,零次、一次或多次。 ?:表示可以有也可以无,有的话只能有一次,零次或一次。 十八、DTD之定义属性 属性(ATTLIST)定义 <!ATTLIST 元素名称 属性名 属性类型 约束 属性名 属性类型 约束 …… > 属性声明举例: <!ATTLIST商品 类别CDATA#REQUIRED 颜色CDATA#IMPLIED > 对应的xml为: <商品类别="服装"颜色="黄色"/> 属性值类型: CDATA:表示属性的取值为普通的文本字符串。 ENUMERATED(DTD没有此关键字):表示枚举,只能从枚举列表中任选其一,如(鸡肉|牛肉|猪肉)。 ID:表示属性的取值不能重复(不能只写数字)。 设置说明: #REQUIRED:表示该属性必须出现。 #IMPLIED:表示该属性可有可无。 #FIXED:表示该属性的取值为一个固定值。语法::#FILED “固定值” 直接值:表示属性的取值为该默认值。 十九、DTD之定义实体(没用) 实体用于为一段内容创建一个别名,以后在xml文档中就可以使用别名引用这段内容了。 在DTD定义中,一条<!ENTITY 别名 “值”>语句用于定义一个实体。 在元素中引用 &别名; DTD中定义: <!ENTITYcopyright"版权所有,翻版必究"> xml中引用: ©right; 二十、XML Schema简介 XML Schema也是一种用于定义和描述XML文档结构和内容的模式语言,其出现是为了克服DTD的局限性。 XML Schema是用一套预先规定的XML元素和属性创建的,这些元素和属性定义了XML文档的结构和内容模式。XML Schema规定XML文档实例的结构和每个元素/属性的数据类型。 Schema相对于DTD的明显好处就是,XML Schema文档本身也是XML文档,而不像DTD一样使用自成一体的语法。 二十一、XML Schema的一些概念 XML Schema文件自身就是一个XML文件,但它的扩展名通过为.xsd。 和XML文件一样,一个XML Schema文档也必须有一个根节点,并且这个根节点必须是schema。 应用schema约束 开发xml过程 编写一个XML Schema约束文档后,通常需要把这个文件中声明的元素绑定到一个URI的地址上,这个URI地址叫namespace名称空间,以后XML文件就可以通过这个URI(即名称空间)引用半丁指定名称空间的元素。 二十二、Schema入门 首先在src目录下编写一个book.xml <?xmlversion="1.0"encoding="UTF-8"standalone="no"?> <书架> <书> <书名>javaweb开发大全</书名> <作者>王二</作者> <售价>79.9</售价> <简介>这非常不错哦</简介> </书> </书架> 在src目录下编写一个book.xsd的schema文件 <?xmlversion="1.0"encoding="UTF-8"?> <!-- *引入W3C的名称 *在根节点上,使用属性xmlns(xmlnamespace) *xmlns="http://www.w3.org/2001/XMLSchema" *定义元素 *<elementname="书架"></element> *判断是否是复杂还是简单的元素 *如果是简单 在element有属性 type="数据的类型" *如果是复杂 *声明标签是复杂的元素 <complexType> *子元素之间的关系 <sequence> *起名:targetNamespace 目标名称空间(起名) *值是任意的:http://www.example.org/book *elementFormDefault : *qualified(使用) :质量好的 *unqualified :质量不好的 *编写属性 *<attributename="出版社"type="string"use="required"></attribute> *name 属性名称 *type 属性类型 *user 属性约束 --> <schemaxmlns="http://www.w3.org/2001/XMLSchema"targetNamespace="http://www.example.org/book"elementFormDefault="qualified"> <!--复杂元素--> <elementname="书架"> <!--复杂元素--> <complexType> <!--有顺序的--> <sequencemaxOccurs="unbounded"> <elementname="书"> <!--复杂的元素--> <complexType> <!--有顺序的--> <sequence> <!--简单元素--> <elementname="书名"type="string"></element> <elementname="作者"type="string"></element> <elementname="售价"type="double"></element> <elementname="简介"type="string"></element> </sequence> <!--书的属性--> <attributename="出版社"type="string"use="required"></attribute> </complexType> </element> </sequence> </complexType> </element> </schema> 最后在book.xml中修改一下,如下所示 <?xmlversion="1.0"encoding="UTF-8"standalone="no"?> <!-- *引入W3C名称空间,我是实例文档。 *xmlns="http://www.w3.org/2001/XMLSchema-instance" *引入自己编写的schema的文档 *xmlns="http://www.itcast.cn/1110" *问题:元素上不能有相同的属性名称 *解决:起别名 :aa *技巧:在下面出现标签的概率小起别名 *引入自己编写的schema文档的地址 *schemaLocation属性是W3C提供的,如果W3C名称空间要是有别名的话,先把别名写上。 xsi:schemaLocation="名称空间schema文件的地址" --> <书架xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://www.example.org/book"xsi:schemaLocation="http://www.example.org/bookbook.xsd"> <书> <书名>javaweb开发大全</书名> <作者>王二</作者> <售价>79.9</售价> <简介>这非常不错哦</简介> </书> </书架> 二十三、Schema入门总结 2.xml编程 一、xml解析技术概述 XML解析方式分为两种:DOM方式和SAX方式 DOM:文档对象模型(Document Object Model)。这种方式是W3C推荐的处理XML的一种方式。 SAX:Simple API for XML。这种方式不是官方标准,属于开源社区,几乎所有的XML解析器都支持它。 XML解析开发工具包: JAXP(Java API for XML Processing):是SUN公司推出的解析标准实现。 DOM4j:是开源组织推出的解析开发工具包。(很多公司、框架都使用它) JDom:是开源组织推出的解析开发工具包。 二、JAXP JAXP(Java API for XML Processing)开发工具包是JavaSE的一部分,它由以下几个包及其子包组成: org.w3c.dom:提供DOM方式解析XML的标准接口 org.xml.sax:提供SAX方式解析XML的标准接口 javax.xml:提供了解析XML文档的类 javax.xml.Parsers包中,定义了几个工厂类。我们可以通过调用这些工厂类,得到对XML文档进行解析的DOM和SAX解析器对象。 DocumentBuilderFactory SAXParserFactory javax.xml.parsers包中的DocumentBuilderFactory用于创建DOM模式的解析器对象,DocumentBuilderFactory是一个抽象工厂类,它不能直接实例化,但该类提供了一个newInstance()方法,这个方法会根据本地平台默认安装的解析器,自动创建一个工厂的对象并返回。 所以,获得JAXP中的DOM的解析器的步骤如下: 1)调用DocumentBuilderFactory.newInstance()方法得到创建DOM解析器的工厂。 2)调用工厂对象的newDocumentBuilder()方法得到DOM解析器对象。 3)调用DOM解析器对象的parse()方法解析XML文档,得到代表整个文档的Document对象,进而可以利用DOM特性对整个XML文档进行操作了。 DOM编程: DOM解析器在解析XML文档时候,会把文档中的所有元素,按照其出现的层次关系,解析成一个个Node对象(节点)。 在DOM中,节点之间关系如下: 位于一个节点之上的节点是该节点的父节点(parent)。 一个节点之下的节点是该节点的子节点(children)。 同一层次,具有相同父节点的节点是兄弟节点(sibing)。 一个节点的下一个层次的节点集合是节点后代(descendant)。 父、祖父节点及所有位于节点上面的,都是该节点的祖先(ancestor)。 Node对象: Node对象提供了一系列常量来代表节点的类型,当开发人员互殴的某个类型Node类型后,就可以把Node节点转换成相应的节点对象(Node的子类对象),以便于调用其特有的方法。 Node对象提供了相应的方法去获得它的父节点或子节点。编程人员通过这些方法就可以读取整个XML文档的内容,进行增加、修改、删除XML文档的内容了。 示例:DOM解析XML 在src下新建一个book.xml文件 <?xmlversion="1.0"encoding="UTF-8"?> <书架> <书出版社="机械出版社"> <书名>javaweb开发大全</书名> <作者>王二</作者> <售价>79.9</售价> <简介>这非常不错哦</简介> </书> <书出版社="清华出版社"> <书名>javaSE开发大全</书名> <作者>李四</作者> <售价>99.9</售价> <简介>很好</简介> </书> </书架> 在src下新建JAXPDomTest类 packagecn.jaxp; importjavax.xml.parsers.DocumentBuilder; importjavax.xml.parsers.DocumentBuilderFactory; importorg.w3c.dom.Document; importorg.w3c.dom.Node; importorg.w3c.dom.NodeList; /** *JAXP的DOM解析XML */ publicclassJAXPDomTest{ publicstaticvoidmain(String[]args)throwsException{ run(); } /** *获取作者的文本内容 *@throwsException */ publicstaticvoidrun()throwsException{ //获取解析器工厂类 DocumentBuilderFactorybuilderFactory=DocumentBuilderFactory.newInstance(); //获得解析器对象 DocumentBuilderbuilder=builderFactory.newDocumentBuilder(); //解析XML的文档,返回Document对象 Documentdocument=builder.parse("src/book.xml"); //获取作者元素的对象集合,返回NodeList NodeListnodeList=document.getElementsByTagName("作者"); //遍历NodeList集合,拿到每一个作者,打印文本的内容 for(intx=0;x<nodeList.getLength();x++){ Nodenode=nodeList.item(x); System.out.println(node.getTextContent());; } } } 示例:修改xml文件 更新xml文档 javax.xml.transform包中的Transformer类用于把代表XML文件的Document对象转换为某种格式后进行输出。 Transformer类通过transform方法完成转换操作,该方法接收一个源和一个目的地。我们可以通过: javax.xml.transform.dom.DomSource类来关联要转换的document对象。 用javax.xml.transform.stream.StreamResult对象来表示数据的目的地。 Transformer对象通过TransformerFactory获得。 修改之前的xml文件 <?xmlversion="1.0"encoding="UTF-8"standalone="no"?><书架> <书出版社="机械出版社"> <书名>javaweb开发大全</书名> <作者>王二</作者> <售价>79.9</售价> <简介>这非常不错哦</简介> </书> <书出版社="清华出版社"> <书名>javaSE开发大全</书名> <作者>李四</作者> <售价>99.9</售价> <简介>很好</简介> </书> </书架> packagecn.jaxp; importjavax.xml.parsers.DocumentBuilder; importjavax.xml.parsers.DocumentBuilderFactory; importjavax.xml.transform.Transformer; importjavax.xml.transform.TransformerFactory; importjavax.xml.transform.dom.DOMSource; importjavax.xml.transform.stream.StreamResult; importorg.w3c.dom.Document; importorg.w3c.dom.Element; importorg.w3c.dom.Node; importorg.w3c.dom.NodeList; /** *JAXP的DOM解析XML */ publicclassJAXPDomTest{ publicstaticvoidmain(String[]args)throwsException{ /*run();*/ run2(); } /** *获取作者的文本内容 *@throwsException */ publicstaticvoidrun()throwsException{ //获取解析器工厂类 DocumentBuilderFactorybuilderFactory=DocumentBuilderFactory.newInstance(); //获得解析器对象 DocumentBuilderbuilder=builderFactory.newDocumentBuilder(); //解析XML的文档,返回Document对象 Documentdocument=builder.parse("src/book.xml"); //获取作者元素的对象集合,返回NodeList NodeListnodeList=document.getElementsByTagName("作者"); //遍历NodeList集合,拿到每一个作者,打印文本的内容 for(intx=0;x<nodeList.getLength();x++){ Nodenode=nodeList.item(x); System.out.println(node.getTextContent());; } } /** *在第二本下,载末尾添加子节点 */ publicstaticvoidrun2()throwsException{ //获得工厂类 DocumentBuilderFactorybuilderFactory=DocumentBuilderFactory.newInstance(); //获得解析器 DocumentBuilderbuilder=builderFactory.newDocumentBuilder(); //解析xml,返回Document对象 Documentdocument=builder.parse("src/book.xml"); //获取第二本书 Nodebook2=document.getElementsByTagName("书").item(1); //创建元素对象 Elementelement=document.createElement("哈哈"); //设置文本内容 element.setTextContent("哈哈还是呵呵"); //把元素对象添加到第二本书下 book2.appendChild(element); //回写 TransformerFactorytransformerFactory=TransformerFactory.newInstance(); Transformertransformer=transformerFactory.newTransformer(); transformer.transform(newDOMSource(document),newStreamResult("src/book.xml")); } } 修改之后的xml文件 <?xmlversion="1.0"encoding="UTF-8"standalone="no"?><书架> <书出版社="机械出版社"> <书名>javaweb开发大全</书名> <作者>王二</作者> <售价>79.9</售价> <简介>这非常不错哦</简介> </书> <书出版社="清华出版社"> <书名>javaSE开发大全</书名> <作者>李四</作者> <售价>99.9</售价> <简介>很好</简介> <哈哈>哈哈还是呵呵</哈哈></书> </书架> SAX解析 在使用DOM解析XML文档的时候,需要读取整个XML文档,在你内存构成代表整个DOM树的Document的对象,从而再对XML文档进行操作,此种情况下,如果XML文档特别大,就会消耗计算机的大量内存,并且容易导致内存溢出。 SAX解析允许在读取文档的时候,即对文档进行处理,而不必等到整个文档装载完才能进行操作。 SAX采用事件处理的方式解析XML文件,利用SAX解析XML文档,设计两个部分:解析器和事件处理器。 解析器可以使用JAXP的API创建,创建出SAX解析器后,就 可以指定解析器去解析某个XML文档。 解析器采用SAX方式在解析某个XML文档的时候,它只要解析到XML文档的一个组成部分,都会去调用事件处理器的一个方法,解析器在调用事件处理器的方法时,会把当前解析到的xml文件内容作为方法的参数传递给事件处理器。 事件处理器由程序员编写,程序员通过事件处理器中方法的参数,就可以很轻松的得到SAX解析器解析到的数据,从而可以决定如何对数据进行处理。 SAX解析原理 SAX是事件驱动的XML处理方法。 它是基于事件驱动的。 startElement()回调在每次SAX解析器遇到元素的起始标记时被调用。 characters()回调为字符数据所调用。 endElement()为元素的结束标记所调用。 DefaultHandler类来实现所有这些回调,并提供所有回调方法默认的空实现。 使用SAX方式解析XML 使用SAXParserFactory创建SAX解析工厂 SAXParserFactory factory =SAXParserFactory.newInstance(); 通过SAX解析工厂得到的解析器对象 SAXParser sp = factory.newSAXParser(); 通过解析器对象解析xml文件 sp.parse("book.xml",new XMLContentHandler()); 这里的XMLContentHandler()继续DefaultHandler。 packagecn.jaxp; importjavax.xml.parsers.ParserConfigurationException; importjavax.xml.parsers.SAXParser; importjavax.xml.parsers.SAXParserFactory; importorg.xml.sax.Attributes; importorg.xml.sax.SAXException; importorg.xml.sax.helpers.DefaultHandler; classMyHandlerextendsDefaultHandler{ @Override publicvoidstartElement(Stringuri,StringlocalName,StringqName,Attributesattributes)throwsSAXException{ System.out.println("开始文档:"+qName); } @Override publicvoidcharacters(char[]ch,intstart,intlength) throwsSAXException{ System.out.println(newString(ch,start,length)); } @Override publicvoidendElement(Stringuri,StringqName) throwsSAXException{ System.out.println("结束文档:"+qName); } } publicclassJAXPSAXTest{ publicstaticvoidmain(String[]args)throwsException,SAXException{ SAXParserFactoryfactory=SAXParserFactory.newInstance(); SAXParsersaxParser=factory.newSAXParser(); saxParser.parse("src/book.xml",newMyHandler()); } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |