------- android培训、java培训、期待与您交流! ----------
xml
1.xml的作用:在xml语言中,他允许用户自定义标签,一个标签可以用于描述一段数据,一个标签可以分为开始标签和结束标签,在开始标签和结束标签之间,又可以使用其他标签描述其他数据
以此来实现数据关系的描述
例如
<中国>
<北京>
<海淀></海淀>
<丰台></丰台>
</北京>
<湖南>
<长沙></长沙>
<岳阳></岳阳>
</湖南>
<湖北>
<武汉></武汉>
<荆州></荆州>
</湖北>
</中国>
xml的常见应用:xml技术除了用于保存有关系的数据之外,他还经常用作软件配置文件,用来描述程序模块之间的关系,在一个软件系统中,为了提高程序的灵活性,它所启动的模块由其
配置文件决定,如一个软件启动时,他需要启动A,B两份模块,而A,B这两个模块在启动时,又分别需要A1,A2,B1,B2模块的支持,为了准确描述这种关系,此时使用xml文件最合适
2.xml的语法
一个xml文件分为以下几个内容
。文档声明
。最简单的文档声明:<?xml version="1.0" ?>
。用encoding属性说明文档的字符编码:<?xml version="1.0" encoding="gb2312" ?>
。用standalone属性说明文档是否独立:<?xml version="1.0" encoding="gb2312" standlone="yes" ?>standlone表示是否是独立的(独立的表示的是会依赖其他的文件)
。元素
。元素就是标签例如<a>www</a>含标签体<a></a>不含标签体,简写为<a/>,不允许交叉嵌套标签,良好的xml文档必须只有一个跟标签,标签中的为内容可能会有回车和换行
。元素的命名规范,一个xml文件可以包含字母,数字,以及一些其他的可见字符,但必须遵守以下规范
。标签区分大小写<p>和<P>是两个不同的标签
。不能以数字或下划线开头
。不能包含空格和冒号
。不能以xml开头
。属性
。一个标签可以有多个属性,每个属性可以有自己的名称和取值。例如<input name="text">
。属性值一定要用"(双引号)或'(单引号)引起来
。定义属性必须要遵循和标签相同的命名规范
。在xml技术中,标签属性所描述的信息,也可以也可以被改成子元素来来描述。例如
<input>
<name>text</name>
</input>
。注释
.和html相同,用<!--注释-->格式,注释不能在xml声明之前,注释不能嵌套
。CDATA区,特殊字符
。在编写xml文件时,有时有些内容可能不想让解析引擎解析执行。而是当做原始数据用来处理,遇到这种情况,可以把这些内容放在CDATA区中
。语法
<![CDATA[
<iiiii>
<br/>
</iiiii>
]]>
。处理指令
。简称pi,用来指挥解析引擎如何解析xml文件内容,例如可以使用xml-stylesheet指令,通知xml解析引擎应用css文件显示xml文件内容
<?xml-stylesheet type="text/css" href="1.css"?> 必须以?开头?结尾,xml文件声明就是一个处理指令
。转义字符
。& &
。< <
。> >
。" "
。’ '
3.xml约束概述
。什么是xml约束
。在xml技术里,可以编写一个文档来约束xml文档的书写规范,这称为xml的约束
。常用的xml约束技术
。xml DTD 语法介绍
当引用的文件在本地时可以采用如下格式
<!DOCTYPE 文档根节点 SYSTEM “DTD文件URL”>
例如<!DOCTYPE 书架 SYSTEM “book.dtd”>表示从书架这个节点开始遵循book.dtd约束。
元素定义1
<!ELEMENT 元素名称 元素类型或内容>
例如:<!ELEMENT 书架(书+)>
<!ELEMENT 书(书名,作者,售价)> 用逗号分隔,出现顺序必须与声明一致,用|分隔,表示只能任选其一
<!ELEMENT 书名(#PCDATA)>
在元素内容中也可以使用+ * ?来表示文件的出现次数,?表示出现0次或1次,+表示出现1次或多次,*表示出现0次或多次
也可以写在文档内部
<!DOCTYPE 购物车[
<!ELEMENT 肉 EMPTY>
]>
属性定义
<ATTLIST 元素名
属性名1 属性值类型 设置说明
属性名2 属性值类型 设置说明
>
例子
<ATTLIST 商品
类别 CDATA #REQUIRED //#REQUIRED代表此类商品是必须的
颜色 CDATA #IMPLIED //#IMPLIED代表此类商品可写可不写,#FIXED则表示不能够修改,必须提供固定值类型
>
常用的属性值类型有:1.CDATA表示普通文本字符串
2.ENUMERATED(枚举)
3.ID
4.ENTITY(实体),实体分为两种类型,引用实体和参数实体
1.引用实体:<!ENTITY 实体名称 "实体内容">,例如<!ENTITY copyright "i am a program">,使用语法 &实体名称; ,如©right;
2.参数实体:参数实体被dtd文件自己使用 <!ENTITY % 实体名称 "实体内容"> 使用语法 %实体名称
。xml Schema
4.xml的解析
xml解析方式分为两种dom和sax
dom解析的优点是对文档的增删改查比较方便,缺点是占用内存
sax解析的优点是占用内存小,解析速度较快,缺点是不适合增删改查
dom解析实例代码
import java.io.File;
import java.io.FileOutputStream;
import java.util.Arrays;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class DemoXml1 {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); //拿到工厂对象
DocumentBuilder db = dbf.newDocumentBuilder(); //拿到文档解析器
Document d = db.parse(new File("G:\\javaProject\\myxml\\src\\com\\itcast\\xml\\MyXml.xml")); //解析文档
DemoXml1 dx = new DemoXml1();
dx.test2(d.getElementsByTagName("书架").item(0)); //调用便利方法
//dx.test(d);
}
public void test1(Document d) throws Exception {
Element e = d.getDocumentElement();
System.out.println(e.getNodeName()); //由打印可看出e为根节点
}
public void test2(Node d) throws Exception { //便利节点,把所有节点的名称全部打印出来
if(d instanceof Element) {
System.out.println(d.getNodeName());
System.out.println(d.getTextContent().trim());
}
NodeList nl = d.getChildNodes();
for(int i = 0; i < nl.getLength(); i++) {
test2(nl.item(i));
}
}
@Test
public void add() throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); //拿到工厂对象
DocumentBuilder db = dbf.newDocumentBuilder(); //拿到文档解析器
Document d = db.parse(new File("G:/javaProject/myxml/src/com/itcast/xml/MyXml.xml")); //解析文档
//创建新的节点
Element e = d.createElement("售价");
e.setTextContent("180元");
d.getElementsByTagName("书").item(0).insertBefore(e, d.getElementsByTagName("书").item(0).getChildNodes().item(0));
//在指定的位置之前插入新的节点
TransformerFactory tf = TransformerFactory.newInstance();
Source s = new DOMSource(d);
Transformer t = tf.newTransformer();
Result r = new StreamResult(new FileOutputStream("G:/javaProject/myxml/src/com/itcast/xml/MyXml.xml"));
t.transform(s, r); //将改变后的xml文件写进磁盘
}
@Test
public void delete() throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); //拿到工厂对象
DocumentBuilder db = dbf.newDocumentBuilder(); //拿到文档解析器
Document d = db.parse(new File("G:/javaProject/myxml/src/com/itcast/xml/MyXml.xml")); //解析文档
d.getElementsByTagName("书").item(0).removeChild(d.getElementsByTagName("书").item(0).getChildNodes().item(1)); //删除指定节点
//在指定的位置之前插入新的节点
TransformerFactory tf = TransformerFactory.newInstance(); //拿到能得到转换器的转换工厂对象
Source s = new DOMSource(d); //创建源
Transformer t = tf.newTransformer(); //通过工厂拿到Transformer对象
Result r = new StreamResult(new FileOutputStream("G:/javaProject/myxml/src/com/itcast/xml/MyXml.xml")); //拿到目标
t.transform(s, r); //将改变后的xml文件写进磁盘
}
}
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;
import org.xml.sax.helpers.DefaultHandler;
public class SaxDemo {
public static void main(String[] args) throws Exception {
//首先拿到得到解析器的工厂对象
SAXParserFactory spf = SAXParserFactory.newInstance();
//拿到解析器对象
SAXParser sp = spf.newSAXParser();
//通过解析器拿到读取器对像
XMLReader xmlr = sp.getXMLReader();
//在读取器内部设置文件处理器对象
xmlr.setContentHandler(new MyContentHandler());
//解析文档
//xmlr.parse("G:/javaProject/myxml/src/com/itcast/xml/MyXml.xml");
//嫌麻烦的话还有第二种方式
sp.parse("G:/javaProject/myxml/src/com/itcast/xml/MyXml.xml", new DefaultHandler(){
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
System.out.println(new String(ch, start, length));
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
System.out.println("qname" + qName);
}
@Override
public void startElement(String uri, String localName,
String qName, Attributes attributes) throws SAXException {
System.out.println("qname" + qName);
for(int i = 0; i < attributes.getLength(); i++) {
System.out.println("name" + attributes.getQName(i));
System.out.println("name" + attributes.getValue(i));
}
}
});
}
}
//定义一个内部类,该内部类实现了ContentHandler这个接口
class MyContentHandler implements ContentHandler {
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
System.out.println(new String(ch, start, length));
}
@Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
System.out.println("qName=" + qName);
}
@Override
public void endPrefixMapping(String prefix) throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void ignorableWhitespace(char[] ch, int start, int length)
throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void processingInstruction(String target, String data)
throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void setDocumentLocator(Locator locator) {
// TODO Auto-generated method stub
}
@Override
public void skippedEntity(String name) throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void startElement(String uri, String localName, String qName,
Attributes atts) throws SAXException {
System.out.println("uri=" + uri);
System.out.println("localName=" + localName);
System.out.println("qName=" + qName);
}
@Override
public void startPrefixMapping(String prefix, String uri)
throws SAXException {
// TODO Auto-generated method stub
}
}
5.Dom4j解析xml
import java.io.FileOutputStream;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import org.junit.Test;
public class TestDom4j {
@Test
public void changeXml() throws Exception {
//1.拿到读取器对象
SAXReader saxr = new SAXReader();
//2.利用读取器读取指定的文档,得到document对象
Document document = saxr.read("G:\\javaProject\\myxml\\src\\com\\itcast\\xml\\MyXml.xml");
//3.拿到该文档的根节点元素
Element root = document.getRootElement();
List list = root.elements("书");
Element e1 = (Element)list.get(1);
Element e2 = (Element)e1.element("售价");
//修改指定元素的文本内容
e2.setText("10");
//拿到漂亮的输出格式,哈哈,也可以拿到压实的输出格式
OutputFormat of = OutputFormat.createPrettyPrint();
//为了避免乱码的产生,应该提前设置好编码,建议使用OutputStream,不建议使用Reader
of.setEncoding("utf-8");
XMLWriter xmlw = new XMLWriter(new FileOutputStream("G:\\javaProject\\myxml\\src\\com\\itcast\\xml\\MyXml.xml"), of);
xmlw.write(document);
}
@Test
public void addXml() throws Exception {
Document document = DocumentHelper.createDocument();
Element root = DocumentHelper.createElement("root");
root.setText("ok");
document.add(root);
//拿到漂亮的输出格式,哈哈,也可以拿到压实的输出格式
OutputFormat of = OutputFormat.createPrettyPrint();
//为了避免乱码的产生,应该提前设置好编码,建议使用OutputStream,不建议使用Reader
of.setEncoding("utf-8");
XMLWriter xmlw = new XMLWriter(new FileOutputStream("G:\\javaProject\\myxml\\src\\com\\itcast\\xml\\Xml.xml"), of);
xmlw.write(document);
}
}