# 什么时xml
# xml简介
xml:eXtensible Markup Lauguage (可扩展性标记语言)
特定:可扩展,xml中的标签都可自定义,语法严格,区分大小写
作用:xml的主要作用就是用于简单数据存储,可以用来做配置文件,也可以使用xml进行数据传输
# xml文档声明
<?xml version="1.0" encoding="UTF-8"?> version:版本号,固定值为1.0 encoding:指定文档的码表,默认值为UTF-8 standalone:指定文档是否独立yes或no# 文档中的标签
<xml-body> <book id="100"> <name>Java编程思想</name> <price>136</price> </book> <book id="101"> <name>Java编程思想</name> <price>136</price> <![CDATE[ <hello> // 会将<hello>原样输出 ]]> </book> </xml-body> 1:文档中有且仅有一个根元素 2:元素需要正确闭合 3:元素需要正确嵌套 4:元素名称需要遵守(元素名称区分大小写,数字不能开头)# HTML和XML区别
html语法松散,xml语法严格 html做页面展示,xml做数据存储 html所有标签都是预定义的,xml所有标签都是自定义的
# xml约束
为何需要约束:因为xml的标签都是由用户自定义的,因此在开发时,每个人都可以根据自己的需求来定义xml标签,会导致项目中的xml难以维护,所以需要使用一定的规范机制来约束xml文件中标签的书写
约束方式一:dtd
# 创建xml文件 <?xml version="1.0" encoding="UTF-8"?> <usermsg> <user> <name>zhangsan</name> <age>18</age> <addr>fujian</addr> </user> <user> <name>lisi</name> <age>20</age> <addr>guangdong</addr> </user> </usermsg> # 创建DTD文件来越苏xml文件 <?xml version="1.0" encoding="UTF-8" ?> <!ELEMENT usermsg (user+) > <!ELEMENT user (name,age,addr) > <!ELEMENT name (#PCDATA) > <!ELEMENT age (#PCDATA)> <!ELEMENT addr (#PCDATA)>
# DTD的引入方式 可以单独写在文件中,也可以直接嵌套在xml文件中 可以在xml文件中引入第三方公共的DTD约束文件 <!-- 外部dtd的引入方式 --> <!DOCTYPE 文档根结点 SYSTEM "DTD文件的URL"> 文档根结点:指的是当前xml中的根标签。 SYSTEM:引入的系统中存在文件 "DTD文件的URL":DTD存放的位置 <!-- 引入公共的DTD --> <!DOCTYPE 文档根结点 PUBLIC "DTD名称" "DTD文件的URL"> 文档根结点:指的是当前xml中的根标签。 PUBLIC:表示当前引入的DTD是公共的DTD <!-- 直接在xml文件中写DTD --> <!DOCTYPE 根标签名 [ 具体的标签的约束 ]> <?xml version="1.0" encoding="UTF-8"?> <usermsg> <user> <name>zhangsan</name> <age>18</age> <addr>fujian</addr> </user> <user> <name>lisi</name> <age>20</age> <addr>guangdong</addr> </user> </usermsg> <?xml version="1.0" encoding="UTF-8" ?> <!ELEMENT usermsg (user+) > <!ELEMENT user (name,age,addr) > <!ELEMENT name (#PCDATA) > <!ELEMENT age (#PCDATA)> <!ELEMENT addr (#PCDATA)>
元素 <!ELEMENT 标签名 约束> 约束来限定当前标签中可以有的子标签,或者当前标签中可以书写的内容 “约束”中可以使用一些符号定义标签具体的出现次数 ? 零次或者一次 * 零次或者多次 + 一次或者多次 usermsg(user+) 表示当前的usermsg标签下可以有一个或者多个user标签 , 用来限定当前的子标签出现的顺序user(name,age,addr)user标签下只能有name age addr 子标签,并且必须按照name age addr的顺序书写 | user (name|age,addr) user下可以name或者age ,但必须有addr,并且addr必须name或age后面 #PCDATA 表明该元素可包含任何字符数据,但不能在其中包含任何子元素。只有 PCDATA 的元素通过圆括号中的 #PCDATA 进行声明 EMPTY 表明该元素不能有任何子元素或文本,仅可以使用属性。 ANY 表该元素中可以包含任何DTD中定义的元素内容 如:<!ELEMENT note ANY> <!ELEMENT age EMPTY > 当前的age标签是个空标签,它不能有文本内容约束方式二:schema
# DTD在约束xml时只能引入一个DTD,同时DTD无法对属性及标签中的数据类型做数据类型的限定 <!-- web.xml中使用了schema作为约束 --> <!-- 约束其书写的格式,例如在价格标签中,schema中规定至只能写入数字,如果写入其它形式数据,就会报错 --> # 定义schema文件 在定义Schema文件的时候,由于这个Schema文件本身就是xml,它也要受到别的约束。而这个约束是W3C组织提前定义好的, 在Schema文件中需要提前引入进来在根标签中使用属性进行进入: <schema xmlns="http://www.w3.org/2001/XMLSchema" 引入W3C定义的schema书写的规范 targetNamespace="http://www.doaoao.com/test" 给当前的Schema文件起名字(命名空间) 作用是当哪个xml要引入这个schema约束的时候,必须通过当前targetNamespace 后面书写的uri地址来引入 <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <display-name></display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app>
# xml解析
数据存储在xml文件中,如果想要读取到java内存中,这时就要对xml进行解析
解析xml两个思想:
<!--dom--> dom会将xml文档加载进内存,形成一颗dom树(document对象),将文档的各个组成部分封装为对象。 优点:可以对dom树进行增删改查。 缺点:dom树非常占内存,解析速度慢。 <!--sax--> 逐行读取,基于事件驱动 优点:不占内存,速度快 缺点:只能读取,不能回写
常用的解析器:
jaxp,jdom,dom4j
# 利用dom4j解析xml文件例子(遍历指定元素)
package testxml; import java.util.List; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Element; import org.dom4j.io.SAXReader; import org.junit.Test; public class don4j_test { @Test public void test1() throws DocumentException{ // 创建一个xml解析对象 SAXReader reader = new SAXReader(); // 将xml文件加载到document对象中 Document document = reader.read("src/MyXml.xml"); // 获取xml中的根节点 Element root = document.getRootElement(); // 获取当前节点的所有子节点(返回一个List对象) List list = root.elements(); Element thirdBook = (Element)list.get(1); // "1"表示的是取得根节点中的第二个子节点 String name = thirdBook.element("name").getText(); System.out.println(name); } }
# 利用don4j解析xml例子(遍历所有节点)
package testxml; 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 don4j_test { @Test public void test1() throws DocumentException{ // 创建一个xml解析对象 SAXReader reader = new SAXReader(); // 将xml文件加载到document对象中 Document document = reader.read("src/MyXml.xml"); // 获取xml中的根节点 Element root = document.getRootElement(); treeSelect(root); } // 利用递归遍历所有节点 private void treeSelect(Element ele){ // 输出当前节点的名字 System.out.println(ele.getName()); for(int i=0;i<ele.nodeCount();i++){ // 获取下标为i的节点 Node node = ele.node(i); // 判断当前的标签是否为标签 if(node instanceof Element){ treeSelect((Element)node); }else{ System.out.println(node.getText()); } } } }
# 使用xpath读取xml中的节点
package testxml; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Node; import org.dom4j.io.SAXReader;s import org.junit.Test; public class XpathTst { @Test public void test1() throws DocumentException{ SAXReader reader = new SAXReader(); Document document = reader.read("src/MyXml.xml"); Node node_name = document.selectSingleNode("/xml-body/book/name"); System.out.println(node_name.getText()); // 获取xml-body下的第二个book Node node_name2 = document.selectSingleNode("/xml-body/book[1]/name"); System.out.println(node_name2.getText()); // 获取属性id的值 Node node_name3 = document.selectSingleNode("/xml-body/book/attribute::id"); System.out.println(node_name3.getText()); } }
# 使用xpath遍历所有节点
package testxml; import java.util.List; import org.dom4j.Document; import org.dom4j.DocumentException; import org.dom4j.Node; import org.dom4j.io.SAXReader; import org.junit.Test; public class XpathTst { @Test public void test1() throws DocumentException{ SAXReader reader = new SAXReader(); Document document = reader.read("src/MyXml.xml"); List list = document.selectNodes("//*"); for (int i=0;i<list.size();i++){ Node node = (Node)list.get(i); System.out.println(node.getName() + "\t" + node.getText()); } } }
待补充...
待补充...