XML
XML语法
XML的基本语法
XML必须有关闭标签
区分大小写
属性需要有引号
标签必须正确嵌套
Xml文件的组成部分
文档声明
元素
元素的属性
注释
CDATA区
特殊字符
处理指令(PI:Processing Instruction)
XML的文档声明
文档声明:出现在XML的第一行第一列的位置。
写法
<?xml 属性名=”属性值” 属性名=”属性值” ...?>
version :必须的. 使用”1.0”
encoding :字符集. 是使用浏览器打开的时候采用的默认的字符集的编码
standalone :描述XML文档是否需要依赖其他的文件
xml的元素
什么是元素
xml中的元素其实就是一个个的标签
标签分为两种
a: 包含标签体
理解: 简括号全部成对儿出现, 所有的数据都用一对儿简括号存储
<student>
<name>zhangsan</name>
<age>18</age>
</student>
b: 不包含标签体
理解: 只有最外层的一个简括号,括号用/标识结束, 内部的数据都用属性来编写
<student
name="zhangsan"
age="18"
/>
标签(元素的书写规范)
严格区分大小写;<p><P>
只能以字母或下划线开头;abc _abc
不能以xml(或XML、Xml等)开头----W3C保留日后使用;
名称字符之间不能有空格或制表符;
名称字符之间不能使用冒号 : (有特殊用途)
XML的属性
属性的名称规范与元素一致,属性需要使用引号!
元素中属性的注意事项
一个元素可以有多个属性,每个属性都有它自己的名称和取值。
属性值一定要用引号(单引号或双引号)引起来。
属性名称的命名规范与元素的命名规范相同。
元素中的属性是不允许重复的。
在XML技术中,标签属性所代表的信息也可以被改成用子元素的形式来描述。
例如:
<?xml version="1.0" encoding="UTF-8"?>
<students>
<student name="zhangsan" age="18" />
<student>
<name>zhangsan</name>
<age>18</age>
</student>
</students>
XML的注释
<!-- 被注释的内容 -->
注释不能嵌套定义
XML的CDATA区
使用 CDATA 来避免输出标签文本时,过多的转义。
XML的CDATA区:(CDATA:Character Data)
<![CDATA[ 内容 ]]>
<students> <student> <name>zhangsan</name> <url> <![CDATA[ <cnblogs>www.cnblogs.com</cnblogs> <baidu>www.baidu.com</baidu> ]]> </url> </student> <student> <name>zhangsan</name> <url> <cnblogs>www.cnblogs.com</cnblogs> </url> </student> </students>
XML的约束
用来规范XML的写法。
XML的约束的种类及区别?
DTD(Document Type Definition 文档类型定义) 和 Schema
区别:
1.DTD语法是自成一体的.Schema语法就是XML的语法.
2.Schema的语法就是XML的语法所以更容易被解析器所解析.
3.Schema支持名称空间.
4.Schema有比DTD更加强大的语义和语法的约束.
DTD的语法
DTD的引入方式
内部的DTD:
<!DOCTYPE persons [ ]>
外部的DTD:
一种本地DTD:
<!DOCTYPE persons SYSTEM "unknown.dtd">
一种网络DTD:
<!DOCTYPE persons PUBLIC "//UNKNOWN/" "unknown.dtd">
DTD的语法
语法细节
在DTD文档中使用ELEMENT关键字来声明一个XML元素。
• 语法:<!ELEMENT 元素名称 使用规则>
使用规则:
• (#PCDATA):指示元素的主体内容只能是普通的文本.(Parsed Character Data)
• EMPTY:用于指示元素的主体为空。比如<br/>
• ANY:用于指示元素的主体内容为任意类型。
• (子元素):指示元素中包含的子元素
• 定义子元素及描述它们的关系:
– 如果子元素用逗号分开,说明必须按照声明顺序去编写XML文档。
• 如: <!ELEMENT FILE (TITLE,AUTHOR,EMAIL)>
– 如果子元素用"|"分开,说明任选其一。
• 如:<!ELEMENT FILE (TITLE|AUTHOR|EMAIL)>
– 用+、*、?来表示元素出现的次数
• 如果元素后面没有+*?:表示必须且只能出现一次
• +:表示至少出现一次,一次或多次
• *:表示可有可无,零次、一次或多次
• ?:表示可以有也可以无,有的话只能有一次。零次或一次
<?xml version="1.0" encoding="UTF-8"?> <!ELEMENT 书架(书+)> <!ELEMENT 书 (书名,作者,售价)> <!ELEMENT 书名 (#PCDATA)> <!ELEMENT 作者 (#PCDATA)> <!ELEMENT 售价 (#PCDATA)>
定义属性
• 在DTD文档中使用ATTLIST关键字来为一个元素声明属性。
• 语法:
<!ATTLIST 元素名
属性名1 属性值类型 设置说明
属性名2 属性值类型 设置说明
…
>
• 属性值类型:
– CDATA:表示属性的取值为普通的文本字符串
– ENUMERATED (DTD没有此关键字):表示枚举,只能从枚举列表中任选其一,如(鸡肉|牛肉|猪肉|鱼肉)
– ID:表示属性的取值不能重复
• 设置说明
– #REQUIRED:表示该属性必须出现
– #IMPLIED:表示该属性可有可无
– #FIXED:表示属性的取值为一个固定值。语法:#FIXED "固定值"
直接值:表示属性的取值为该默认值
<!ATTLIST 商品 类别 CDATA #REQUIRED 颜色 CDATA #IMPLIED > <?xml version = "1.0" encoding="GB2312" standalone="yes"?> <商品 类别="服装"颜色="黄色" /> 实例代码2 <?xml version = "1.0" encoding="GB2312" standalone="yes"?> <!DOCTYPE 购物篮 [ <!ELEMENT 购物篮 (肉+)> <!ELEMENT 肉 EMPTY> <!ATTLIST 肉 品种 ( 鸡肉 | 牛肉 | 猪肉 | 鱼肉 ) "鸡肉"> ]> <购物篮> <肉 品种="鱼肉"/> <肉 品种="牛肉"/> <肉/> </购物篮>
DTD约束示例
1.在xml下面创建demo1.dtd文件,代码如下 <?xml version="1.0" encoding="UTF-8"?> <!ELEMENT persons (person+)> <!-- person节点可以出现一次或多次--> <!ELEMENT person (name|age|sex)*> <!-- name,age,sex节点可以出现 零次或多次, 且name,age,sex顺序随意--> <!ELEMENT name (#PCDATA)> <!-- name节点里面的内容放文本内容即可 --> <!ELEMENT age (#PCDATA)> <!ELEMENT sex (#PCDATA)> <!ATTLIST person id ID #REQUIRED> <!-- person属性是id,这个id必须存在,且id值是唯一的 --> 2.在demo1.xml文件引入demo1.dtd约束,代码如下 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE persons SYSTEM "demo1.dtd"> <!-- 引入dtd约束 --> <!-- XML的注释 --> <persons> <person id="p1"> <name>李旭华</name> <age>38</age> <sex>男<</sex> </person> <person id="p2"> <name>李冠希</name> <age>28</age> <sex>男</sex> </person> </persons>
Schema约束
Schema约束自身就是一个XML文件,但它的扩展名通常为.xsd。
一个XML Schema文档通常称之为模式文档(约束文档),遵循这个文档书写的xml文件称之为实例文档。
XML Schema对名称空间支持得非常好。
名称空间: 相当于package。
约束文档: 编写好的Person类。
实例文档: 通过Person类创建对象。
约束文档: <?xml version='1.0' encoding='UTF-8' ?> <xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema' //标准的名称空间 targetNamespace='http://www.cnblogs.com' //将该schema文档绑定到http://www.cnblogs.com名称空间 > <xs:element name='书架' > <xs:complexType> <xs:sequence maxOccurs='unbounded' > <xs:element name='书' > <xs:complexType> <xs:sequence> <xs:element name='书名' type='xs:string' /> <xs:element name='作者' type='xs:string' /> <xs:element name='售价' type='xs:string' /> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> 实例文档: <?xml version="1.0" encoding="UTF-8"?> <cnblogs:书架 xmlns:cnblogs="http://www.cnblogs.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.cnblogs.com book.xsd"> <cnblogs:书> <cnblogs:书名>JavaScript网页开发</cnblogs:书名> <cnblogs:作者>二狗子</cnblogs:作者> <cnblogs:售价>28.00元</cnblogs:售价> </cnblogs:书> </cnblogs:书架> 名称空间: <cnblogs:书架 xmlns:cnblogs="http://www.cnblogs.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.cnblogs.com book.xsd"> 使用默认名称空间 基本格式: xmlns="URI" 举例: <书架 xmlns="http://www.it315.org/xmlbook/schema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.it315.org/xmlbook/schema book.xsd"> <书> <书名>JavaScript网页开发</书名> <作者>马杀鸡</作者> <售价>28.00元</售价> </书> <书架>
Schema约束示例
1.创建demo2.xsd文件,代码如下 <?xml version="1.0" encoding="UTF-8"?> <!-- 名称空间:一个XML只能引入一个DTD约束文档.使用了Schema约束XML文档,一个XML可以引入多个Schame的约束!!! 如果再多个Schema文档中定义了相同的属性名称 该怎么办? * 名称空间类似于java中的package.通过名称空间区分 标签或属性来自于哪个文档的!!!通常名称空间唯一的不重复的即可.一般情况下使用一个URL地址表示一个名称空间. xmlns :xml name sapace .代表当前的文档应用的名称空间. targetNameSpace :目标名称空间. elementFormDefault :确定被约束文档书写的严谨程度 --> <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.boomoom.com/ee25" xmlns:tns="http://www.example.org/demo2" elementFormDefault="qualified"> <!-- 复杂标签 --> <element name="persons"> <!-- 复杂类型 --> <complexType> <sequence maxOccurs="unbounded" minOccurs="1"> <element name="person"> <complexType> <sequence> <!-- 简单标签 --> <element name="name" type="string"></element> <element name="age" type="int"></element> <element name="sex" type="string"></element> </sequence> <attribute name="id" type="string" use="required"></attribute> </complexType> </element> </sequence> </complexType> </element> </schema> 2.创建demo2.xml文件,具体代码如下 <?xml version="1.0" encoding="UTF-8"?> <!-- XML的注释 --> <persons xmlns:aa="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.cnblogs.com/ee25" aa:schemaLocation="http://www.boomoom.com/ee25 demo2.xsd" > <person id="p1"> <name>李旭华</name> <age>38</age> <sex>男</sex> </person> <person id="p2"> <name>李冠希</name> <age>28</age> <sex>男</sex> </person> </persons>
XML的解析的方式
DOM解析:DOM:Document Object Model.
SAX解析:Simple Api for XML.
DOM和SAX的区别
DOM 是一次性将文档加载到内存,形成树形结构进行解析。
优点:对 XML 进行增删改的操作。
缺点:如果文档特别大,容易导致内存溢出。
SAX是事件驱动的方式,一行一行进行解析的。
优点:如果文档特别大,不会导致内存溢出。
缺点:不能文档进行增删改的操作。
DOM4J
DOM4J:开源组织提供了一套XML的解析的API。
DOM4J的入门案例步骤
1、导入jar包.dom4j-1.6.1.jar
2、创建解析器
3、解析文档获得代表文档的Document对象.
4、获得跟节点.
5、从跟节点下查找其他的节点.
@Test /** * 获得元素的内容:查询的操作. */ public void demo1() throws Exception{ // 创建解析器 SAXReader reader = new SAXReader(); // 解析XML的文档 Document document = reader.read("xml/demo1.xml"); // 获得跟节点 Element root = document.getRootElement(); System.out.println(root.getName()); // 查找跟节点下的子节点. element() elements(); Element pElement = root.element("person"); // 查找的是第一个person元素 // root.elements("person").get(1); // 查找的是第二个person元素 Element nElement = pElement.element("name"); Element aElement = pElement.element("age"); Element sElement = pElement.element("sex"); System.out.println(nElement.getText()); System.out.println(aElement.getText()); System.out.println(sElement.getText()); }
XPath
dom4j支持XPath的jar包.
jaxen-1.1-beta-6.jar
dom4j的XPath支持的API:
List document.selectNodes(String xPath);
Node document.selectSingleNode(String xPath);
@Test /** * DOM4J的XPath的写法: */ public void demo2() throws Exception{ // 创建解析器: SAXReader reader = new SAXReader(); // 解析XML返回Document对象. Document document = reader.read("xml/demo1.xml"); /*List<Node> list = document.selectNodes("//name"); for (Node node : list) { Element element = (Element) node; System.out.println(element.getText()); }*/ List<Node> list = document.selectNodes("//person['@id']"); for (Node node : list) { Element element = (Element) node; System.out.println(element.attributeValue("id")); } }
DOM4J解析XML
1.创建一个webapps文件夹,把html等文件放入,创建一个conf文件,把server.xml文件放入,server.xml配置文件如下: <?xml version="1.0" encoding="UTF-8"?> <Server> <Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"/> </Server> 2.在MyServer中的代码如下: public class MyServer { public static void main(String[] args) throws Exception { // 解析XML: // 创建解析器 SAXReader reader = new SAXReader(); // 解析XML文档: Document document = reader.read("conf/server.xml"); Element element = (Element)document.selectSingleNode("//Connector['@port']"); String port = element.attributeValue("port"); // ServerSocket 对象可以监听端口 ServerSocket serversocket = new ServerSocket(Integer.parseInt(port)); //ServerSocket serversocket = new ServerSocket(8888); while(true) { Socket socket = serversocket.accept(); // 等待客户端的连接请求,一旦有请求过来,就结束阻塞,返回客户端对象 //System.out.println(socket.getInetAddress()); // 一旦有客户来访问, 就另开一个新线程去提供服务, main线程继续等待下一个客户的连接 new Thread(new MyService(socket)).start(); } } } 3.在MyService中的代码如下: public class MyService implements Runnable{ private Socket socket; public MyService(Socket socket) throws Exception { this.socket = socket; } @Override public void run() { // 提供服务 try{ InputStream in = socket.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(in)); String firstLine = reader.readLine(); System.out.println(firstLine); String path = firstLine.split(" ")[1]; System.out.println(path); // 从文件读, 往浏览器写 File file = new File("webapps"+path); FileInputStream fis = new FileInputStream(file); OutputStream os = socket.getOutputStream(); os.write("HTTP/1.1 200 OK\r\n".getBytes()); os.write("\r\n".getBytes()); byte[] buffer = new byte[1024]; int len = 0; while ((len = fis.read(buffer))!=-1) { os.write(buffer, 0, len); } socket.close(); }catch(Exception e){ e.printStackTrace(); } } }
DOM4J的常用方法
Dom4JDemo:
package com.boomoom; import java.io.IOException; import java.util.List; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; /* * Dom4J的常用方法: * Document * Element getRootElement() :获取根元素对象(根标签) * Element * List elements() :获取所有的子元素 * List elements(String name):根据指定的元素名称来获取相应的所有的子元素 * Element element(String name):根据指定的元素名称来获取子元素对象,如果元素名称重复,则获取第一个元素 * String elementText(String name) :根据指定的子元素名称,来获取子元素中的文本 * String getText() :获取当前元素对象的文本 * void setText(String text):设置当前元素对象的文本 * String attributeValue(String name):根据指定的属性名称获取其对应的值 * public Element addAttribute(String name,String value):根据指定的属性名称和值进行添加或者修改 * addElement * DocumentHelper * static Element createElement(String name) */ public class Dom4JDemo { public static void main(String[] args) throws Exception { //7、操作XML文件属性:打印State的Name //8、添加属性:State: GDP="1w亿" Document document = Dom4JUtils.getDocument(); //获取根元素 Element rootElement = document.getRootElement(); //添加新的属性和对应的值 rootElement.addAttribute("GDP", "1w亿"); //写回文件 Dom4JUtils.write2XML(document); } private static void method7() throws Exception { //7、操作XML文件属性:打印State的Name Document document = Dom4JUtils.getDocument(); //获取根元素 Element rootElement = document.getRootElement(); //根据属性名称获取值 String value = rootElement.attributeValue("Name"); System.out.println(value); } private static void method6() throws Exception, IOException { //5、向指定元素节点上增加同级元素节点:在洛阳前面,添加一个<City>三门峡</City> //创建一个新的元素对象 Element cityElement = DocumentHelper.createElement("City"); //设置文本 cityElement.setText("三门峡"); Document document = Dom4JUtils.getDocument(); //获取根元素 Element rootElement = document.getRootElement(); //获取根元素下所有的子元素 List<Element> es = rootElement.elements(); //将新的元素添加到子元素列表中 es.add(1, cityElement); //写会文件 Dom4JUtils.write2XML(document); } private static void method5() throws Exception, IOException { //4、向指定元素节点中增加子元素节:添加一个新城市<City>南阳</City> Document document = Dom4JUtils.getDocument(); //获取根元素 Element rootElement = document.getRootElement(); //添加元素 Element cityElement = rootElement.addElement("City"); //设置文本 cityElement.setText("南阳"); //写回文件 Dom4JUtils.write2XML(document); } private static void method4() throws Exception, IOException { //6、删除指定元素节点:删除元素开封 Document document = Dom4JUtils.getDocument(); //获取根元素 Element rootElement = document.getRootElement(); //获取根元素下的所有子元素 List<Element> es = rootElement.elements(); Element cityElement = es.get(1); //无法自杀,找他爹 Element parentElement = cityElement.getParent(); parentElement.remove(cityElement); //写回文件 Dom4JUtils.write2XML(document); } private static void method3() throws Exception, IOException { //3、修改某个元素节点的主体内容:信阳-->安阳 Document document = Dom4JUtils.getDocument(); //获取根元素 Element rootElement = document.getRootElement(); //获取根元素下的所有子元素 List<Element> es = rootElement.elements(); //根据索引可以获取指定的元素 Element cityElement = es.get(3); //修改文本 cityElement.setText("安阳"); //写回文件 Dom4JUtils.write2XML(document); } private static void method2() throws Exception { //2、遍历所有元素节点:打印他们的元素名称。 //获取根元素 Document document = Dom4JUtils.getDocument(); Element rootElement = document.getRootElement(); treeWalk(rootElement); } public static void treeWalk(Element element) { //输出元素的名称 System.out.println(element.getName()); //获取指定元素的所有子元素 List<Element> es = element.elements(); for (Element e : es) { treeWalk(e); } } private static void method() throws Exception { //1、得到某个具体的节点内容:打印"郑州" Document document = Dom4JUtils.getDocument(); //获取根元素 Element rootElement = document.getRootElement(); //获取根元素下的所有子元素 List<Element> elements = rootElement.elements(); //根据索引获取第一个City元素 Element cityElement = elements.get(0); //根据子元素的名称来获取子元素的文本 String text = cityElement.elementText("Name"); System.out.println(text); } }
Dom4JUtils:
package com.boomoom; import java.io.FileOutputStream; import java.io.IOException; import org.dom4j.Document; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; public class Dom4JUtils { public static Document getDocument() throws Exception { SAXReader reader = new SAXReader(); Document document = reader.read("src/com/boomoom/city.xml"); return document; } public static void write2XML(Document document) throws IOException { OutputFormat format = OutputFormat.createPrettyPrint(); //format.setEncoding("UTF-8");//默认的编码就是UTF-8 XMLWriter writer = new XMLWriter( new FileOutputStream("src/com/boomoom/city.xml"), format ); writer.write( document ); } }
city.xml
<?xml version="1.0" encoding="UTF-8"?> <State Code="37" Name="河南" description="郑州" GDP="1w亿"> <City> <Name>郑州</Name> <Region>高薪区</Region> </City> <City>三门峡</City> <City>洛阳</City> <City>安阳</City> <City>南阳</City> </State>