xml 语法:
html 于 xml 语法区别:
html语法松散, xml语法严谨
html做页面展示,xml做数据存储
html标签预定义,xml标签自定义
1. dtd约束使用
* 外部dtd:在外部文件中定义dtd, xml中如何引入dtd文件
* 本地dtd文件:<!DOCTYPE SYSTEM "student.dtd">
* 网络dtd文件:<!DOCTYPE students PUBLIC "名称空间" "student.dtd">
student.dtd 定义:
<!--跟节点 students 下可以有若干个 student -->
<!ELEMENT students (student*) >
<!-- 必须要出现 三个标签 -->
<!ELEMENT student (name,age,sex)>
<!-- name 中可以文本 -->
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ELEMENT sex (#PCDATA)>
<!-- student 标签中 numbe 标签必须唯一 -->
<!ATTLIST student number ID #REQUIRED>
student.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE students SYSTEM "student.dtd">
<students>
<student number="xiaoing" >
<name>xiaoming</name>
<age>220</age>
<sex>8</sex>
</student>
</students>
缺点:不能限制文本类型
2. xsd:schema 约束
student.xsd
<?xml version="1.0"?>
<!-- 这里引入schema 的 shema约束
xmlns="http://www.itheima.cn/xml"
targetNamespace="http://www.itheima.cn/xml": 自定义命名空间,xml 中需要引入
xmlns:xsd="http://www.w3.org/2001/XMLSchema": w3c对 schema约束
注意:xmlns:xsd 名称空间的别名,就像c++ 命名空间的别名一样,后面使用都要带上前缀
-->
<xsd:schema xmlns="http://www.itheima.cn/xml"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.itheima.cn/xml" elementFormDefault="qualified">
<!-- 根节点, 名称、类型 -->
<xsd:element name="students" type="studentsType"/>
<!-- 类型,辅助类型,标签中有标签 -->
<xsd:complexType name="studentsType">
<!-- 序列,有顺序 -->
<xsd:sequence>
<!-- student标签 最小 0 个,做多无限个 -->
<xsd:element name="student" type="studentType" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<!-- 子元素类型 -->
<xsd:complexType name="studentType">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="age" type="ageType" />
<xsd:element name="sex" type="sexType" />
</xsd:sequence>
<xsd:attribute name="number" type="numberType" use="required"/>
</xsd:complexType>
<!-- set类型 枚举-->
<xsd:simpleType name="sexType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="male"/>
<xsd:enumeration value="female"/>
</xsd:restriction>
</xsd:simpleType>
<!-- age 类型integer,最小值0,最大值255 -->
<xsd:simpleType name="ageType">
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="0"/>
<xsd:maxInclusive value="256"/>
</xsd:restriction>
</xsd:simpleType>
<!-- 节点属性 -->
<xsd:simpleType name="numberType">
<xsd:restriction base="xsd:string">
<xsd:pattern value="itheima_\d{4}"/>
</xsd:restriction>
</xsd:simpleType>
</xsd:schema>
student.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!--
xsi:schemaLocation="http://www.itheima.cn/xml student.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
引入schema
xmlns="http://www.itheima.cn/xml"
默认名称空间,后面使用不用带上前缀
xmlns:xiaozhi="http://www.itheima.cn/xml"
如果使用之定义名称空间,后面使用标签的时候,都要带上xiaozhi
xiaozhi:student
xiaozhi:name
-->
<students
xmlns="http://www.itheima.cn/xml"
xsi:schemaLocation="http://www.itheima.cn/xml student.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>
<student number="itheima_1001">
<name>xiaozhitongxue</name>
<age>120</age>
<sex>male</sex>
</student>
<student number="itheima_1003">
<name>xiaoheitongxue</name>
<age>20</age>
<sex>female</sex>
</student>
</students>
3. xml解析
** xml常用解析器:
JAXP:sun公司提供解析,支持dom.sax sun公司自己都不用
JDOM: jdom组织开发jdom,没有火起来
DOM4J: 从jdom离职的人开发,非常好用,综合了dom|sax解析
文档位置: docs/index/Quick start(文档快速入手)
文档大纲,学会看文档拷贝过来就行了,里面有例子
1. 本地 xml 数据便利
2. 代码 创建 xml 写入 磁盘
3. xml 字符串 转化为 doucment对象
Book.xml
<?xml version="1.0" encoding="UTF-8"?>
<书架>
<书 出版社="小置出版社">
<书名>挪威的森林</书名>
<作者>村上村树</作者>
<单价>10</单价>
<批发价>20</批发价>
</书>
<书>
<书名>飘</书名>
<作者>尼古拉斯</作者>
<单价>10</单价>
</书>
</书架>
dom4j 解析程序代码:
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;
public class Main {
/**
* 实现 功能 把 student.xml 转化为 List<Student>
*/
@Test
public void test1() throws ClassNotFoundException, DocumentException{
// 方式4: 通过类加载器
ClassLoader classloader=this.getClass().getClassLoader();
// classloader加载文件,从当前包路径下加载资源文件, jdbc.properties在com.denganzhi.bb包下
InputStream inputstream=classloader.getSystemResourceAsStream("com\\dengzhi\\scheme\\student.xml");
// System.out.println(inputstream.getClass());
SAXReader reader = new SAXReader();
// 把 xml 文档加载到 Doucment对象中
Document document = reader.read(inputstream);
Element root=document.getRootElement();
Element studentNode= root.element("student");
// System.out.println(studentNode.getName());
List<Student> stuList=new ArrayList<Student>();
List<Element> listElements = root.elements();
for (Element element : listElements) { // 得到root节点下所有子节点
System.out.println(element.elementText("name")); // 获取子节点 name 节点文本内容
Student stu=new Student();
stu.setAge(Integer.parseInt(element.elementText("age")));
stu.setName(element.elementText("name"));
if(element.elementText("sex").equals("female")){
stu.setSex(Sex.female);
}else{
stu.setSex(Sex.male);
}
stuList.add(stu);
/**
* xiaozhitongxue
xiaoheitongxue
*/
}
System.out.println(stuList);
}
}
XPath 语法使用,快速找到节点某个位置文本,看文档(jaxen-1.1-beta-6.jar需要加入额外jar包)
/***
* XPath语法, 具体使用可以看文档
* @throws DocumentException
*/
@Test
public void test2() throws DocumentException{
//jaxen-1.1-beta-6.jar 需要加入这个jar包
SAXReader reader = new SAXReader();
ClassLoader classloader=this.getClass().getClassLoader();
InputStream inputstream=classloader.getSystemResourceAsStream("com\\dengzhi\\scheme\\Book.xml");
Document document = reader.read(inputstream);
// 书架下 书的第一个节点 下的 书名
Node node=document.selectSingleNode("/书架/书[1]/书名");
System.out.println(node.getText());
// 书架下的所有节点
List<Node> listNodes= document.selectNodes("/书架//*");
for (Node node2 : listNodes) {
System.out.println("node2:"+node2.getName());
}
}
/***
* Xpath语法: 文档中有例子,学会看文档
* /AAA/CCC 从根节点下AAA节点 的CCC节点选取
* //BBB 根节点下的所有BB节点
* /AAA/CCC/DDD/*: DDD下 的所有节点
* /AAA/BBB[1] AAA节点下BBB节点中第一个BBB 节点
* //BBB[@id]: BBB 节点中包含属性 @id节点的
*
*/
资料源码地址:https://download.csdn.net/download/dreams_deng/12344983
4 . Android 中 xml 解析,pull 解析
4.1. xml拼接 生成本地文件
// 拼接xml保存到本地
// 应用:比如 短信、联系人备份就可以 使用xml
StringBuffer sb=new StringBuffer();
sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
sb.append("<student>");
sb.append("<name>");
sb.append("xiaoming");
sb.append("</name>");
sb.append("</student>");
try {
FileOutputStream fos = openFileOutput("student.xml", Context.MODE_PRIVATE);
fos.write(sb.toString().getBytes());
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
4.2. xml 生成使用 android api
// Android 提供xml 序列化 api
XmlSerializer xmlSerializer= Xml.newSerializer();
try {
FileOutputStream fos = openFileOutput("student1.xml", Context.MODE_PRIVATE);
xmlSerializer.setOutput(fos,"utf-8");
// 写文件开头
xmlSerializer.startDocument("utf-8",true);
// student
xmlSerializer.startTag(null,"student");
xmlSerializer.startTag(null,"name");
xmlSerializer.text("小明");
xmlSerializer.endTag(null,"name");
xmlSerializer.startTag(null,"age");
xmlSerializer.text("26");
xmlSerializer.endTag(null,"age");
xmlSerializer.endTag(null,"student");
xmlSerializer.endDocument();
xmlSerializer.endDocument();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
4.2. Anroid xml 解析, 解析原理
解析原理:一个节点一个节点的解析读取
节点类型:
<?xml version='1.0' encoding='utf-8' standalone='yes' ?> //文档开头节点 0
<student> // 开始节点2 , parser.getEventType();
<name> // 开始节点2 , parser.getEventType();
小明 // 文本节点 4 , parser.getEventType();
</name> // 结束节点3 , parser.getEventType();
<age> // 开始节点2
26 // 文本节点 4
</age> // 结束节点3
</student> // 文档结束节点1
Android xml解析代码
/**
* android pull解析,一个节点一个节点的读取
*/
String Tag="denganzhi1";
public void xmlParseMethod(View view) throws IOException, XmlPullParserException {
String filesPath = getFilesDir().getAbsolutePath()+"/student1.xml";
File file=new File(filesPath);
// 获取 一个 xml 解析器
XmlPullParser parser=Xml.newPullParser();
// 获取解析初始化参数
FileInputStream fis=new FileInputStream(file);
parser.setInput(fis,"utf-8");
// 解析xml 文件
int type= parser.getEventType();
// 判断是否已经 解析到文档末尾
while( type!= XmlPullParser.END_DOCUMENT){
Log.e(Tag,"type:"+ type);
if(type == XmlPullParser.START_TAG){
// 开始节点
if( "name".equals(parser.getName()) ){
String str= parser.nextText();
Log.e(Tag, "name:"+str);
}else if("age".equals(parser.getName())){
String age= parser.nextText();
Log.e(Tag,"age:"+age);
}
}
// 让解析器 解析下一个 节点
type =parser.next();
}
fis.close();
}
资料源码地址: https://download.csdn.net/download/dreams_deng/12344983