一、XML语法
0、引入
HTML: 负责网页的结构
CSS: 负责网页的样式(美观)
Javascript: 负责在浏览器端与用户进行交互。
XML:软件配置文件(最常见)、作为小型数据库
1、文档声明
在编写XML文档时,需要先使用文档声明,声明XML文档的类型。
① 最简单的声明语法(version:xml的版本号)
<?xml version="1.0" ?>
② 用encoding属性说明文档的字符编码(解码)
<?xml version="1.0" encoding="GB2312" ?>
③ 用standalone属性说明文档是否独立
<?xml version="1.0" encoding="GB2312" standalone="yes" ?>
注意:如果在ecplise工具中开发xml文件,保存xml文件时自动按照文档声明的encoding来保存文件;如果用记事本工具修改xml文件,注意保存xml文件按照文档声明的encoding的码表来保存。
2、标签命名规范
① 一个标签有如下几种书写形式,例如:
包含标签体:<a>www.itcast.cn</a>
不含标签体的:<a></a>
简写为:<a/>
(空标签)
② xml标签名称区分大小写:例如<P>
和<p>
是两个不同的标签
③ xml标签一定要正确配对
④ xml标签名中间不能使用空格
⑤ xml标签名不能以数字开头
⑥ 名称中间不能包含冒号(:)
注意: 在一个xml文档中,有且仅有一个根标签
对于XML标签中出现的所有空格和换行,XML解析程序都会当作标签内容进行处理。例如:下面两段内容的意义是不一样的。由于在XML中,空格和换行都作为原始内容被处理,所以,在编写XML文件时,使用换行和缩进等方式来让原文件中的内容清晰可读的“良好”书写习惯可能要被迫改变。
3、属性
① 属性值一定要用双引号(”)或单引号(’)引起来(HTML不一定要带引号)
② 定义属性必须遵循与标签相同的命名规范
③ 在一个xml文档中只能存在一个根标签
④ 标签属性所代表的信息,也可以被改成用子元素的形式来描述,例如:
<input>
<name>text</name>
</input>
4、注释
Xml文件中的注释采用<!--注释-->
格式。
注意:XML声明之前不能有注释
5、转义字符
在xml中内置了一些特殊字符,这些特殊字符不能直接被浏览器原样输出,如果希望把这些特殊字符按照原样输出到浏览器,对这些特殊字符进行转义
特殊字符 | 转义字符 |
---|---|
< | < |
> | > |
“ | " |
& | & |
空格 | &nsbp; |
6、CDATA区
在编写XML文件时,有些内容可能不想让解析引擎解析执行,而是当作原始内容处理。遇到此种情况,可以把这些内容放在CDATA区里,对于CDATA区域内的内容,XML解析程序不会处理,而是直接原封不动的输出。
格式:<![CDATA[ 内容 ]]>
<![CDATA[
<itcast>
<br/>
</itcast>
]]>
7、处理指令PI(processing instruction)
① 处理指令用来指挥解析引擎如何解析XML文档内容。
例如,在XML文档中可以使用xml-stylesheet指令,通知XML解析引擎,应用css文件显示xml文档内容:<?xml-stylesheet type="text/css" href="1.css"?>
② 处理指令必须以<?
作为开头,以?>
作为结尾,XML声明语句就是最常见的一种处理指令。
③ 作用: 告诉xml解析如果解析xml文档
二、XML解析 ##
1、作用:xml文件除了给开发者看,更多的情况使用程序读取xml文件的内容(这叫做xml解析)
2、XML解析方式(原理不同):DOM解析、SAX解析
3、XML解析工具
① DOM解析:
◆ JAXP (oracle-Sun公司官方)
◆ JDOM工具(非官方)
◆ Dom4J工具(非官方):三大框架(struts、Hibernate、spring)默认读取xml的工具就是
② SAX解析:Sax解析工具(oracle-sun公司官方)
4、DOM解析原理:xml解析器一次性把整个xml文档加载进内存,然后在内存中构建一棵Document的对象树,通过Document对象得到树上的节点对象,然后通过节点对象访问(操作)到xml文档的内容(标签、属性、文本、注释)。
5、Dom4j工具:非官方,不在jdk中
① 使用步骤
◆ 导入dom4j的核心包:dom4j-1.6.1.jar
◆ 编写Dom4j读取xml文件代码
public static void main(String[] args) {
try {
//1.创建一个xml解析器对象
SAXReader reader = new SAXReader();
//2.读取xml文档,返回Document对象
Document doc = reader.read(new File("./src/contact.xml"));
System.out.println(doc);
} catch (DocumentException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
② Domj4读取xml文件
public class Demo1 {
/**
* 获取节点信息
*/
@Test
public void test1() throws Exception{
//1.读取xml文档,返回Document对象
SAXReader reader = new SAXReader();
Document doc = reader.read(new File("./src/contact.xml"));
//2.nodeIterator: 得到当前节点下的所有子节点对象(不包含孙以下的节点)
Iterator<Node> it = doc.nodeIterator();
while(it.hasNext()){//判断是否有下一个元素
Node node = it.next();//取出元素
String name = node.getName();//得到节点名称
//继续取出其下面的子节点
//只有标签节点才有子节点
//判断当前节点是否是标签节点
if(node instanceof Element){
Element elem = (Element)node;
Iterator<Node> it2 = elem.nodeIterator();
while(it2.hasNext()){
Node n2 = it2.next();
System.out.println(n2.getName());
}
}
}
}
/**
* 获取所有节点信息方式:遍历
* @throws Exception
*/
@Test
public void test2() throws Exception{
//1.读取xml文档,返回Document对象
SAXReader reader = new SAXReader();
Document doc = reader.read(new File("./src/contact.xml"));
//得到根标签
Element rooElem = doc.getRootElement();
getChildNodes(rooElem);
}
/**
* 方法:获取传入的标签下的所有子节点
* @param elem
*/
private void getChildNodes(Element elem){
System.out.println(elem.getName());
//得到子节点
Iterator<Node> it = elem.nodeIterator();
while(it.hasNext()){
Node node = it.next();
//判断是否是标签节点
if(node instanceof Element){
Element el = (Element)node;
//递归
getChildNodes(el);
}
};
}
/**
* 获取标签信息
*/
@Test
public void test3() throws Exception{
//1.读取xml文档,返回Document对象
SAXReader reader = new SAXReader();
Document doc = reader.read(new File("./src/contact.xml"));
//2.得到根标签
Element rootElem = doc.getRootElement();
//得到标签名称
String name = rootElem.getName();
System.out.println(name);
//3.得到当前标签下指定名称的第一个子标签
/*
Element contactElem = rootElem.element("contact");
System.out.println(contactElem.getName());
*/
//4.得到当前标签下指定名称的所有子标签
/*
Iterator<Element> it = rootElem.elementIterator("contact");
while(it.hasNext()){
Element elem = it.next();
System.out.println(elem.getName());
}
*/
//5.得到当前标签下的的所有子标签
List<Element> list = rootElem.elements();
//遍历List的方法
//1)传统for循环、2)增强for循环、3)迭代器
/*for(int i=0;i<list.size();i++){
Element e = list.get(i);
System.out.println(e.getName());
}*/
/*for(Element e:list){
System.out.println(e.getName());
}*/
/*
Iterator<Element> it = list.iterator(); //ctrl+2 松开 l
while(it.hasNext()){
Element elem = it.next();
System.out.println(elem.getName());
}*/
//获取更深层次的标签(方法只能一层层地获取)
Element nameElem = doc.getRootElement().
element("contact").element("name");
System.out.println(nameElem.getName());
}
/**
* 获取属性信息
*/
@Test
public void test4() throws Exception{
//1.读取xml文档,返回Document对象
SAXReader reader = new SAXReader();
Document doc = reader.read(new File("./src/contact.xml"));
//获取属性:(先获的属性所在的标签对象,然后才能获取属性)
//1.得到标签对象
Element contactElem = doc.getRootElement().element("contact");
//2.得到属性
//2.1 得到指定名称的属性值
/*
String idValue = contactElem.attributeValue("id");
System.out.println(idValue);
*/
//2.2 得到指定属性名称的属性对象
/*Attribute idAttr = contactElem.attribute("id");
//getName:属性名称、getValue:属性值
System.out.println(idAttr.getName() +"=" + idAttr.getValue());*/
//2.3 得到所有属性对象,返回LIst集合
/*List<Attribute> list = contactElem.attributes();
//遍历属性
for (Attribute attr : list) {
System.out.println(attr.getName()+"="+attr.getValue());
}*/
//2.4 得到所有属性对象,返回迭代器
Iterator<Attribute> it = contactElem.attributeIterator();
while(it.hasNext()){
Attribute attr = it.next();
System.out.println(attr.getName()+"="+attr.getValue());
}
}
/**
* 获取文本信息
*/
@Test
public void test5() throws Exception{
//1.读取xml文档,返回Document对象
SAXReader reader = new SAXReader();
Document doc = reader.read(new File("./src/contact.xml"));
/**
* 注意: 空格和换行也是xml的内容
String content = doc.getRootElement().getText();
System.out.println(content);
*/
//获取文本(先获取标签,再获取标签上的文本)
Element nameELem =
doc.getRootElement().element("contact").element("name");
//1. 得到文本
String text = nameELem.getText();
System.out.println(text);
//2. 得到指定子标签名的文本内容
String text2 = doc.getRootElement().element("contact").elementText("phone");
System.out.println(text2);
}
}
获取 | 返回值 |
---|---|
获取节点 | |
[Element对象].nodeIterator();//获取当前标签节点下的所有子节点 | Iterator |
获取标签 | |
[Document对象].getRootElement();//获取xml文档的根标签 | Element |
[ELement对象].element(“标签名”);//指定名称的第一个子标签 | Element |
[Element对象].elementIterator(“标签名”);//指定名称的所有子标签 | Iterator<Element> |
[Element对象].elements(); //获取所有子标签 | List<Element> |
获取属性 | |
[Element对象].attributeValue(“属性名”);//获取指定名称的属性值 | String |
[Element对象].attribute(“属性名”);//获取指定名称的属性对象 | Attribute |
[Attribute对象].getName();//获取属性名称 | |
[Attibute对象].getValue();//获取属性值 | |
[Element对象].attributes();//获取所有属性对象 | List<Attribute> |
[Element对象].attibuteIterator();//获取所有属性对象 | Iterator<Attribute> |
获取文本 | |
[Element对象].getText();//获取当前标签的文本 | |
[Element对象].elementText(“标签名”);//获取当前标签的指定名称的子标签的文本内容 |
/**
* 把xml文档信息封装到对象中
**/
public class Demo2 {
public static void main(String[] args) throws Exception{
List<Contact> list = new ArrayList<Contact>();
//读取xml,封装对象
SAXReader reader = new SAXReader();
Document doc = reader.read(new File("./src/contact.xml"));
//读取contact标签
Iterator<Element> it = doc.getRootElement().elementIterator("contact");
while(it.hasNext()){
Element elem = it.next();
//创建Contact
Contact contact = new Contact();
contact.setId(elem.attributeValue("id"));
contact.setName(elem.elementText("name"));
contact.setAge(elem.elementText("age"));
contact.setPhone(elem.elementText("phone"));
contact.setEmail(elem.elementText("email"));
contact.setQq(elem.elementText("qq"));
list.add(contact);
}
for (Contact contact : list) {
System.out.println(contact);
}
}
}
public class Contact {
private String id;
private String name;
private String age;
private String phone;
private String email;
private String qq;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getQq() {
return qq;
}
public void setQq(String qq) {
this.qq = qq;
}
@Override
public String toString() {
return "Contact [age=" + age + ", email=" + email + ", id=" + id
+ ", name=" + name + ", phone=" + phone + ", qq=" + qq + "]";
}
}
③ Domj4修改xml文件
//写出内容到xml文档
public class Demo3 {
public static void main(String[] args) throws Exception{
//一、读取或创建一个Document对象
//读取xm文件
Document doc = new SAXReader().read(new File("./src/contact.xml"));
/**
* 1.指定写出的格式
*/
OutputFormat format = OutputFormat.createCompactFormat(); //紧凑的格式:去除空格换行.项目上线的时候
//OutputFormat format = OutputFormat.createPrettyPrint(); //漂亮的格式:有空格和换行.开发调试的时候
/**
* 2.指定生成的xml文档的编码
* 同时影响了xml文档保存时的编码和xml文档声明的encoding的编码(xml解析时的编码)
* 结论: 使用该方法生成的xml文档避免中文乱码问题。
*/
format.setEncoding("utf-8");
//二、修改Document对象内容
//三、把修改后的Document对象写出到xml文档中
//指定文件输出的位置
FileOutputStream out = new FileOutputStream("e:/contact.xml");
//1.创建写出对象
//XMLWriter writer = new XMLWriter(out);
XMLWriter writer = new XMLWriter(out,format);
//2.写出对象
writer.write(doc);
//3.关闭流
writer.close();
}
}
功能 | 解释 |
---|---|
增加 | |
DocumentHelper.createDocument() | 增加文档 |
addElement(“名称”) | 增加标签 |
addAttribute(“名称”,”值”) | 增加属性 |
修改 | |
Attribute.setValue(“值”) | 修改属性值 |
Element.addAtribute(“同名的属性名”,”值”) | 修改同名的属性值 |
Element.setText(“内容”) | 修改文本内容 |
删除 | |
Element.detach() | 删除标签 |
Attribute.detach() | 删除属性 |
public class Demo4 {
/**
* 增加:文档、标签、属性
*/
@Test
public void test1() throws Exception{
/**
* 1.创建文档
*/
Document doc = DocumentHelper.createDocument();
/**
* 2.增加标签
*/
Element rootElem = doc.addElement("contactList");
//doc.addElement("contactList");
Element contactElem = rootElem.addElement("contact");
contactElem.addElement("name");
/**
* 3.增加属性
*/
contactElem.addAttribute("id", "001");
contactElem.addAttribute("name", "eric");
//把修改后的Document对象写出到xml文档中
FileOutputStream out = new FileOutputStream("e:/contact.xml");
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("utf-8");
XMLWriter writer = new XMLWriter(out,format);
writer.write(doc);
writer.close();
}
/**
* 修改:属性值,文本
* @throws Exception
*/
@Test
public void test2() throws Exception{
Document doc = new SAXReader().read(new File("./src/contact.xml"));
/**
* 方案一:修改属性值 1.得到标签对象 2.得到属性对象 3.修改属性值
*/
//1.1 得到标签对象
Element contactElem = doc.getRootElement().element("contact");
//1.2 得到属性对象
Attribute idAttr = contactElem.attribute("id");
//1.3 修改属性值
idAttr.setValue("003");
/**
* 方案二:修改属性值 1.得到标签对象 2.通过增加同名属性的方法,修改属性值
*/
//1.1 得到标签对象
Element contactElem = doc.getRootElement().element("contact");
//1.2 通过增加同名属性的方法,修改属性值
contactElem.addAttribute("id", "004");
/**
* 修改文本:1.得到标签对象 2.修改文本
*/
Element nameElem = doc.getRootElement().element("contact").element("name");
nameElem.setText("李四");
FileOutputStream out = new FileOutputStream("e:/contact.xml");
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("utf-8");
XMLWriter writer = new XMLWriter(out,format);
writer.write(doc);
writer.close();
}
/**
* 删除:标签,属性
* @throws Exception
*/
@Test
public void test3() throws Exception{
Document doc = new SAXReader().read(new File("./src/contact.xml"));
/**
* 1.删除标签:1.1 得到标签对象 1.2 删除标签对象
*/
//1.1 得到标签对象
Element ageElem = doc.getRootElement().element("contact").element("age");
//1.2 删除标签对象
ageElem.detach();
//ageElem.getParent().remove(ageElem);
/**
* 2.删除属性:2.1得到属性对象 2.2 删除属性
//2.1 得到属性对象
//得到第二个contact标签
Element contactElem = (Element)doc.getRootElement().elements().get(1);
//2.2 得到属性对象
Attribute idAttr = contactElem.attribute("id");
//2.3 删除属性
idAttr.detach();
//idAttr.getParent().remove(idAttr);
FileOutputStream out = new FileOutputStream("e:/contact.xml");
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("utf-8");
XMLWriter writer = new XMLWriter(out,format);
writer.write(doc);
writer.close();
}
}
6、XPath技术
① 问题:当使用dom4j查询比较深的层次结构的节点(标签,属性,文本),比较麻烦
② XPath作用:主要是用于快速获取所需的节点对象。
③ 在dom4j中如何使用XPath技术
◆ 导入XPath支持jar包: jaxen-1.1-beta-6.jar
◆ 使用XPath方法
List<Node> selectNodes("xpath表达式"); 查询多个节点对象
Node selectSingleNode("xpath表达式"); 查询一个节点对象
④ XPath语法
功能 | 名称 | 解释 |
---|---|---|
/ | 绝对路径 | 表示从xml的根位置开始或子元素(一个层次结构) |
// | 相对路径 | 表示不分任何层次结构的选择元素 |
* | 通配符 | 表示匹配所有元素 |
[] | 条件 | 表示选择什么条件下的元素 |
@ | 属性 | 表示选择属性节点 |
and | 关系 | 表示条件的与关系(等价于&&) |
text() | 文本 | 表示选择文本内容 |
public class Demo4 {
public static void main(String[] args) throws Exception {
Document doc = new SAXReader().read(new File("./src/contact.xml"));
String xpath = "";
/**
* 1. / 绝对路径:表示从xml的根位置开始或子元素(一个层次结构)
*/
xpath = "/contactList";
xpath = "/contactList/contact";
/**
* 2. // 相对路径:表示不分任何层次结构的选择元素。
*/
xpath = "//contact/name";
xpath = "//name";
/**
* 3. * 通配符:表示匹配所有元素
*/
xpath = "/contactList/*"; //根标签contactList下的所有子标签
xpath = "/contactList//*";//根标签contactList下的所有标签(不分层次结构)
/**
* 4. [] 条件:表示选择什么条件下的元素
*/
//带有id属性的contact标签
xpath = "//contact[@id]";
//第二个的contact标签
xpath = "//contact[2]";
//选择最后一个contact标签
xpath = "//contact[last()]";
/**
* 5. @ 属性:表示选择属性节点
*/
xpath = "//@id"; //选择id属性节点对象,返回的是Attribute对象
xpath = "//contact[not(@id)]";//选择不包含id属性的contact标签节点
xpath = "//contact[@id='002']";//选择id属性值为002的contact标签
xpath = "//contact[@id='001' and @name='eric']";//选择id属性值为001,且name属性为eric的contact标签
/**
*6. text():表示选择文本内容
*/
//选择name标签下的文本内容,返回Text对象
xpath = "//name/text()";
xpath = "//contact/name[text()='张三']";//选择姓名为张三的name标签
List<Node> list = doc.selectNodes(xpath);
for (Node node : list) {
System.out.println(node);
}
}
}
7、SAX解析
① DOM解析原理:一次性把xml文档加载进内存,然后在内存中构建Document树,对内存要求比较高。
缺点: 不适合读取大容量的xml文件,容易导致内存溢出。
SAX解析原理: 加载一点,读取一点,处理一点,对内存要求比较低。
② SAX解析工具:Sun公司提供的内置在jdk中:org.xml.sax.*;
③ 核心的API(SAXParser类) 用于读取和解析xml文件对象
◆parse(File f, DefaultHandler dh)方法: 解析xml文件
【File:表示要读取的xml文件;DefaultHandler:SAX事件处理程序,要使用DefaultHandler的子类】
public class Demo5 {
public static void main(String[] args) throws Exception{
//1.创建SAXParser对象
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
//2.调用parse方法读取xml文件
/**
* 参数一: xml文档
* 参数二: DefaultHandler的子类[一个类继承class 类名(extends DefaultHandler)在调用是创建传进去
*/
parser.parse(new File("./src/contact.xml"), new MyDefaultHandler());
//输出文档
String content = handler.getContent();
System.out.println(content);
}
}
}
/**
* SAX处理程序(如何解析xml文档)
* @author APPle
*
*/
public class MyDefaultHandler extends DefaultHandler {
private StringBuffer sb = new StringBuffer();
//获取xml信息
public String getContent(){
return sb.toString();
}
/**
* 开始文档时调用
*/
@Override
public void startDocument() throws SAXException {
System.out.println("MyDefaultHandler.startDocument()");
}
/**
* 开始标签时调用
* @param qName: 表示开始标签的标签名
* @param attributes: 表示开始标签内包含的属性列表
*/
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
sb.append("<"+qName);
//判断是否有属性
if(attributes!=null){
for(int i=0;i<attributes.getLength();i++){
//得到属性名称
String attrName = attributes.getQName(i);
//得到属性值
String attrValue = attributes.getValue(i);
sb.append(" "+attrName+"=\""+attrValue+"\"");
}
}
sb.append(">");
}
/**
* 结束标签时调用
* @param qName: 结束标签的标签名称
*/
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
sb.append("</"+qName+">");
}
/**
* 读到文本内容的时调用
* @param ch: 表示当前读完的所有文本内容
* @param start: 表示当前文本内容的开始位置
* @param length: 表示当前文本内容的长度
*/
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
//得到当前读取的文本
String content = new String(ch,start,length);
sb.append(content);
}
/**
* 结束文档时调用
*/
@Override
public void endDocument() throws SAXException {
System.out.println("MyDefaultHandler.endDocument()");
}
}
◆ DefaultHandler类的API
void startDocument():在读到文档开始时调用
void endDocument():在读到文档结束时调用
void startElement(String uri, String localName, String qName, Attributes attributes):读到开始标签时调用
void endElement(String uri, String localName, String qName):读到结束标签时调用
void characters(char[] ch, int start, int length):读到文本内容时调用
public class Demo3 {
public static void main(String[] args)throws Exception {
SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
MyDefaultHandler3 handler = new MyDefaultHandler3();
parser.parse(new File("./src/contact.xml"), handler);
List<Contact> list = handler.getList();
for (Contact contact : list) {
System.out.println(contact);
}
}
}
public class MyDefaultHandler3 extends DefaultHandler {
//存储所有联系人对象
private List<Contact> list = new ArrayList<Contact>();
public List<Contact> getList(){
return list;
}
//保存一个联系人信息
private Contact contact;
/**
* 思路:
* 1)创建Contact对象
* 2)把每个contact标签内容存入到Contact对象
* 3)把Contact对象放入List中
*/
//用于临时存储当前读到的标签名
private String curTag;
@Override
public void startElement(String uri, String localName, String qName,Attributes attributes) throws SAXException {
curTag = qName;
//读取到contact的开始标签创建Contact对象
if("contact".equals(qName)){
contact = new Contact();
//设置id值
contact.setId(attributes.getValue("id"));
}
}
@Override
public void characters(char[] ch, int start, int length)throws SAXException {
//当前文本内容
String content = new String(ch,start,length);
if("name".equals(curTag)){
contact.setName(content);
}
if("age".equals(curTag)){
contact.setAge(content);
}
if("phone".equals(curTag)){
contact.setPhone(content);
}
if("email".equals(curTag)){
contact.setEmail(content);
}
if("qq".equals(curTag)){
contact.setQq(content);
}
}
@Override
public void endElement(String uri, String localName, String qName)throws SAXException {
//设置空时为了避免空格换行设置到对象的属性中
curTag = null;
//读到contact的结束标签放入List中
if("contact".equals(qName)){
list.add(contact);
}
}
}
8、DOM解析与SAX解析区别
① DOM解析原理:一次性加载xml文档,不适合大容量的文件读取;DOM解析可以任意进行增删改查;DOM解析任意读取任何位置的数据,甚至往回读;DOM解析面向对象的编程方法(Node,Element,Attribute)Java开发者编码比较简单。
② SAX解析原理:加载一点,读取一点,处理一点,适合大容量文件的读取;SAX解析只能读取;SAX解析只能从上往下,按顺序读取,不能往回读;SAX解析基于事件的编程方法,java开发编码相对复杂。
三、XML约束
1、XML语法: 规范xml文件的基本编写规则(由w3c组织制定的)
XML约束: 规范xml文件数据内容格式的编写规则(由开发者自行定义)
2、XML约束技术
① DTD约束:语法相对简单,功能也相对简单,学习成本也低。
② Schema约束:语法相对复杂,功能也相对强大,学习成本相对高
3、DTD约束
① 导入DTD方式
◆ 内部导入
<!DOCTYPE note [
<!ELEMENT note (to,from,heading,body)>
<!ELEMENT to (#PCDATA)>
<!ELEMENT from (#PCDATA)>
<!ELEMENT heading (#PCDATA)>
<!ELEMENT body (#PCDATA)>
]>
◆ 外部导入
◇ 本地文件系统的外部导入:<!DOCTYPE 根元素 SYSTEM "文件名.dtd">
◇ 公共的外部导入:<!DOCTYPE 根元素 PUBLIC "http://gz.itcast.cn/itcast.dtd">
② DTD语法
◆ 约束标签:<!ELEMENT 元素名称 类别>
或 <!ELEMENT 元素名称 (元素内容)>
◇ 类别:
空标签: EMPTY,表示元素一定是空元素
普通字符串:(#PCDATA),表示元素的内容一定是普通字符串(不能含有子标签)
任何内容: ANY,表示元素的内容可以是任意内容(包括子标签)
◇ 元素内容:
顺序问题:<!ELEMENT 元素名称 (子元素名称1,子元素名称2,.....)>
次数问题:
标签:必须且只出现1次;
标签+:至少出现1次;
标签*: 0或n次;
标签?: 0 或1次。
◆ 约束属性<!ATTLIST 元素名称 属性名称 属性类型 默认值>
◇ 默认值:
#REQUIRED
:属性值是必需的
#IMPLIED
:属性不是必需的
#FIXED value
:属性不是必须的,但属性值是固定的值value
◇ 属性类型:
CDATA
:表示普通字符串
(en1|en2|..)
:表示一定是任选其中的一个值
ID
:表示在一个xml文档中该属性值必须唯一,值不能以数字开头
4、Schema约束
Schema也是一种用于定义和描述 XML 文档结构与内容的模式语言,其出现是为了克服 DTD 的局限性。
① Schema约束特点:
◆ XML Schema符合XML语法结构。
◆ DOM、SAX等XML API很容易解析出XML Schema文档中的内容。
◆ XML Schema对名称空间支持得非常好。
◆ XML Schema比XML DTD支持更多的数据类型,并支持用户自定义新的数据类型。
◆ XML Schema定义约束的能力非常强大,可以对XML实例文档作出细致的语义限制。
◆ XML Schema不能像DTD一样定义实体,比DTD更复杂,但Xml Schema现在已是w3c组织的标准,它正逐步取代DTD。
② 名称空间:告诉xml文档的哪个元素被哪个schema文档约束,在一个xml文档中不同的标签可以受到不同的schema文档的约束
◆ 一个名称空间受到schema文档约束的情况
//book.xsd文件
<?xml version="1.0" encoding="UTF-8" ?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.itcast.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>
<?xml version="1.0" encoding="UTF-8"?>
<itcast:书架 xmlns:itcast="http://www.itcast.cn[解释:名称空间别名]"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance[解释:公开的名称空间]"
xsi:schemaLocation="http://www.itcast.cn[解释:名称空间别名] book.xsd[解释:schema文件地址]">
<itcast:书>
<itcast:书名>JavaScript网页开发</itcast:书名>
<itcast:作者>张孝祥</itcast:作者>
<itcast:售价>28.00元</itcast:售价>
</itcast:书>
</itcast:书架>
[解释:xml文档定义了一个itcast名称的名称空间,别名是http://www.itcast.cn。书签标签引用了ITcast名称的名称空间。http://www.itcast.cn的schema文件地址在当前目录下的book.xsd中]
◆ 名称空间受到多个schema文档约束的情况
<书架 xmlns="http://www.it315.org/xmlbook/schema"
xmlns:demo="http://www.it315.org/demo/schema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.it315.org/xmlbook/schema http://www.it315.org/xmlbook.xsd
http://www.it315.org/demo/schema http://www.it315.org/demo.xsd">
<书>
<书名>JavaScript网页开发</书名>
<作者>张孝祥</作者>
<售价 demo:币种=”人民币”>28.00元</售价>
</书>
</书架>
◆ 默认名称空间的情况
<书架 xmlns="http://www.it315.org/xmlbook/schema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=“http://www.it315.org/xmlbook/schema book.xsd">
<书>
<书名>JavaScript网页开发</书名>
<作者>张孝祥</作者>
<售价>28.00元</售价>
</书>
</书架>
◆ 不使用名称空间
<书架 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="xmlbook.xsd">
<书>
<书名>JavaScript网页开发</书名>
<作者>张孝祥</作者>
<售价>28.00元</售价>
</书>
</书架>