xml文件概念
xml是可扩展的标签语言,它的标签可以根据需要自定义,和html不同,xml的标签即可以使用中文,也可以使用英文
作用:
- 数据存储:在没有真正数据库的前提下,当做小型的数据库来用是可以的.
- 数据传输:在服务端创建xml文件,以io形式将文件传递给客户端,客户端拿到后,提取出xml文件中的有用内容,进行处理
- 软件配置:比如在JAVAEE应用中的WEB-INF/web.xml文件,尤为重要
基本语法
前言:
一个xml文件,加载到内存后,会形成一个倒状的树结构,xml文件内容越多,耗用的内存就越大
文档声明:就是xml文件中的第一行代码:
约束
- 作用:用于约束xml如何书写的一种技术,这个技术就称作约束模式.约束模式分为两大类:DTD和Schema
如何编写DTD
定义元素
普通定义:
在DTD文件中使用<!ELEMENT 元素名 (类别)>或<!ELEMENT 元素名称 (元素内容)>来对元素进行定义.
空元素定义:
空元素通过类别关键词EMPTY进行声明:<!ELEMENT 元素名称 EMPTY>例子:<!ELEMENT br EMPTY>
只有PCDATA元素定义:
只有 PCDATA 的元素通过圆括号中的 #PCDATA 进行声明:<!ELEMENT 元素名称 (#PCDATA)>例子:<!ELEMENT from (#PCDATA)>
带有任何内容的元素定义:
通过类别关键词 ANY 声明的元素,可包含任何可解析数据的组合:<!ELEMENT 元素名称 ANY>例子:<!ELEMENT note ANY>
带有子元素(序列)的元素
带有一个或多个子元素的元素通过圆括号中的子元素名进行声明:<!ELEMENT 元素名称 (子元素名称 1)>或者<!ELEMENT 元素名称 (子元素名称 1,子元素名称 2,.....)>例子:<!ELEMENT note (to,from,heading,body)>
声明只出现一次的元素
<!ELEMENT 元素名称 (子元素名称)>例子:<!ELEMENT note (message)>
后面的其他定义元素的方式不常用,如果项目需要请查阅参考手册.
定义属性
使用<!ATTLIST 元素名称 属性名称 属性类型 默认值>来定义属性,例如:<!ATTLIST payment type CDATA "check">
以下是属性类型的选项:
类型 | 描述 |
---|---|
CDATA | 值为字符数据 (character data) |
(en1|en2|..) | 此值是枚举列表中的一个值 |
ID | 值为唯一的 id |
IDREF | 值为另外一个元素的 id |
IDREFS | 值为其他 id 的列表 |
NMTOKEN | 值为合法的 XML 名称 |
NMTOKENS | 值为合法的 XML 名称的列表 |
ENTITY | 值是一个实体 |
ENTITIES | 值是一个实体列表 |
NOTATION | 此值是符号的名称 |
xml: | 值是一个预定义的 XML 值 |
### 默认值参数可使用下列值:
值 | 解释 |
---|---|
值 | 属性的默认值 |
REQUIRED | 属性值是必需的 |
IMPLIED | 属性不是必需的 |
FIXED value | 属性值是固定的 |
DTD - 实体
实体的出现时为了解决代码太过冗余,提高数据的复用性和可读性
一个内部实体声明
语法:
<!ENTITY 实体名称 "实体的值">
例子:
DTD 例子:
<!ENTITY writer "Bill Gates"> <!ENTITY copyright "Copyright W3School.com.cn">
XML 例子:
<author>&writer;©right;</author>
注释: 一个实体由三部分构成: 一个和号 (&), 一个实体名称, 以及一个分号 (;)。
一个外部实体声明
语法:
<!ENTITY 实体名称 SYSTEM "URI/URL">
例子:
DTD 例子:
<!ENTITY writer SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd"> <!ENTITY copyright SYSTEM "http://www.w3school.com.cn/dtd/entities.dtd">
在java中如何解析xml文件
我们需要提取到xml文件中的有效数据,来用在我们的java代码中,这时xml文件相当于是小型的数据库
解析XML文件为分二个类别,分别是:
01——DOM(DocumentObject Model)方式
W3C推荐的解析XML方式
一次性加载到内存,将XML文件形成一个倒状树结构 从树根开始遍历,这一点思想和JavaScript中DOM是相同的JavaEE学的是DOM4J解析器,开源免费,导入dom4j-1.6.1.jar到工程的classpath路径中Android学的是PULL解析器,开源免费,Android内置PULL解析器所需要的jar包
02——SAX(Simple Api for Xml)方式
多次性加载到内存,按事件方式依次处理
8.04 Java解析XML文件:
遍历每个节点属性值和节点之间的内容
/**
* 遍历每个节点属性和节点之间的内容
*/
public class Demo01 {
/**
* 主函数
*/
public static void main(String[] args) throws Exception{
SAXReader saxReader = new SAXReader();
InputStream is = Demo01.class.getClassLoader().getResourceAsStream("bookstore.xml");
Document xmlDocument = saxReader.read(is);
Element rootElement = xmlDocument.getRootElement();
List<Element> bookElementList = rootElement.elements("book");
//迭代
for(Element bookElement : bookElementList){
//获取book节点的属性id的值
String id = bookElement.attributeValue("id");
//由book节点先定位到title子节点,再获取title子节点之间的内容
String title = bookElement.element("title").getText();
String auth = bookElement.element("auth").getText();
String price = bookElement.element("price").getText();
//提示
System.out.println("编号:"+id);
System.out.println("标题:"+title);
System.out.println("作者:"+auth);
System.out.println("单位:"+price);
System.out.println("======================================");
}
}
}
XPath表达式
什么是XPath
XPath是一个用于在XML文件中,快速查询符合条件标签的技术
为什么要用XPath
如果按照dom4j的传统做法,查找一个具有多层结构的标签,非常麻烦,效率太低,
如果要用XPath,能直接定位该元素,但必须导入dom4j-1.6.1.jar和jaxen-1.1-beta-6.jar
到工程的classpath路径中
XPath常用的API
Stringxpath = “//user[@name=’哈哈’ and @pass=’123’]”;书写一个XPath字符串,属性值要单引号
Elementelement = (Element) xmlDocument.selectSingleNode(xpath);返回一个集合中的第一个元素
Listlist = xmlDocument.selectNodes(xpath) ;返回一个集合
Node是父接口,Element是子接口
Demo1.java
/**
* 使用XPath表达式来定位节点,并获取节点之间的内容
*/
public class Demo02 {
/**
* 主函数
*/
public static void main(String[] args) throws Exception{
SAXReader saxReader = new SAXReader();
InputStream is = Demo07.class.getClassLoader().getResourceAsStream("bookstore.xml");
Document xmlDocument = saxReader.read(is);
//用xpath表达式定位XML文件中的title节点
String xpath = "/bookstore/book/title";
//获取符合xpath表达式匹配的所有节点的第一个
//Element titleElement = (Element) xmlDocument.selectSingleNode(xpath);
//获取符合xpath表达式匹配的所有节点
List<Element> titleElementList = xmlDocument.selectNodes(xpath);
for(Element titleElement : titleElementList){
String title = titleElement.getText();
System.out.println(title);
}
}
}
users.xml
<?xml version="1.0" encoding="UTF-8"?>
<classs>
<user name="哈哈" gender="男" age="22"/>
<user name="呵呵" gender="男" age="23"/>
<user name="嘻嘻" gender="女" age="24"/>
</classs>
Demo2.java
/**
* 用户名是否在XML文件中存在
*/
public class Demo08 {
/**
* 根据用户名和性别在XML文件中查询是否有该用户,
* @param name 用户名
* @param gender 性别
* @return 是否存在,true表示存在,false表示不存在
*/
private static boolean exists(String name,String gender,int age) throws Exception {
boolean flag = false;
SAXReader saxReader = new SAXReader();
InputStream is = Demo08.class.getClassLoader().getResourceAsStream("users.xml");
Document xmlDocument = saxReader.read(is);
String xpath = "//user[@name='"+name+"' and @gender='"+gender+"' and @age>'"+age+"']";
List<Element> userElementList = xmlDocument.selectNodes(xpath);
if(userElementList.size()>0){
flag = true;
}else{
;
}
return flag;
}
/**
* 主函数
*/
public static void main(String[] args) throws Exception{
boolean flag = exists("呵呵","男",20);
if(flag){
System.out.println("存在该用户名");
}else{
System.out.println("不存在该用户名");
}
}
}