HTML_day3
一、html与xml结合的运用:
1、xml的简介:
(1)xml全称:eXtensible Markup Language
(2)xml是可扩展性标记型语言
——可扩展性:html是使用固定含义的标签,xml可以自定义标签,并且可以使用中文。
——标记型:xml也是使用标签对数据进行封装。
(3)xml的用途:xml可以用于数据的显示,但它的主要功能是进行数据的存储。
2、xml的应用:
(1)不同系统之间的数据传输。以前的数据传输都是使用字符串的形式进行传输,不利于接收方的解读与代码的后期维护。而xml是将数据内容进行层级封装,从而增强了数据的解读与代码的后期维护。
(2)实现生活中的对应关系。使用树形结构存储对象之间的对应关系。
(3)方便文件的配置。比如数据库文件的配置。
3、xml的版本:
(1)xml拥有两个版本:1.0(主要使用版本),1.1(不能进行向下兼容)
4、xml的文档声明:
(1)声明格式: <?xml version = "1.0" encoding = "编码方式" standalond = "yes/no"?>
——属性:version:表示使用的xml的版本号,通常使用的是1.0;encoding:设置编码方式,常用的编码有utf-8,gbk,Unicode(万国码);standalone:是否需要添加外置文件,yes表示需要,no表示不需要。
(2)单独创建xml文件后,文档声明必须放在xml文件的第一行
(3)产生乱码的原因:文件的保存方式与文不同,解决方式是将二者编码同步(文件保存的默认编码方式为gbk)。
5、xml中新标签的定义:
(1)有开始标签就必须有结束标签,结束标签不能省略。
(2)如果标签内没有内容,可以在标签内结束:<xxxx/>
(3)在xml中,空格与换行会被当做原数数据进行处理,因此不能为了代码的可观赏性而进行代码的缩进。
(4)在xml中,只有一个根标签,其余相同标签都是它的子标签。
(5)标签不能交叉使用。
6、xml的命名规则:
(1)xml标签严格区分大小写。
(2)xml标签不能以xml或者它的其他字母表达形式作为标签名(如Xml,XML等)
(3)xml不能以数字和下划线开头。
(4)xml标签不能包含空格和冒号。
(5)xml标签可以是中文。
7、xml标签内属性的定义:
(1)同一个标签内可以拥有多个属性。
(2)标签内属性名称不能相同。
(3)属性值必须使用引号引起来(双引号或单引号)
(4)属性的命名规则与标签名的命名规则相同。
8、xml的注释:
(1)格式:<!-- 注释内容-->
(2)注释不能进行嵌套。
9、xml的特殊字符:
(1)&(& <(<) >(>) "(双引号) '(单引号) (空格)
10、xml的CDATA区:
(1)功能:解决多个字符需要转义的情况
(2)格式:<![ CDATA[ 转义内容 ] ]>
(3)原理:将特殊字符当作文本处理,而不是当作标签处理
11、PI指令:用于设置样式,导入css文件
(1)格式:<?xml-stylesheet type = "text/css" href = "css路径">
(2)对中文标签不起作用。
12、xml中的约束:dtd约束、schema约束
(1)dtd约束:
*** 需要创建dtd文件。
*** 内容格式:
复杂元素:<!ELEMENT 主标签 (子标签)>
简单元素:<!ELEMENT 子标签 (#PCDATA)>
*** 在xml文件中导入dtd文件:<!DOCTYPE 根元素名称 SYSTEM "dtd文件路径">
*** 浏览器在解析时,只检验xml语法,不会检验dtd约束。
(2)dtd的引入:
*** 从外部引入自定义的dtd文件:<!DOCTYPE 根元素名称 SYSTEM "dtd文件路径">
*** 从外部引入网络上的dtd文件:<!DOCTYPE 根元素名称 PUBLIC "dtd文件名称" "dtd的url地址">
*** 使用xml中定义的dtd:<!DOCTYPE 根元素名称[ 约束内容 ]>。
(3)dtd的约束类型:
*** (#PCDATA):表示内容是字符串。
*** EMPTY :表示内容为空。
*** ANY :表示内容任意。
***复杂类型子标签的出现次数:+(出现1次或多次);?(出现0次或1次);*(表示出现0次或多次)
*** 子元素分隔符:逗号(,):子元素严格按照标签内顺序出现;或(|):子元素选择出现;括号:对子元素进行分组。
13、dtd的属性定义:
(1)格式:<!ATTLIST 元素名称 属性名称 属性类型 属性约束>
(2)属性类型:CDATA(字符串类型);(内容1|内容2|内容3):枚举内容,列举出多种情况,但每次只出现一种情况,但是dtd中没有枚举的关键字;ID表示id属性,它的值只能是字母或下划线开头,不能是数字。
(3)属性约束:
*** #REQUIRED :表示属性必须存在。
*** #IMPLIED :表示属性可有可无。
*** #FIXED :表示属性拥有一个固定值。格式—— FIXED "固定值"。
*** 直接值 :该属性的默认值,可以被更改。
14、实体的定义与引入:实体需要存在于dtd文件里,如果存在于但它的文件之外,可能某些浏览器无法使用。
(1)定义格式:<!ENTITY 实体名称 "实体内容">
(2)实体的引入:&实体名称;(类似于特殊字符的使用)
15、xml的解析方式:涉及到java代码(属于最重要的内容)
(1)xml的解析方式:dom、sax
*** dom解析方式:使用树形结构进行层级封装,将每一部分封装为对象。
—— 优点:利于增、删、改。
——缺点:空间占用率大,可能会造成内存溢出。
*** sax的解析方式:使用事件驱动,边读取、边解析。从上到下,逐行解析,当解析到某个对象时,返回该对象的名称。
——优点:不会造成内存溢出,利于查找。
——缺点:不能进行增、删、改等操作。
16、xml的三种解析方式:jaxp(sun公司推出)、dom4j(功能最完善)、 jdom(dom4j的前身)
(1)jaxp:sun公司推出的解析规则,属于javase的内容。
——存在于jdk文档的org.w3c.dom包
——解析过程:一、创键解析器工厂,通过DocumentBuilderFactory抽象类的newInstance()获得实列;二、创建解析器,通过步骤一获得的实列调用newDocumentBuilder()获得实列;三、获得Document对象,通过的步骤二的实列调用parse(),传入参数为xml的路径;四、通过查看jdk文档,使用相应的方法完成想要的操作。
(2)解析过后的所有操作在回写之前都只是对内存的操作,实际并未改变xml源码
列子:
DocumentBuilderFactory Dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder Db = Dbf.newDocumentBuilder(); Document doc = Db.parse("F:\\java\\XmlDemo\\src\\MyXml.xml");
(3)回写操作:将xml内容的修改实际映射到xml源码上,改变xml源码内容。
——回写操作:一、创建回写器工厂:通过TransfromBuilderFactory抽象类的newInstance()获得实列;二、创建回写器,通过步骤一的实列调用newTransformer;三、使用回写器进行内容的回写,通过transform()进行操作,参数有document目标对象,io流StreamResult()
列子:
TransformerFactory Tff = TransformerFactory.newInstance(); Transformer Tr = Tff.newTransformer(); Tr.transform(new DOMSource(doc),new StreamResult("\"F:\\\\java\\\\XmlDemo\\\\src\\\\MyXml.xml\""));
二、xml的schema的约束:
1、schema的特点:
(1)schema的文件后缀名是:.xsd
(2)schema的约束更加细化和严格。
(3)一个schema文件就是一个xml文档。
2、schema的约束过程:
——w3c预先定义了元素和属性。
——schema实现约束文档。
——xml生成实列文档。
3、约束格式:
<schema xmlns = "http://www.w3.ord./2001/XMLSchema" targetNameSpace = "http://www.itcast.cn./20140213" elementFormDefault = "qualified">
(1)简单元素:只含有文本,不含有其它元素和其它属性。
(2)复杂类型:<complex>
(3)表示子标签有顺序:<sequence>
(4)<all>:标志标签只能够出现一次,功能等同于dtd中的?约束符号。
(5)<choice>:表示元素只能出现其中的一个,等同于dtd中枚举约束。
(6)maxOccurs:表示标签出现的次数。
(7)<any>:表示可以是任意的元素。
4、约束引入:
(1)约束文件的引入:
—— xmlns:别名 = "schema文件的地址"
5、约束:通过别名进行约束。
—— 别名:标签名
6、属性约束:只能对复杂元素使用,且只能出现在<complex>标签之前。
三、xml的sax解析器:
1、此解析器存在于java的jdk位置:javax.xml.parse
2、解析原理之前已经记录(边读边解析)
——必须手动实现接口或继承ContentHandler的派生类(ContentHandler接口——建立解析规则)
——解析方法中需要传入两个参数:第一个参数为xml的文件路径,第二个参数为事件处理器(需要手动继承DefaultHander类,并进行相应方法的覆写)。
——此种操作等效于在方法里面绑定了一个事件。
3、解析过程:实际就是调用覆写方法的过程,解析结果的差异取决于对覆写方法的改动。
(1)当解析到开始标签的时候 ,调用startElement()方法。参数qname返回开始标签的名字
(2)当解析到文本内容的时候,调用characters()方法,实际是使用了String的构造方法返回内容。
(3)当解析到结束标签的时候,调用endElement()方法,参数qname返回结束标签的名字。
4、案列:
package com.yrc.sax.Hander; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; /** * sax的核心解析类:实现此类后,会被作为sax内置的解析原件 * @author YangRunchun * */ public class MyHander extends DefaultHandler { private Map<String,String> objMap = null; //保存单个完整地解析对象 private List<Map<String,String>> objList = null; //保存所有的解析对象 private String currentTag; //当前被解析的元素的标签 private String currentValue; //当前被解析的元素的值 private String nodeName; //当前被解析的元素的节点名称 public MyHander(String nodeName) { //记录当前元素节点 this.nodeName = nodeName; } //返回所有解析的对象 public List<Map<String, String>> getObjList() { return objList; } /** * 当遇到开始标签的时候,实列化List集合 */ @Override public void startDocument() throws SAXException { objList = new ArrayList<Map<String,String>>(); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if(qName.equals(nodeName)) { objMap = new HashMap<String, String>(); } //处理所有属性 if(objMap!=null && attributes!=null) { for(int i=0;i<attributes.getLength();i++) { objMap.put(attributes.getQName(i), attributes.getValue(i)); } } currentTag = qName; } /** * 处理xml读取到的内容(处理文本) */ @Override public void characters(char[] ch, int start, int length) throws SAXException { if(currentTag!=null && objMap!=null) { currentValue = new String(ch,start,length); if(currentValue!=null & !currentValue.trim().equals("") && !currentValue.trim().equals("\n")) { objMap.put(currentTag, currentValue); } } //保存好内容后需要将当前值与当前标签置空 currentTag = null; currentValue = null; } /** * 结束标签时会调用这个方法 */ @Override public void endElement(String uri, String localName, String qName) throws SAXException { //将当次map加入list,然后将map值为空,用于下一个标签解析 if(qName.equals(nodeName)) { objList.add(objMap); objMap = null; } super.endElement(uri, localName, qName); } }
四、使用dom4j解析xml:核心是查询jdk文档
1、dom4j不属于javase的内容,所以在使用的时候,必须导入相应的jar包。
(1)将jar包放入工程文件之下,但是必须新建forder文件。
(2)dom4j的使用:查询dom4j操作文档。
2、dom4j的操作与回写:使用xml的操作流。
(1)XMLWriter类用于dom4j的回写操作。
(2)真正的回写方法:位于XMLWriter中的write方法。
(3)关闭IO流:因为回写使用了IO操作,所以在回写操作执行完毕之后,需要关闭IO流。
(4)节点添加:
——在末尾添加:因为使用的是sax的解析方式,所以在进行节点添加的时候,是从上到下(先父后子)。直接添加标签和内容,不需要在添加之前创建节点。
——在特点位置添加:需要在添加结点之前单独创建Element结点,使用add(index,Element).
(5) 修改结点内容:使用setText()方法。
(6)定位待删除结点,然后使用该结点的父节点执行删除操作,使用remove()。
(7)获得结点属性:使用jdk提供的方法。
(8)存在有两个格式化方式:
——createPrettyPrint():表示美化格式,并且会自动进行换行。
——createCompactForm():表示压缩格式,内容只在一行显示,不会进行换行操作。
3、dom4j方法的封装:将dom4j提供的方法根据实际需要进行选择性的封装。创建一个单独的操作类,并将相应方法封装在类中。
4、使用dom4j需要时刻进行异常处理。
五、XPATH:一种文档定位操作。
1、解决问题:dom4j使用sax的逐行解析方式,在大文档中效率较差,因此使用XPATH进行文档内容的直接定位。
2、作用:实现对文档内容的直接定位,简化dom4j原始的数据元素定位操作。
3、XPATH的使用:查询XPathTutorial.chm文档。
4、特殊语法:
(1)/ :单独使用时,一个/符号表示一层。
(2)// :表示忽略层,直接索取文档中所有待查找的同名关键字。
(3)支持特殊字符,如出现0次或多次(*关键字)。
5、使用dom4j支持XPATH操作:
(1)默认情况下dom4j不支持XPATH
(2)实现支持:需要导入XPATH的jar包jaxen-1.1-beta-6.jar(将jar加入到Library?)
6、节点与属性的差异:
(1)node:相对于tree而言,将xml文档树形化之后,产生节点对象。
(2)Element:是文档本身的定义。一个标签就是一个元素,并且标签内部可以包含子标签。
——两者关系:只有包含完整信息的节点才能成为元素。当请求获得一个元素时,是获得一个完整的元素,包括他的子标签。

浙公网安备 33010602011771号