黑马程序员-XML

------- 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文件声明就是一个处理指令
。转义字符
。&   &amp;
。<   &lt;
。>   &gt;
。"   &quot;
。’   &apos;


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">,使用语法 &实体名称; ,如&copyright;
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);
	} 
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值