--默认值不起作用-->
◆注意事项:
仅仅是定义元素中的内容为文本内容用#PCDATA,其他地方都用CDATA
例如:
ELEMENTpackage(#PCDATA)>
ELEMENTpackagecolorCDATA"ffffffff">
1.16属性类型
1)CDATA:
文本内容。
2)ID:
属性的值在xml中是唯一的(该属性值不可重复)。
3)枚举(en1|en2…):
属性的值只能是列举的其中之一。
1.17属性值的约束
1)#REQUIRED:
当前这个属性必须在标签里出现(即要写出来),则此时默认值无效了。
例如:
ATTLISToracleuserCDATA"user"#REQUIRED>
2)#FIXED:
属性里的值为固定值(值要给出),或者值是其列举的其中之一。
例如:
ATTLISToracleuserCDATA"user"#FIXED("user"|"admin")>
3)默认值"xxx":
若在默认值位置直接给定值,那么就是默认值。
例如:
ATTLISToracleidCDATA"sss">
1.18DTD命名空间介绍
1)命名空间(NameSpace),XML文件允许自定义标记,所以可能出现来自不同源DTD或Schema文件的同名标记,为了区分这些标记,就需要使用命名空间。
2)命名空间的目的是有效的区分来自不同DTD的相同标记,例如下例xml文件中使用了命名空间区分开“表格”和“桌子”。
例如:
table>
这是一个表格
table>
table>
coffeetable
wood
table>
2、Schema简介
2.1Schema的作用
因为DTD无法解决命名冲突问题,所以出现了Schema,它是DTD的替代者。
DTD和Schema的功能都是用于描述XML结构的。
Schema:
W3C提出的一套用于约束XML元素的标准,支持命名空间,和DTD的作用一致。
DTD因为定义语法相对困难,且不是标准的XML形式去描述定义的。
而Schema本身就是xml(所以也被称作是自描述的语言),去约束另一个xml元素的内容相对DTD更易维护。
2.2Schema文件的扩展名xsd
XMLSchemaDifinition(简称XSD,遵循W3C标准)。
3、
Java解析XML
3.1Java与XML共同点
有很多共同点,比如跨平台、与厂商无关,目前为止Java对XML的解析比其他语言更完善(Java是支持XML最好的语言)。
3.2Java解析XML有两种方式
1)DOM:
文本对象模型(DocumentObjectModel)
2)SAX:
基于xml的简单API(SimpleAPIForXML)
3)嵌入式设备中常用SAX进行解析。
例如android中就是使用SAX作为解析xml文件的工具的。
Android中还有一种叫做Pull解析。
3.3JDOM/DOM4J
目前常用的2种解析XML文件的API。
3.4DOM解析
解析XML是以树状结构进行解析的。
DOM在解析XML的时候会将整个xml内容解析出来,以Element(元素)描绘每个节点和嵌套关系,并载入内存。
1)关键字:
树(Document)
2)优点:
把xml文件在内存中构造树型结构,可以遍历和修改节点,因为它知道节点的所有关系。
3)缺点:
因为解析时就将整个xml文件全部载入到内存,所以解析过长,内存开销大。
3.5SAX解析
解析XML是把xml文件作为输入流,触发标记开始,内容开始,标记结束等动作。
1)关键字:
流(Stream)
2)优点:
解析可以立即开始,速度快,没有内存压力。
3)缺点:
不能对节点做修改。
3.6案例:
使用DOM4J包的核心API解析xml文件
我们使用DOM工具,来自DOM4J,非常流行的用于解析xml的DOM工具,还有一种常用的叫做JDOM,解析步骤:
1)创建用于解析Xml文件的读取器SAXReader;
2)使用SAXReader读取指定的输入流来解析xml文件;
3)第2步的方法会返回一个Document对象,描述整个文档,通过该文档对象获取根标签(标记)Root;
4)根据树的组成形式,逐一解析。
step1:
创建DBinfo类,其中属性有
privateStringurl;//连接的urlprivateStringdriver;//连接的驱动
privateStringusername;//数据库用户名privateStringpassword;//数据库密码
privateStringdbName;//数据库连接名privateStringattUser;//数据库标签的属性user
……各自对应的get/set方法
step2:
创建XMLUtils工具类用于解析xml文件(xml文件内容见第五章)属性如下:
/**定义常量,用于描述当前解析的XML中出现的标签名*/
privatestaticfinalStringELEMENT_JDBC="jdbc";
privatestaticfinalStringELEMENT_ORACLE="oracle";
privatestaticfinalStringELEMENT_MYSQL="mysql";
privatestaticfinalStringELEMENT_URL="url";
privatestaticfinalStringELEMENT_DRIVER="driver";
privatestaticfinalStringELEMENT_USERNAME="username";
privatestaticfinalStringELEMENT_PASSWORD="password";
privatestaticfinalStringATTRIBUTE_USER="user";
step3:
在XMLUtils工具类中,添加xmlToDBInfo(InputStreaminput)方法
/**方法xmlToDBInfo:
解析xml文件,将配置的所有数据库连接返回*/
publicstaticListxmlToDBInfo(InputStreaminput){
/**参数InputStreaminput说明:
因为我们要使用DOM去解析XML文件,那么一
定会通过输入流去获取Xml文件中的数据,无论这个文件来自网络还是本地文件,我们在程序中都是通过输入流的形式读取的。
*/
//1使用dom4j需要导包:
dom4j-1.6.1.jar
SAXReaderreader=newSAXReader();
/**解析xml前调用该方法!
该方法默认值为false,设置为true的作用是检查xml的合法性,验证DTD。
*/
reader.setValidation(false);//此处建议先false,否则DTD稍有错误就将报错!
//2导包:
org.dom4j.Document
Documentdocument;
try{document=reader.read(input);//读取并解析文件
}catch(Exceptione){e.printStackTrace();
thrownewRuntimeException("数据读取错误!
",e);}
//3导包:
org.dom4j.Element
/**root.getName()用于获取当前标签的名字,这里应该是jdbc*/
Elementroot=document.getRootElement();
if(!
"jdbc".equals(root.getName())){
thrownewRuntimeException("数据格式错误,根应该是:
"+ELEMENT_JDBC);}
//4逐一解析
/**root.elements();该方法获取root元素下的所有子元素并以集合的形式返回。
*root.element(Stringname);获取指定名字的子元素
*root.elements(Stringname);获取指定名字的所有子元素*/
ListchildList=root.elements();
/**将oracle元素和mysql元素保存的内容存放到相应的DBInfo对象中,再将这些对象存入一个集合并返回,最终完成解析工作。
*/
Listinfos=newArrayList();
for(Elementchild:
childList){
//将oracle或mysql标签转化为DBInfo对象并存入集合infos
DBInfoinfo=toDBInfo(child);infos.add(info);}
returninfos;}
step4:
将标签内容转化为DBInfo对象,添加toDBInfo(Elementelement)方法
privatestaticDBInfotoDBInfo(Elementelement){
DBInfoinfo=newDBInfo();
//ElementurlElement=element.element(ELEMENT_URL);//现拿到标签,再拿标签内容
//Stringurl=urlElement.getText();
Stringurl=element.elementText(ELEMENT_URL);//同上面两步,直接获取子元素文本
Stringdriver=element.elementText(ELEMENT_DRIVER);
Stringusername=element.elementText(ELEMENT_USERNAME);
Stringpassword=element.elementText(ELEMENT_PASSWORD);
StringattUser=element.attributeValue(ATTRIBUTE_USER);//获取标签的属性值
StringdbName=element.getName();//获取当前标签的名字
info.setAttUser(attUser);info.setDbName(dbName);
info.setDriver(driver);info.setPassword(password);
info.setUrl(url);info.setUsername(username);
returninfo;}
step5:
测试
FileInputStreamfis=newFileInputStream("src"+File.separator+
"day03"+File.separator+"part2"+File.separator+"db_info.xml");
Listinfos=XMLUtils.xmlToDBInfo(fis);
for(DBInfoinfo:
infos){
System.out.println("db_name:
"+info.getDbName());
System.out.println("url:
"+info