码迷,mamicode.com
首页 > 其他好文 > 详细

XML

时间:2015-04-06 20:22:20      阅读:122      评论:0      收藏:0      [点我收藏+]

标签:xml   dtd   schema   sax   

一、概述
	XML是一种通用的数据交换格式。
	XML中的数据必须通过软件程序来解析执行或显示,如IE;这样的解析程序称之为Parser(解析器)。

二、基本语法
	1、文档声明:
		作用:用于标识该文档是一个XML文档。
		注意事项:声明必须出现在文档的第一行(之前连空行都不能有,也不能有任何的注释)

		最简单的XML声明:<?xml version="1.0"?>
		声明中的encoding属性:说明解析当前XML文档时所使用的编码。默认是UTF-8
		声明中的standalone属性:说明XML文档是否是独立的。
	2、元素
		结束标签不能省略
		一个XML文档必须且只能有一个根标签
		XML文档中不会忽略回车和换行及空格!
		标签的命名规范:元素(标签)的名称可以包含字母、数字、减号、下划线和英文句点,严格区分大小写;
						只能以字母或下划线开头,且不能以xml(或XML、Xml等)开头----W3C保留日后使用;

	3、元素的属性
		元素的属性取值一定要用引号引起来(单引号或双引号)

	4、注释
		与HTML中的注释完全一致:<!--这是注释--> 注意:注释不能嵌套

	5、CDATA区
		CDATA是Character Data的缩写。
		作用:CDATA区中的东东(可以包含标签和特殊字符)都是文本。
		语法:
			<![CDATA[
			
					文本内容
					
					]]>
		6、特殊字符
		&		&
		<		<   (less than)
		>		>	(great than)
		"		"
		'		'

	7、处理指令(PI:Processing Instruction)
		处理指令,简称PI(Processing Instruction)。
		作用:用来指挥软件如何解析XML文档。
		语法:必须以"<?"作为开头,以"?>"作为结尾。
		
		常用处理指令:
		XML声明:<?xml version="1.0" encoding="GB2312"?>
		xml-stylesheet指令:<?xml-stylesheet type="text/css" href="some.css"?>
			作用:指示XML文档所使用的CSS样式XSL。注:对中文命名的标签元素不起作用

三、XML的约束
	1、格式良好的XML文档:符合XML语法的。
	2、有效的XML文档:遵循约束规范的。
	格式良好的不一定是有效的,但有效的必定格式良好。

四、DTD的基本语法	
	1、DTD:Document Type Definition
	2、作用:约束XML的书写规范。
	3、DTD文件保存到磁盘时,必须使用UTF-8编码!
	4、引入外部的DTD文档来约束当前的XML文档的方法
		DTD文件在本地:<!DOCTYPE 根元素名称 SYSTEM "DTD文件的路径">
		DTD文件在网络上:<!DOCTYPE 根元素名称 PUBLIC "DTD名称" "DTD的路径URL">
	5、DTD的语法细节
		5.1定义元素
			语法:<!ELEMENT 元素名称 使用规则>
			使用规则:
				(#PCDATA):指示元素的主体内容只能是普通的文本.(Parsed Character Data)
				EMPTY:指示元素的不能有主体内容。
				ANY:用于指示元素的主体内容为任意类型
				(子元素):指示元素中包含的子元素
						如果子元素用逗号分开,说明必须按照声明顺序去编写XML文档
						如果子元素用“|”分开,说明任选其一。
						用+、*、?来表示元素出现的次数
		5.2定义元素的属性(attribute)
			语法:<!ATTLIST 哪个元素的属性
							属性名1 属性值类型 设置说明
							属性名2 属性值类型 设置说明>
				属性值类型:
					CDATA:说明该属性的取值为一个普通文本
					ENUMERATED (DTD没有此关键字):
						语法:<!ATTLIST 元素名称 (值1|值2) "值1">
					ID:属性的取值不能重复
				设置说明:
					#REQUIRED:表示该属性必须出现
					#IMPLIED:属性可有可无
					#FIXED:表示属性的取值为一个固定值 语法:#FIXED "固定值"
					直接值:表示属性的取值为该默认值
		5.2定义实体(相当于定义别名)
			关键字ENTITY
			实体的定义分为引用实体和参数实体
			引用实体:
				作用:在DTD中定义,在XML中使用
				语法:<!ENTITY 实体名称 "实体内容">
				在XML中使用:&实体名称;
			参数实体:
				作用:在DTD中定义,在DTD中使用
				语法:<!ENTITY % 实体名称 "实体内容">
				在DTD中使用:%实体名称;
五、XML解析方式
	1、常用XML的解析方式:DOM和SAX
		DOM:Document Object Model是W3C推荐使用的解析方式
		
		SAX:Simple API for XML。非官方标准。
			SAX采用事件处理的方式解析XML文件,利用 SAX 解析 XML 文档,涉及两个部分:解析器和事件处理器:
			1)解析器可以使用JAXP的API创建,创建出SAX解析器后,就可以指定解析器去解析某个XML文档。
			2)解析器采用SAX方式在解析某个XML文档时,它只要解析到XML文档的一个组成部分(文档的开始,元素的开始、文本、元素的结束、文档的结束),都会去调用事件处理器的一个对应的方法,解析器在调用事件处理器的方法时,会把当前解析到的xml文件内容作为方法的参数传递给事件处理器。
			3)事件处理器由程序员编写,程序员通过事件处理器中方法的参数,就可以很轻松地得到sax解析器解析到的数据,从而可以决定如何对数据进行处理。
			
		*****重要区别:
		DOM解析:需要读取整个 XML 文档,在内存中构架代表整个 DOM 树的Doucment对象,从而再对XML文档进行操作。此种情况下,如果 XML 文档特别大,就会消耗计算机的大量内存,并且容易导致内存溢出。
		SAX解析:允许在读取文档的时候,即对文档进行处理,而不必等到整个文档装载完才会文档进行操作。
		
	2、常用的XML解析开发包:
		JAXP:SUN推出的实现,能进行DOM和SAX方式解析
			JAXP:(Java API for XML Processing)开发包是JavaSE的一部分,它由以下几个包及其子包组成:
				org.w3c.dom:提供DOM方式解析XML的标准接口
				org.xml.sax:提供SAX方式解析XML的标准接口
				javax.xml:提供了解析XML文档的类
				
			javax.xml.parsers包中,定义了几个工厂类 DocumentBuilderFactory、SAXParserFactory。我们可以通过调用这些工厂类,得到对XML文档进行解析的DOM和SAX解析器对象。
				
				JAXP DOM解析
					调用 DocumentBuilderFactory.newInstance() 方法得到创建 DOM 解析器的工厂
					DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
					调用工厂对象的 newDocumentBuilder方法得到 DOM 解析器对象。
					DocumentBuilder builder = factory.newDocumentBuilder();
					调用 DOM 解析器对象的 parse() 方法解析 XML 文档,得到代表整个文档的 Document 对象,进行可以利用DOM特性对整个XML文档进行操作了。
					Document document = builder.parse("books.xml");  //指java项目的根路径下的文件
					
					更新XML文档
					javax.xml.transform包中的Transformer类用于把代表XML文件的Document对象转换为某种格式后进行输出
			
					//获得持久化对象实例工厂
					TransformerFactory factory = TransformerFactory.newInstance();
					//获得持久化对象
					Transformer transformer = factory.newTransformer();
					//将内存数据,保存到硬盘
					//源:document  将document封装到Source
					Source xmlSource = new DOMSource(document);
					//结果:books.jasp.xml  将“文件路径”封装到Result
					Result outputTarget = new StreamResult("books.jasp.xml");
					transformer.transform(xmlSource, outputTarget);
					
					即:
					//把内存中Documeng树写回XML文件中
					TransformerFactory facotry = TransformerFactory.newInstance();
					Transformer ts = facotry.newTransformer();
					ts.transform(new DOMSource(document), new StreamResult("src/book.xml"));
					
				JAXP SAX解析
					使用SAXParserFactory创建SAX解析工厂
					SAXParserFactory spf = SAXParserFactory.newInstance();
					通过SAX解析工厂得到解析器对象		
					SAXParser sp = spf.newSAXParser();
					通过解析器对象得到一个XML的读取器
					XMLReader xmlReader = sp.getXMLReader();
					设置读取器的事件处理器		
					xmlReader.setContentHandler(new BookParserHandler());
					解析xml文件	
					xmlReader.parse("book.xml");
					
					JAXP进行SAX解析原理示例:

					import javax.xml.parsers.SAXParser;
					import javax.xml.parsers.SAXParserFactory;
					import org.xml.sax.Attributes;
					import org.xml.sax.ContentHandler;
					import org.xml.sax.Locator;
					import org.xml.sax.SAXException;
					import org.xml.sax.XMLReader;

					//JAXP进行SAX解析原理示例
					public class SAXDemo1 {

						public static void main(String[] args) throws Exception {
							// 得到解析工厂SAXParserFactory
							SAXParserFactory factory = SAXParserFactory.newInstance();
							// 得到解析器SAXParser
							SAXParser parser = factory.newSAXParser();
							// 得到XML读取器:XMLReader
							XMLReader reader = parser.getXMLReader();
							// 注册内容处理器:ContentHandler
							reader.setContentHandler(new MyContentHandler());
							// 读取XML文档
							reader.parse("src/book.xml");
						}
					}

					class MyContentHandler implements ContentHandler {
						//解析到文档开始时被调用
						public void startDocument() throws SAXException {
							System.out.println("解析到了文档的开始");
						}
						//解析到元素开始时被调用:qName元素名称
						public void startElement(String uri, String localName, String qName,
								Attributes atts) throws SAXException {
							System.out.println("解析到了元素的开始:"+qName);
						}
						//解析到文本内容时被调用
						public void characters(char[] ch, int start, int length)
								throws SAXException {
							System.out.println("文本内容:"+new String(ch,start,length));
						}
						//解析到元素结束时被调用
						public void endElement(String uri, String localName, String qName)
								throws SAXException {
							System.out.println("解析到了元素的结束:"+qName);
						}
						//解析到文档结束时被调用
						public void endDocument() throws SAXException {
							System.out.println("解析到了文档的结束");
						}

						public void endPrefixMapping(String prefix) throws SAXException {

						}

						public void ignorableWhitespace(char[] ch, int start, int length)
								throws SAXException {

						}

						public void processingInstruction(String target, String data)
								throws SAXException {

						}

						public void setDocumentLocator(Locator locator) {

						}

						public void skippedEntity(String name) throws SAXException {

						}

						public void startPrefixMapping(String prefix, String uri)
								throws SAXException {

						}
					}

		Dom4J 与JDOM不同的是,dom4j使用接口和抽象基类
		
			获得document的三种情况
				1.读取XML文件,获得document对象
					SAXReader reader = new SAXReader();
					Document?document = reader.read(new File("input.xml")); //Document document = reader.read("input.xml");					
				2.将字符串转化为XML--解析XML形式的文本,得到document对象.
      					String text = "<members><member>sitinspring</member></members>";
					Document document = DocumentHelper.parseText(text);
					注:将文档或节点的XML转化为字符串:调用document或 元素(element)的 asXML()方法。
				3.主动创建document对象.
   					Document document = DocumentHelper.createDocument(); //创建根节点
					Element root = document.addElement("members");

			更新XML文档
				//写回XML文档
				OutputStream out = new FileOutputStream("src/book.xml");
				OutputFormat format = OutputFormat.createPrettyPrint();
				//format.setEncoding("UTF-8");//指定编码:这是默认编码
				XMLWriter writer = new XMLWriter(out, format);
				writer.write(document);
				writer.close();
				
			相关API
				* 获得根元素
					Element rootElement = document.getRootElement();
				* 获得所有的子元素
					List list = rootElement.elements();
				* 获得指定的子元素
					Element priceElement = bookElement.element("price");
				* 获得指定属性的元素
					Node bookNode = document.selectSingleNode("//book[@id='b002']");
				* 设置文本
					priceElement.setText("100");
				* 获得节点的名称
					child.getName()
				* 获得指定名称的属性值
					String id = bookElement.attributeValue("id");
		
		JDom

六、Schema约束(看懂即可)
	1、Schema约束文档本身就是一个XML文档,扩展名为xsd
		
		优点:
		XML Schema符合XML语法结构。 
		DOM、SAX等XML API很容易解析出XML Schema文档中的内容。 
		XML Schema对名称空间支持得非常好。 
		XML Schema比XML DTD支持更多的数据类型,并支持用户自定义新的数据类型。 
		
	2、	重点:根据Schema写出XML文档
		难点:XML文档的根元素怎么写?

		例子:book.xsd
		<?xml version="1.0" encoding="UTF-8"?>
		<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
							  targetNamespace="http://www.jxn.cn"
							  elementFormDefault="qualified">
			<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>
		
		a、首先看Schema文档book.xsd,找到根元素
		<?xml version="1.0" encoding="UTF-8"?>
		<书架></书架>
		b、思考:书架来自于哪个名称空间?看Schema文档,targetNamespace就是名称空间。
		用xmlns关键字(xmlns名称空间声明)来声明我的元素来自哪个名称空间(xmlns:xml namespace)

		<?xml version="1.0" encoding="UTF-8"?>
		<jxn:书架 xmlns:jxn="http://www.jxn.cn"></jxn:书架>

		c、思考:名称空间与哪个xsd文件对应呢?使用schemaLocation关键字来关联名称空间和xsd的对应关系

		<?xml version="1.0" encoding="UTF-8"?>
		<jxn:书架 xmlns:jxn="http://www.jxn.cn" 
					schemaLocation="http://www.jxn.cn book.xsd"></jxn:书架>

		d、schemaLocation来自哪里?来自一个标准的名称空间(http://www.w3.org/2001/XMLSchema-instance)
		<?xml version="1.0" encoding="UTF-8"?>
		<jxn:书架 xmlns:jxn="http://www.jxn.cn" 
					xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
					xsi:schemaLocation="http://www.jxn.cn book.xsd"></jxn:书架>














XML

标签:xml   dtd   schema   sax   

原文地址:http://blog.csdn.net/wodewutai17quiet/article/details/44904365

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!