XML

XML和HTML的比较

全称

语法

作用

HTML

超文本标记语言

语法松散,标签不区分大小写,标签可以不匹配。

标签是固定的。

负责网页的结构

XML

Extensible Markup Language 可扩展标记语言

语法严格,标签区分大小写,标签须匹配。

标签不固定,可扩展。

1)描述带关系的数据结构(作为软件的配置文件,如struts2、hibernate、spring框架、Tomcat服务器)

2)装载数据(作为小型的“数据库”)。

3)应用之间传输数据的格式。另一个流行的格式是JSON。

文档声明

在编写XML文档时,需要先使用文档声明,声明XML文档的类型。

最简单的声明语法:

<?xml version="1.0" ?>

用encoding属性说明文档的字符编码:

<?xml version="1.0"  encoding="utf-8"?>

用standalone属性说明文档是否独立:

<?xml version="1.0" encoding="utf-8" standalone="yes" ?>

注意:xml文件的编码问题:

1)记事本xml文件内容保存的编码(另存为 -> 选择编码 utf-8 保存)

2)解析xml文件内容的编码(<?xml version="1.0" encoding="utf-8"?>)

以上两个编码必须保存一致,才能避免中文乱码问题。

3)如果在ecplise开发工具上编写xml文件,那么xml文件内容会自动按照文档声明的encoding的编码进行保存,所以不会中文乱码问题。

标签

<student>学生</student>

注意:

1)标签一定要配对,可以有空标签(无标签体),空标签简写形式不能省略结束标记斜杠 / 。

2)标签名区分大小写,不能以数字开头,中间不能包含空格,如果没有指定名称空间,不能含有冒号。

3)一个xml文件有且仅有一个根标签。

4)标签可以嵌套但不能交叉。

5)空格和换行也是标签体内容。

属性

<student id="1"></student>

注意:

1)一个属性分为属性名和属性值。属性名和值之间使用=号分割。

2)属性值一定要使用单引号或者双引号包含,不能省略,也不能单双混用!

3)一个标签内可以包含多个属性,但是不能出现同名的属性。

注释

<!-- 注释内容 --->

转义字符

和HTML的转义字符(字符实体)一致。

CDATA块

把CDATA块中的内容全部原样输入。语法:

<![CDATA[

内容

]]>

其他处理指令(processing instruction)

<?xml-stylesheet type="text/css" href="1.css"?>(已过时)

使用该处理指令,可以让xml像html一样使用。(已过时)

XML解析之DOM解析

XML解析方式和解析工具

DOM解析(Document Object Model)

SAX解析(Simple API for XML)

原理

文件一次性加载进内存,转化为document树,通过树上的对象获取或设置xml文件信息

加载一点,读取一点,处理一点。解析XML文档的时候可以触发一系列的事件。

优缺点

内存占用大(文件太大内存会溢出)。

可以查询和修改。

内存占用小。

只能查询。

编程方式

面向对象方式编程

基于事件方式编程

应用场景

修改或输出xml文件

提取部分数据到应用程序

解析的工具

1)Sun官方jaxp工具

2)jdom工具

3)dom4j工具:三大框架读取xml文件的程序。(非官方的,第三方的)

sun公司官方的sax解析工具,jdk中自带sax解析工具的api:

org.xml.sax.*;

JAXP-DOM示例

package xml;

import java.io.File;

import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;

import javax.xml.parsers.DocumentBuilderFactory;

import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;

import org.w3c.dom.Node;

import org.w3c.dom.NodeList;

import org.xml.sax.SAXException;

public class JaxpDemo {

public static void main(String[] args) {

//获取 DocumentBuilderFactory 的新实例。

DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();

//指定由此代码生成的解析器将忽略注释

dbf.setIgnoringComments(true);

//设置忽略空格

dbf.setIgnoringElementContentWhitespace(true);

DocumentBuilder db = null;

Document document = null;

try {

//获取DocumentBuilder的实例

db = dbf.newDocumentBuilder();

File file = new File("E:\\contact.xml");

document = db.parse(file);

//按文档顺序返回包含在文档中且具有给定标记名称的所有 Element 的 NodeList

NodeList nodeList = document.getElementsByTagName("name");

for (int i = 0; i < nodeList.getLength(); i++) {

Node node = nodeList.item(i);

//输出标记的值

System.out.println(node.getFirstChild().getNodeValue());

}

} catch (ParserConfigurationException e) {

e.printStackTrace();

} catch (SAXException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

}

dom4j工具使用

dom4j集成Xpath(路径查询语言)支持、XML Schema(约束模式文档)支持。

编程步骤

1)到dom4j的官方下载 。dom4j-1.6.1.zip

2)导入dom4j的支持jar包、dom4j-1.6.1.jar核心包

3)写代码。

常用API

获取或创建文档对象

获取文档对象:Document document = new SAXReader().read("xml文件路径");

创建文档对象:Document document = DocumentHelper.createDocument();

将文档对象写出到xml文件:

1)设置输出格式:

紧凑模式:OutputFormat compactFormat = OutputFormat.createCompactFormat();//紧凑模式,节省带宽,上线时使用

美观模式:OutputFormat prettyPrint = OutputFormat.createPrettyPrint();//美观模式,便于查看,开发时使用

2)设置输出编码(同时设置了文档声明中encoding的值):

outputFormat.setEncoding("utf-8");

3)创建写出器(无 outputFormat 参数则默认使用紧凑模式和UTF-8编码):

XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("要写出的xml文件路径"), outputFormat);

4)写出Document对象到XML文件:

xmlWriter.write(document);

5)关闭资源:

xmlWriter.close();

元素、属性、文本操作

查:

元素:

document.getRootElement(); 获取根标签

element.elements(); 获取所有子标签

element.elements("子元素名"); 获取指定名称的所有子标签

element.element("子元素名"); 获取指定名称的首个子标签

element.getName(); 获取标签名

属性:

element.atrributes(); 获取该标签的所有属性对象

element.atrribute("属性名"); 从标签获取指定属性名的属性对象

element.atrribute(属性索引); 从标签获取指定属性索引的属性对象(属性索引从0开始)

element.atrributeValue("属性名"); 从标签获取指定属性名的属性值

atrribute.getName(); 从属性获取属性名

atrribute.getValue(); 从属性获取属性值

文本:

element.getText(); 获取标签的文本

  element.elementText("子元素名"); 获取指定名称的首个子标签的文本

增:

document.addElement("元素名"); 创建元素

element.addAtribute("属性名","属性值"); 创建属性(返回原元素对象)

element.addText("文本内容"); 追加文本

改:

setValue(); 修改属性值

addAttribute("同名属性","修改值"); 修改属性值

setText(); 修改文本

删:

标签/属性.detach(); 自杀

标签/属性.getParent().remove(标签/属性); 他杀

XPath技术

作用

快速查询和修改xml文件的节点。

编程步骤

1)导入dom4j的xpath插件包:jaxen-1.1-beta-6.jar

2)在dom4j中使用xpath:

List<Node> list = selectNodes("xpath表达式"); 查询多个节点(标签/属性/文本)

Node node = selectSingleNode("xpath表达式"); 查询单个节点(标签/属性/文本),如有多个,返回第一个

XPath表达式(重点)

/   绝对路径    斜杠在最前面,代表xml文件的根。斜杠在中间,表示子元素。

//  相对路径    选择后代元素(不分层次结构)

*   通配 选择所有元素

[ ]   条件        选择什么条件下的元素。例如 /AAA/BBB[1] 选择第一个BBB子元素

@   属性         选取属性

=    内容 (值)  

and  逻辑与

text()   选取文本内容

路径表达式

结果

bookstore

选取 bookstore 元素的所有节点

/bookstore

选取根元素 bookstore 注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径!

bookstore/book

选取所有属于 bookstore 的子元素的 book 元素。

//book

选取所有 book 子元素,而不管它们在文档中的位置。

bookstore//book

选择所有属于 bookstore 元素的后代的 book 元素,而不管它们位于 bookstore 之下的什么位置。

使用限定语[]

路径表达式

结果

/bookstore/book[1]

选取属于 bookstore 子元素的第一个 book 元素。

/bookstore/book[last()]

选取属于 bookstore 子元素的最后一个 book 元素。

/bookstore/book[last()-1]

选取属于 bookstore 子元素的倒数第二个 book 元素。

/bookstore/book[position()<3]

选取最前面的两个属于 bookstore 元素的子元素的 book 元素。

//title[@lang]

选取所有拥有名为 lang 的属性的 title 元素。

//title[@lang='eng']

选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。

/bookstore/book[price>35.00]

选取所有 bookstore 元素的 book 元素,且其中的 price 元素的值须大于 35.00。

使用通配符

路径表达式

结果

/bookstore/*

选取 bookstore 元素的所有子节点

//*

选取文档中的所有节点

//title[@*]

选取所有带有属性的 title 元素。

//book/title | //book/price

选取所有 book 元素的 tilte 和 price 元素。

XML解析之SAX解析

SAX 解析器在解析开始的时候就开始发送事件。当解析器发现文档开始、元素开始和文本等时,代码会收到一个事件。

SAX 解析器根本不创建任何对象,它只是将事件传递给您的应用程序。如果希望基于那些事件创建对象,这将由您来完成。

DefaultHandler类

startElement(): 开始标签

characters():文本内容

endElement(): 结束标签

案例

打印xml文件主要内容

package xml;

import java.io.IOException;

import javax.xml.parsers.ParserConfigurationException;

import javax.xml.parsers.SAXParser;

import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;

import org.xml.sax.SAXException;

import org.xml.sax.helpers.DefaultHandler;

public class SaxDemo_PrintXml {

public static void main(String[] args) {

SAXParser saxParser;

try {

saxParser = SAXParserFactory.newInstance().newSAXParser();

saxParser.parse("./src/contact.xml", new PrintXmlHandler());

} catch (ParserConfigurationException e) {

e.printStackTrace();

} catch (SAXException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

}

}

}

class PrintXmlHandler extends DefaultHandler {

private StringBuffer sb = new StringBuffer();

@Override

public void startDocument() throws SAXException {

System.out.println("指定XML文件的主要内容为:\r");

}

@Override

public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {

sb.append("<" + qName);

if (null != attributes) {

for (int i = 0; i < attributes.getLength(); i++) {

sb.append(" " + attributes.getQName(i) + "=\"" + attributes.getValue(i) + "\"");

}

}

sb.append(">");

}

@Override

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

sb.append(new String(ch, start, length));

}

@Override

public void endElement(String uri, String localName, String qName) throws SAXException {

sb.append("<" + qName + ">");

}

@Override

public void endDocument() throws SAXException {

System.out.println(sb);

}

}

提取xml内容到对象

package xml;

import java.io.IOException;

import java.util.ArrayList;

import java.util.List;

import javax.xml.parsers.ParserConfigurationException;

import javax.xml.parsers.SAXParser;

import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;

import org.xml.sax.SAXException;

import org.xml.sax.helpers.DefaultHandler;

public class SaxDemo_XmlToObject {

public static void main(String[] args) {

SAXParser saxParser;

try {

saxParser = SAXParserFactory.newInstance().newSAXParser();

MyDefaultHandler myDefaultHandler = new MyDefaultHandler();

saxParser.parse("./src/contact.xml", myDefaultHandler);

List<Contact> conList = myDefaultHandler.getList();

for (Contact contact : conList) {

System.out.println(contact);

}

} catch (ParserConfigurationException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (SAXException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} catch (IOException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

class MyDefaultHandler extends DefaultHandler {

//用于存储一个contact标签中的信息

private Contact contact = null;

//用于存储所有Contact对象信息

private List<Contact> conList = new ArrayList<Contact>();

//用于返回储所有Contact对象信息

public List<Contact> getList() {

return conList;

}

//用于存储当前解析到的元素

private String curTag = null;

//用于存储当前解析到的文本

private String curText = null;

@Override

public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {

//供characters方法解析文本之用

curTag = qName;

if ("contact".equals(qName)) {

contact = new Contact();

contact.setId(attributes.getValue("id"));

}

}

@Override

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

if (null != curTag) {

curText = new String(ch, start, length);

switch (curTag) {

case "name":

contact.setName(curText);

break;

case "gender":

contact.setGender(curText);

break;

case "phone":

contact.setPhone(curText);

break;

case "email":

contact.setEmail(curText);

break;

case "address":

contact.setAddress(curText);

}

}

}

@Override

public void endElement(String uri, String localName, String qName) throws SAXException {

//供characters方法丢弃空白及换行文本之用

curTag = null;

if ("contact".equals(qName)) {

conList.add(contact);

}

}

}

class Contact {

private String id;

private String name;

private String gender;

private String phone;

private String email;

private String address;

@Override

public String toString() {

return "Contact [id=" + id + ", name=" + name + ", gender=" + gender + ", phone=" + phone + ", email=" + email

+ ", address=" + address + "]";

}

省略getter和setter方法

}

其他XML解析工具

Xstream

<dependency>

<groupId>com.thoughtworks.xstream</groupId>

<artifactId>xstream</artifactId>

<version>1.4.10</version>

</dependency>

XML约束(看懂即可)

什么是约束?

xml语法: w3c组织对xml文件的编程规则规范。(w3c组织制定的)

xml约束: 由开发者指定的对xml文件内容规范。(开发者根据业务指定的)

约束分类

DTD约束:相对简单,数据类型简单。 场景:Hibernate  Struts2

Schema约束:相对复杂,功能强大,数据类型非常丰富。 场景:Spring

DTD约束

1)dtd的使用方法

内部的dtd:约束内容写在xml文件中。

外部的dtd:约束内容写在另一个文件中,在xml中引用。

2)语法

约束标签

<!ELEMENT 元素名称 类别> 或 <!ELEMENT 元素名称 (元素内容)>

类别:

EMPTY:空标签

PCDATA:普通字符串(不能包含子标签)

ANY: 任意内容(空标签/字符串/可以包含子标签)

顺序问题:

(子元素名称 1,子元素名称 2,.....): 一定要依次出现1,2,...

数量问题:

子元素:  有且仅有1个

+ :    1个或多个

* :  0个或多个

? :    0个或1个

约束属性

<!ATTLIST 元素名称 属性名称 属性类型 默认值>

默认值:

#REQUIRED:必须

#IMPLIED:不是必须的

#FIXED value : 固定的

属性类型:控制属性值

CDATA:普通字符串

(en1|en2...): 枚举中的一个值

ID: 唯一的值

Schema约束

重点:名称空间(知道如何依据名称空间找到scheme约束文件,语法查询w3c文档)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值