1、XML意为可扩展标记语言,Extensible Markup Language,能够表达层次结构,并且重复的元素不会被曲解。
2、XML和HTML的区别:
(1)与HTML不同,XML对大小写敏感;
(2)在HTML中,若从上下文中可以知道哪里是段落或者列表项的结尾,则可省略结束标签。而XML中结束标签不可省略。
(3)在XML中,只有单个标签而没有相对应的结束标签的元素必须以/结尾
(4)在XML中,属性值必须用引号括起来
(5)在HTML中,属性名可以没有值,但XML的所有属性必须有值。
3、格式良好的XML文档:
(1)必须有XML声明语句
(2)有且仅有一个根元素
(3)标签大小写敏感
(4)属性值用双引号
(5)标签成对
(6)元素正确嵌套
*XML文档以文档头开始。<?xml version=”1.0”?>
*文档头之后是文档定义类型,<?DOCTYPE ……>
<?xml version=”1.0”?>
<?DOCTYPE configuration …>
….
*经验法则:属性只应该用来修改值的解释,而不是用来指定值
4、常见XML解析技术:
(1)DOM解析:官方提供,基于XML的树形解析器
(2)SAX解析:民间提供,基于事件的流机制解析器
(3)JDOM解析:第三方提供,开源免费,比DOM解析快
(4)DOM4J解析:第三方提供,开源免费,是JDOM的升级版
*DOM解析:若文件过大,会造成内存溢出。优点是方便实现增删改操作。
*SAX解析:采用事件驱动,边读边解析,从上到下,一行一行的解析,解析到某一个对象,把对象名称返回。解析时不会造成内存溢出,能够实现查询操作,但不能实现增删改操作。
5、DOM解析:读入XML文档,首先需要一个DocumentBuilder对象,可从DocumentBuilderFactory中得到
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
File f = ….
(或者 URL u = …)
(或者 InputStream in = …)
Document doc = builder.parse(f/u/in);
*Document对象是XML文档的树形结构在内存中的表示形式,实现了Node接口。
*Element getDocumentElement方法启动对文档内容的解析,返回根元素
String getTagName方法返回元素的标签名
String getAttribute(String name)返回给定名字的属性值,没有时返回空字符串
trim方法可以把实际数据前后的空白字符删掉
NodeLIst getChildNodes方法返回类型为NodeLIst的集合
Node getFirstChild获取该节点的第一个子节点,没有时返回null
Node getLastChild获取该节点的最后一个子节点,没有时返回null
Node getNextSibling获取该节点的下一个兄弟节点,没有时返回null
Node getParentNode获取该节点的父节点,没有时返回null
NamedNodeMap getAttributes返回含有描述该节点所有属性的Attr节点的映射表
6、验证XML文档:XML解析器能自动校验某个文档是否具有正确的结构。若要指定文档结构,可提供文档定义类型(DTD)或一个XML Schema定义
(1)DTD可在XML文档的开头声明
<?xml version=”1.0”?>
<?DOCTYPE configuration [
…
]>
….
规则被纳入到DOCTYPE声明中,位于由[…]限定界限的块中,文档类型必须匹配根元素的名字。但这样写会使得代码长度边长,可把DTD存储在外部,SYSTEM声明可以用来实现这个目标,可指定包含DTD的URL:
<?DOCTYPE configuration SYSTEM “config.dtd”>
或者
<?DOCTYPE configuration SYSTEM “http://myserver.com/config.dtd”>
*使用DTD能够使得解析器在解析XML文档时能够明确解析DTD指定的子元素,解析器就能知道子元素之间的空白符不是文本,这样就能简化代码。
(2)XML Schema定义
<?xml version=”1.0”?>
<configuration xmlns:xsi=” http://www.w3.org/2001/XMLSchema-instance”
Xsi:noNamespaceSchemaLocation=”config.xsd”>
….
*Schema本身就是XML文档
Schema功能比DTD强大,正逐步替代DTD
Schema的根元素固定为schema
Schema文档定义完毕后,需要绑定到一个URI地址上,地址称为名称空间
*前缀xsd:表示XSL Schema定义的名称空间
*解析带有Schema的XML文件和解析带有DTD的XML文件的3点差别:
(1)必须打开对命名空间的支持,即使在XML文件里用不到
factory.setNamespaceAware(true);
(2)通过如下代码处理Schemade工厂
final String JAPX_SCHEMA_LANGUAGE=”http://java.sun.com/xml/jaxp/properties/sch”;
final String W3C_XML_SCHEMA=”http://www.w3.org/2001/XMLschema”;
factory.setAttribute(JAPX_SCHEMA_LANGUAGE, W3C_XML_SCHEMA);
(3)解析器不会丢弃元素中的空白字符
7、使用XPath定位信息:要定位某个XML文档中的一段特定信息,使用XPath语言使得访问树节点变得容易。如:
…
dbuser
secret
…
通过对XPath表达式/configuration/database/username求得database中username的值
*使用XPath表达式首先从XPathFactory创建一个XPath对象
XPathFactory XPFactory = XPathFactory.newInstance();
Path = XPFactory.newXPath();
然后,调用evaluate方法计算XPath表达式:
String name = Path.evaluate(“/configuration/database/username”,doc);
**DOM解析器可完整的读入XML文档,将其转换成一个树形的数据结构。但当文档过大时,并且处理算法简单,可以在运行时解析节点,且不必看到完整的树形结构,这是DOM解析就很低效。这时可使用流机制解析器,SAX解析器在解析XML输入数据的各个组成部分时会报告时间,但不会以任何形式存储文档,而是由时间处理器建立相应的数据结构。实际上,DOM解析器是在SAX解析器上建立起来的,它在接收到解析器事件时构建DOM树。
8、SAX解析器的代码:
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
SAXPaser parser = factory.newSAXParser();
Parser.parse(source,handler);
Source可以是一个文件、一个URL字符串或者一个输入流,handler属于DefaultHandler的一个子类
*与DOM解析器一样,命名空间处理特性默认是关闭的,可以调用工厂类的setNamespaceAware方法激活命名空间处理特性
9、生成XML文档:用文档的内容创建一棵DOM树,然后再写出概述的所有内容。
(1)不带命名空间的文档
通过调用DocumentBuilder类的newDocument方法得到一个空文档
Document doc = builder.new Document();
使用Document类的createDocument方法构建文档里的元素
Element rootElement = doc.createElement(rootName);
Element childElement = doc.createElement(childName);
使用createTextNode方法构建文本节点
Text textNode = doc.CreateTextNode(textContents);
使用下面的方法给文档添加根元素,给父节点添加子节点
doc.append(rootElement);
rootElement.appendChild(childElement);
childElement.appendChild(textNode);
使用下面的方法设置元素属性
rootElement.setAttribute(name,value);
(2)带命名空间的文档
首先需要将生成器工厂设置为是命名空间感知的,然后再创建生成器
DocmentBuilderFactory factory = DocumentBuilderFactory.newInstance();
Factory.setNamespaceAware(true);
Builder = factory.newDocumentBuilder();
使用createElementNS创建所有节点
String namespace = http://www.w3.org/2000/svg;
Element rootElement = doc.createElementNS(namespace,”svg”);
设置元素属性
rootElement.setAttributeNS(namespace,qualifiedName,value);
(3)写出文档:把DOM树写出到输出流最容易的方式是使用可扩展的样式表语言转换(Extensible Stylesheet Language Transformations,XSLT)API。