您的位置:首页 > 其它

第二天:xml_dtd_dom_jaxp

2012-05-26 19:11 141 查看
u 为什么需要xml

1. 提出问题?

两个程序间通信的时候,数据格式.

2. 用什么方式做配置文件

<serverinfo>

<ip></ip>

<port></port>

<user><user>

<passwd></passwd>

<driver></driver>

</serverinfo>

u 编码问题

默认iso-8859-1

ansi(美国国家标准协会) 编码 ,如果你是中文操作系统 ,则对应 gb2312 ,在日文操作系统上

utf-8编码 ,可以支持多种语言编码.

不同的国家和地区制定了不同的标准,由此产生了 GB2312, BIG5, JIS
等各自的编码标准。这些使用 2
个字节来代表一个字符的各种汉字延伸编码方式,称为 ANSI
编码。在简体中文系统下,ANSI
编码代表 GB2312
编码,在日文操作系统下,ANSI
编码代表 JIS 编码。


XML声明由以下几个部分组成:

version- -文档符合XML1.0规范,我们学习1.0

encoding - -文档字符编码,比如”gb2312”

standalone- -文档定义是否独立使用

standalone="yes“

standalone=“no” 默认

如果你在XML文档里面写上gb2312,而在另存为时存为utf-8,那么会打不开。

因为gb2312是属于ANSI的,在中国它就代表的是GB2312,所以存为ANSI即可。

,如果想要存为UTF-8那么在XML中也要写成UTF-8.

u 明确一个概念

在xml中元素=标签=节点

u 在属性值有双引号和单引号的时候

“ " ‘ &aqot;

属性值用双引号(")或单引号(')分隔(如果属性值中有',用"分隔;有",用'分隔)

一个元素可以有多个属性,它的基本格式为:

<元素名属性名="属性值">

特定的属性名称在同一个元素标记中只能出现一次

属性值不能包括<,>, &


XML声明之前不能有注释

注释不能嵌套

有些内容可能不想让解析引擎解析执行,而是当作原始内容处理,用于把整段文本解释为纯字符数据而不是标记的情况。包含大量<、>、&或者"字符。CDATA节中的所有字符都会被当作元素字符数据的常量部分,而不是XML标记。

u 处理指令(了解)

html界面 css

xml 显示 css ,使用处理搞定

案例1:

my.css

name{

font-size: 100px;

font-weight: blod;

color: red;

}

sex{

font-size: 80px;

font-weight: blod;

color: blue;

}

age{

font-size: 50px;

font-weight: blod;

color: green;

}

在myClass.xml文件中使用

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

<?xml-stylesheet type="text/css"href="my.css"?>

<class>

<!--注释-->

<stu id='a0011'>

<name>杨过</name>

<sex>男</sex>

<age>20</age>

<介绍>aa</介绍>

<除毛净重>200</除毛净重>

</stu>

<stu id="a002">

<name>李莫愁</name>

<sex>女</sex>

<age>30</age>

</stu>

</class>

总结:

遵循如下规则的XML文档称为格式正规的XML文档:

l 语法规范

XML声明语句

<?xml version="1.0"encoding="gb2312"?>

必须有且仅有一个根元素

标记大小写敏感

属性值用引号

标记成对

空标记关闭

元素正确嵌套

u 为什么需要dtd

去约束指定的XML文件。

l 常用的约束技术

XML DTD


XMLSchema


u 写dtd的注意事项

1. dtd文件要保存成 utf-8编码

要求:能够根据DTD写出XML文档。

u 校验xml的有效性(自己写一个HMTL文件,非常厉害)

1. 我们写一个 check.html文件,用于去校验load文件的有效性 (javascript(livescript) jscript(微软))

<html>

<head>

<scriptlanguage="javascript">

var xmldom= new ActiveXObject("Microsoft.XMLDOM");

xmldom.validateOnParse=true;

xmldom.load("myClass2.xml");

document.writeln("错误信息是:"+xmldom.parseError.reason);

document.writeln("错误行号:"+xmldom.parseError.line);

</script>

</head>

<body>

</body>

</html>

2. dtd文件时 myClass.dtd

<!ELEMENT 班级 (学生+)>

<!ELEMENT 学生 (名字,年龄,介绍)>

<!ELEMENT 名字 (#PCDATA)>

<!ELEMENT 年龄 (#PCDATA)>

<!ELEMENT 介绍 (#PCDATA)>

3. 我的对myClass.dtd写的xml文件myClass2.xml

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

<!DOCTYPE 班级SYSTEM "myClass.dtd">

<班级>

<学生>

<名字>周星驰</名字>

<年龄>23</年龄>

<介绍>学习刻苦</介绍>

</学生>

<学生>

<名字>林青霞</名字>

<年龄>32</年龄>

<介绍>是一个好学生</介绍>

</学生>

</班级>

4. 如何把外部的dtd改成内部的dtd 比如 myClass2.xml修改成内部dtd去约束

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

<!DOCTYPE 班级 [

<!ELEMENT 班级 (学生+)>

<!ELEMENT 学生 (名字,年龄,介绍)>

<!ELEMENT 名字 (#PCDATA)>

<!ELEMENT 年龄 (#PCDATA)>

<!ELEMENT 介绍 (#PCDATA)>

]>

<班级>

<学生>

<名字>周星驰</名字>

<年龄>23</年龄>

<介绍>学习刻苦</介绍>

</学生>

<学生>

<名字>林青霞</名字>

<年龄>32</年龄>

<介绍>是一个好学生</介绍>

</学生>

</班级>

引用DTD约束的两种方式。

l XML文件使用 DOCTYPE
声明语句来指明它所遵循的DTD文件,DOCTYPE声明语句有两种形式:


当引用的文件在本地时,采用如下方式:

<!DOCTYPE文档根结点 SYSTEM"DTD文件的URL">

例如: <!DOCTYPE
书架 SYSTEM “book.dtd”>。


当引用的文件是一个公共的文件时,采用如下方式:


<!DOCTYPE文档根结点 PUBLIC"DTD名称""DTD文件的URL">

例如:<!DOCTYPE web-app PUBLIC


"-//SunMicrosystems, Inc.//DTD Web Application 2.3//EN"

"http://java.sun.com/dtd/web-app_2_3.dtd">

u 属性的顺序问题

元素的顺序有要求,按照规定的顺序写,

属性的顺序没有要求.

属性的值,不能用数字开头.(就像javasrcriprt的id也不能以数字开头)

u 实体

实体分为:

引用实体,它是在dtd中定义的 <!ENTITYintro "这是一个好同志呀!">,可以放在dtd文件后,

该实体是在xml文件中使用, 具体是:

<介绍>学习刻苦&intro; &intro;</介绍>

参数实体

他在dtd中定义,并且在dtd中使用.

最后的myClass2.xml myClass.dtd check.html

myClass2.xml 内容

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

<!DOCTYPE 班级 SYSTEM "myClass.dtd">

<班级>

<学生 学号="a123"性别="女" 大哥="a0002">

<名字>周星驰 &intro;</名字>

<年龄>23</年龄>

<介绍>学习刻苦 &intro; &intro;</介绍>

</学生>

<学生 住址="天津" 性别="男" 学号="a0002" 大哥="a0002 a0003">

<名字>林青霞</名字>

<年龄>32</年龄>

<介绍>&intro;是一个好学生</介绍>

</学生>

<学生 住址="大观园" 性别="男" 学号="a0003" 大哥="a0002">

<名字>贾宝玉</名字>

<年龄>16</年龄>

<介绍>是一个好学生 &intro;</介绍>

</学生>

</班级>

对应的 myClass.dtd文件

<!ELEMENT 班级 (学生+)>

<!ENTITY % tagname "名字">参数实体一定要放在它使用的前面。

<!ENTITY % tagname1 "名字gg">

<!ENTITY % tagname2 "名字kk">

<!ELEMENT 学生 (%tagname;,年龄,介绍)>

<!ATTLIST 学生

住址 CDATA #IMPLIED

学号 ID #REQUIRED

大哥 IDREFS #REQUIRED

性别 (男|女) #REQUIRED

公司 CDATA #FIXED "ibm"

>

<!ELEMENT %tagname; (#PCDATA)>

<!ELEMENT 年龄 (#PCDATA)>

<!ELEMENT 介绍 (#PCDATA)>

<!ENTITY intro "这是一个好同志呀!">

check.html文件内容

<html>

<head>

<script language="javascript">

var xmldom= newActiveXObject("Microsoft.XMLDOM");

xmldom.validateOnParse=true;

xmldom.load("myClass2.xml");

document.writeln("错误信息是:"+xmldom.parseError.reason);

document.writeln("错误行号:"+xmldom.parseError.line);

</script>

</head>

<body>

</body>

</html>

CATEGORY(HandTool|Table|Shop-Professional) "HandTool"
这种其实也在XMl中可写可不写的属性,写的话可以设置三种之一,不写的话,
在使用的时间,它会自己认为有这个属性,并且这个属性为默认值,十分重要。

PARTNUMCDATA #IMPLIED 这种是在XML中可写可不写的属性。

且记:在保存DTD的时间,要把它保存为UTF-8.

u 复杂的dtd的案例

1. 产品目录的dtd文件 product.dtd

<!ENTITY AUTHOR "John Doe">

<!ENTITY COMPANY "JD Power Tools,Inc.">

<!ENTITY EMAIL"jd@jd-tools.com">

<!ELEMENTCATALOG (PRODUCT+)>

<!ELEMENT PRODUCT

(SPECIFICATIONS+,OPTIONS?,PRICE+,NOTES?)>

<!ATTLIST PRODUCT

NAME CDATA #IMPLIED

CATEGORY (HandTool|Table|Shop-Professional)"HandTool"

PARTNUM CDATA #IMPLIED

PLANT (Pittsburgh|Milwaukee|Chicago)"Chicago"

INVENTORY(InStock|Backordered|Discontinued) "InStock">

<!ELEMENT SPECIFICATIONS (#PCDATA)>

<!ATTLIST SPECIFICATIONS

WEIGHT CDATA #IMPLIED

POWER CDATA #IMPLIED>

<!ELEMENT OPTIONS (#PCDATA)>

<!ATTLIST OPTIONS

FINISH (Metal|Polished|Matte)"Matte"

ADAPTER (Included|Optional|NotApplicable)"Included"

CASE (HardShell|Soft|NotApplicable)"HardShell">

<!ELEMENT PRICE (#PCDATA)>

<!ATTLIST PRICE

MSRP CDATA #IMPLIED

WHOLESALE CDATA #IMPLIED

STREET CDATA #IMPLIED

SHIPPING CDATA #IMPLIED>

<!ELEMENT NOTES (#PCDATA)>

2. .针对 product.dtd写的 product.xml

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

<!DOCTYPE CATALOG SYSTEM"product.dtd">

<CATALOG>

<PRODUCT INVENTORY="InStock"NAME="冰箱"CATEGORY="Shop-Professional" PLANT="Chicago" >

<SPECIFICATIONS WEIGHT="50"POWER="100">

你好吗,这个不错!

</SPECIFICATIONS>

<OPTIONS FINISH="Polished"ADAPTER="NotApplicable" CASE="NotApplicable">

xxx

</OPTIONS>

<PRICE MSRP="123"WHOLESALE="20" STREET="90" SHIPPING="400">

</PRICE>

<NOTES>

xxx

</NOTES>

</PRODUCT>

</CATALOG>

XML解析API:

Jaxp(sun)、dom4j(这个效率更加高,不用学习jdom,因为很明显dom4j已经超越了jdom)

之所以学习jaxp它的效率是最低的,因为解析这个XML的标准是sun公司制定的,所以要学习它。

dom原理图.bmp

JAXP 开发包是J2SE的一部分,它由javax.xml、org.w3c.dom
、org.xml.sax包及其子包组成


在 javax.xml.parsers包中,定义了几个工厂类,程序员调用这些工厂类,可以得到对xml文档进行解析的 DOM
或 SAX的解析器对象。


DocumentBuilderFactory:定义工厂API,使应用程序能够从 XML
文档获取生成 DOM 对象树的解析器。

u dom技术(JAXP)注意,以下为用JAXP
API 操作XML。


其实,JAXP的操作方式与JS对html的文档操作极为相似。

1. 所有的操作都是对myClass.xml的文件

<?xml
version="1.0"
encoding="utf-8"
standalone="no"?><班级>
<学生sex="男">
<名字>周星驰</名字>
<年龄>43</年龄>
<介绍>学习刻苦</介绍>
</学生>
<学生sex="女">
<名字>林青霞</名字>
<年龄>32</年龄>
<介绍>是一个好学生</介绍>
</学生>

</班级>

2. 对文件进行遍历的代码

Dom中的所有节点都被看成一个Node,只是类型不同,有元素节点,文本节点,属性节点等。

在xml里面空白位置被当做文本节点处理。

publicstaticvoid list(Node node){

if(node.getNodeType()==Node.ELEMENT_NODE){
System.out.println("该节点名字是"+node.getNodeName());
}//排除空白节
NodeList nl=node.getChildNodes();
//遍历所有的子节点
for(inti=0;i<nl.getLength();i++){

Nodenode2=nl.item(i);
list(node2);
}
}

3. 读取某一个节点

//读取第一个学生的名字.
publicstaticvoid read(Document doc){

//1.得到根元素 Element
是 Node 子类,它的能力比Node
强,

Element e=doc.getDocumentElement();
//2.得到学生节点对象,它的返回是一个node,是element的父类,也就是从大向小的转,所以要强转,如果从小向大转不用强制转换。
Element name=(Element)e.getElementsByTagName("名字").item(1);

System.out.println(name.getTextContent());
}

4. 读取属性

//读取属性
publicstaticvoid readAttr(Document doc){
//得的根元素
Element root=doc.getDocumentElement();
//得到第二个学生节点对象
Element stu2=(Element) root.getElementsByTagName("学生").item(1);

String sexVal=stu2.getAttribute("sex");
System.out.println(sexVal);

}

5. 添加学生

//添加节点(添加学生)
publicstaticvoid addNode(Document doc)
throwsTransformerException{
//创建一个元素节点. Element Node

Element stu=doc.createElement("学生");
Element name=doc.createElement("名字");
name.setTextContent("贾宝玉");
stu.appendChild(name);
//把stu
挂到根元素下
doc.getDocumentElement().appendChild(stu);
//更新文档,因为以上只是在内存中改变了。所以要更新到硬盘上。
//1.得打TransformerFactory
TransformerFactorytff=TransformerFactory.newInstance();
//2.得到一个转化器
Transformer tf=tff.newTransformer();
//3.转化
tf.transform(new DOMSource(doc),
new StreamResult(new File("src/myClass.xml")));
}

6. 给某个元素添加属性

publicstaticvoid addAttribute(Document doc)
throws Exception{
//得到第三个学生的节点对象
Element e=(Element)doc.getElementsByTagName("学生").item(2);
e.setAttribute("sex",
"男");//添加属性
//这是添加属性的第二种方法.
// Attratt=doc.createAttribute("sex2");
// att.setTextContent("女");
// e.setAttributeNode(att);
//更新
TransformerFactorytff=TransformerFactory.newInstance();
Transformer tf=tff.newTransformer();
tf.transform(new DOMSource(doc),
new StreamResult(new File("src/myClass.xml")));
}

7. 删除节点

//删除一个学生
publicstaticvoid delNode(Document doc)
throwsException{
//得到第三个学生的节点对象
Element e=(Element)doc.getElementsByTagName("学生").item(2);
//doc.getDocumentElement().removeChild(e);
//我们在删除某个节点的时候,可以通过得打其父节点,然后将其删除.
e.getParentNode().removeChild(e);
TransformerFactorytff=TransformerFactory.newInstance();
Transformer tf=tff.newTransformer();
tf.transform(new DOMSource(doc),
new StreamResult(new File("src/myClass.xml")));
}

8. 更新元素的内容

//修改学生信息把周星驰的年龄在原来的基础+10;
publicstaticvoid updNode(Document doc)
throwsException{
//得学生
Element e=(Element) doc.getElementsByTagName("年龄").item(0);
//取出年龄的值
String age=e.getTextContent();
int newAge=Integer.parseInt(age)+10;
e.setTextContent(newAge+"");
//更新xml
TransformerFactorytff=TransformerFactory.newInstance();
Transformer tf=tff.newTransformer();
tf.transform(new DOMSource(doc),
new StreamResult(new File("src/myClass.xml")));
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: