xml
发布时间:2020-12-16 00:11:15 所属栏目:百科 来源:网络整理
导读:XML:可扩展标记语言 标签可以自定义,任何标签都可以 xml可以显示数据,主要功能是为了存储数据(可模拟数据库) 是W3C组织发布的技术 使用1.0的版本,1.1不能实现向下兼容 应用:1.不同系统之间传输数据 2.用来表示生活中有关系的数据 3.经常用在配置文件中 -
XML:可扩展标记语言
标签可以自定义,任何标签都可以 xml可以显示数据,主要功能是为了存储数据(可模拟数据库) 是W3C组织发布的技术 使用1.0的版本,1.1不能实现向下兼容 应用:1.不同系统之间传输数据 2.用来表示生活中有关系的数据 3.经常用在配置文件中 --比如现在连接数据库,肯定知道数据库的用户名和密码,数据名称 如果修改数据库的信息,不需要修改源代码,只要修改配置文件就可以了 XML语法: 1.xml文档声明 --创建文件.xml --如果写xml,第一部必须要有一个文档声明: <?xml version="1.0" encoding="utf-8"> 文档生命必须写在第一行第一列,不应该有空格 属性:-version:xml版本 -encoding:xml的编码 -standalone:是否需要依赖其他文件yes/no(用的少) xml中文乱码解决:设置保存时候的编码和打开时候的编码一致 2.定义元素(标签) --一个xml文档必须有且只有一个根标签 --在xml中,空格和换行都作为原始内容被处理 <网址>www.itcast.cn</网址> <网址> www.itcast.cn </网址> 以上两个是不同的。 XML标签规范: --xml区分大小写 --不能以数字,下划线开头 --不能包含空格 --不能以xml或Xml或XML开头 --名称中间不能包含冒号 xml的标签可以是中文 3.定义属性 --1.一个标签上可以有多个属性 2.属性名称不能相同 3.属性名称和属性值之间使用=,属性值要用引号(可单可双) 4、命名规范和元素名称的规范一致 4.注释: <!-- xml的注释 --> 注释也不能放到第一行,第一行第一列必须放文档声明 5.xml中的特殊字符: <:< >:> 6.CDATA区 可以解决多个字符都需要转义的操作,把需要转义的内容放在CDATA区里面,就不需要转义了 写法:<![CDATA[内容]]> <![CDATA[<b> if(a < b && b < c && d>f){}</b>]]> 7.PI指令(处理指令:Processing Instruction): 用来指挥软件如何解析XML文档(设置样式)。 语法:必须以<?开头,以?>结束 常用处理指令:<?xml version="1.0" encoding="utf-8"?> xml-stylesheet指令:指示xml文档所使用的css样式xsl <?xml-stylesheet type="text/css" href="some.css"> 注:对中文命名的标签不起作用 XML语法规则总结: 1.所有XML标签对大小写敏感。 2.所有XML标签都必须有关闭标签。 3.XML必须正确的嵌套顺序。 4.XML必须有根元素。 5.XML的属性值须加引号 6.特殊字符必须转义--CDATA 7.XML中的空格、回车换行会解析时被保留 XML约束: 技术:dtd约束 和 schema约束 1.dtd快速入门: 创建一个文件 后缀名.dtd 步骤: 1.看xml中有多少个元素:有几个元素,就在dtd文件中写几个 2.判断元素是简单元素还是复杂元素 注意:元素名称后面一定要有空格 --简单元素:没有子元素的元素 <!ELEMENT 元素名称 (#PCDATA)> --复杂元素:有子元素的元素 <!ELEMENT 元素名称 (子元素)> 3.需要在xml文件中引入dtd文件 <!DOCTYPE 根元素名称 SYSTEM "dtd文件路径"> 打开xml文件使用浏览器打开的,浏览器只负责校验xml的语法,不负责校验xml约束。 如果想要校验xml的约束,需要使用工具(eclipse) 在eclipse里面创建xml文件,dtd文件 dtd的三种引入方式: 1.外部引入:<!DOCTYPE 根元素名称 SYSTEM "dtd文件路径"> <!DOCTYPE person SYSTEM "NewFile.dtd"> 2.使用内部的dtd文件 <!DOCTYPE person [ <!ELEMENT person (name,age)> <!ELEMENT name (#PCDATA)> <!ELEMENT age (#PCDATA)> ]> 3.使用外部的dtd文件(网络上的dtd文件): <!DOCTYPE 根元素 PUBLIC "dtd名称" "dtd文档的URL"> 后面学struts2框架使用配置文件 使用外部的dtd文件 使用dtd定义元素: 语法:<!ELEMENT 元素名 约束> 简单元素:没有子元素的元素 1.<!ELEMENT name (#PCDATA)> (#PCDATA):表示约束name是字符串类型 2.<!ELEMENT sex EMPTY> EMPTY: 元素为空(没有内容) 3.<!ELEMENT school ANY> ANY:任意 复杂元素: <!ELEMENT person (name,age,sex)> --子元素只出现一次 *<!ELEMENT 元素名称 (子元素)> *表示子元素出现的次数: + :表示一次或多次 ? :表示0次或1次 * :表示出现0次或多次(无论多少次都可以) <!ELEMENT person (name+,age?,sex*)> --表示name可以出现一次或多次 --表示age可以出现0次或1次 --表示sex可以出现任意次 *子元素直接使用逗号隔开:表示元素出现的顺序 *子元素使用|隔开:表示只能出现其中的任意一个 使用dtd定义属性: 语法:<!ATTLIST 元素名称 属性名称 属性类型 属性的约束 > <!ATTLIST birthday ID CDATA #REQUIRED > <birthday ID="birth"></birthday> 属性值类型:CDATA:表示属性的取值为普通的文本字符串 ENUMERATED(dtd没有此关键字):表示枚举,只能枚举列表中人选其一。用一个括号括起来 如(a|b|c)只能取其中的一个;红绿灯效果 ID:表示属性的取值不能重复,属性的值只能由字母,下划线开始,不能出现空白字符 属性约束设置说明: #REQUIRED:表示此属性必须出现 #IMPLIED:表示该属性可有可无 #FIXED:表示属性的取值为一个固定值,语法:#FIXED "固定值" 直接值:不写,使用直接值;写了就是用设置的值 定义引用实体: 概念:在dtd中定义,在xml中使用 语法:<!ENTITY 实体名称 "实体内容"> 引用方式(注意是在xml中使用):&实体名称 如:dtd中定义: <!ENTITY copyright "传智播客版权所有"> xml中引用: ©right; 注意:定义实体需要写在内部dtd里面,如果写在外部dtd里面,在某些浏览器下内容得不到。 1.dtd: <!ELEMENT person (name,age)> <!ELEMENT name (#PCDATA)> <!ELEMENT age (#PCDATA)> demo.xml: <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE person SYSTEM "1.dtd"> <person> <name>张三</name> <age>23</age> </person> XML的解析简介 :(写到java代码) xml是标记型文档 js解析标记型文档:根据html的层级结构,在内存中分配一个树形结构,把html标签,属性和文本都封装成对象。 document对象,element对象,属性对象,文本对象,Node对象 xml的解析方式(技术):dom 和 sax【经常被问到】 dom和sax解析的区别: 使用dom解析:根据xml的层级结构在内存中非配一个树形结构把xml的标签,属性和文本封装成对象。 优点:很方便的实现增删改操作 缺点:如果文件过大,造成内存溢出 使用sax解析: 采用事件驱动,边读边解析(从上到上,一行一行的解析,解析到某一个对象,把对象名称返回。) 优点:不会造成内存溢出,方便实现查询 缺点:不能实现增删改操作 想要解析xml,首先需要解析器 不同的公司和组织提供了针对dom和sax方式的解析器,通过api提供 解析器(是解析器,而不是解析技术): sun公司:jaxp dom4j: dom4j(开发中使用最多) jdom: jdom jaxp:是javase的一部分 jaxp解析器是在javax.xml.parsers包中,定义了几个工厂类 dom:DocumentBuilder 解析器类 --抽象类,不能new,此类的实例可以通过DocumentBuilderFactory.new DocuemntBuilder()获取 一个方法,可以解析xml parse("xml路径") 返回是Document整个文档 返回的Document是一个接口,父节点是Node ,如果在Document里面找不到想要的方法,到Node里面找 在document里面方法: NodeList getElementsByTagName(String tagName)//这个方法可以得到标签,返回集合NodeList Element getElementById(String elementId) //返回具有带给定值的 ID 属性的 Element。 Element createElement(String tagName)//创建标签 Text createTextNode(String data) /创建文本 Node appendChild(Node newChild) //把文本添加到标签下面 Node removeChild(Node oldChild) //使用父节点删除节点 Node getParentNode()//获取父节点 Node getFirstChild()//此节点的第一个节点 Node getLastChild()//此节点的最后一个节点 Node cloneNode(Node deep)//返回此节点的副本,即允当节点的一般复制构造方法 Node replaceChild(Node newChild,Node oldChild)// 将子节点列表中的子节点 oldChild 替换为 newChild,并返回 oldChild 节点。 NodeList list --int getLength():得到集合长度 --Node item(int index):根据下标取到具体的值 遍历: for(int i = 0 ; i < list.getLength() ; i++){ list.item(i); } String getTextContext()// 得到标签里的内容 DocumentBuilderFactory 解析器工厂 --抽象类,不能new,通过newInstance()获取DocumentBuilderFactory的实例 sax:SAXParser 解析器类 SAXParserFactory 解析器工厂 使用jaxp实现 查询 操作的步骤: 1.创建解析器工厂:DocuemnDocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance() 2.根据解析器工厂创建解析器 DocuemntBuilder builder = builderFactory.newDocuemntBuilder() 3.解析xml返回document Docuemnt document = builder.parse("src/person.xml"); 4.得到所有要查询的元素 NodeList list = document.getElementsByTagName("name"); 5.返回集合,遍历集合,得到每一个要查询的元素的内容 练习:查询person.xml中所有name元素的值 import javax.w3c.*; public class Test{ public static void main(String[] args) throw Exception{ /** *1.创建解析器工厂 *2.根据解析器工厂创建解析器 *3.解析xml返回document *4.得到所有的name元素 *5.返回集合,遍历集合,得到每一个name元素 / //1.创建解析器工厂 DocumentBuilderFactory buildFactory = DocumentBuilderFactory.newInstance(); //2. 根据解析器工厂创建解析器 DocuemntBuilder builder = buildFactory.newDocumentBuilder(); //3.解析xml返回document Docuemnt document = builder.parse("src/person.xml"); NodeList list = document.getElementsByTagName("name"); //遍历集合 for(int i = 0 ; i < list.getLength() ; i++){ Node name = list.item(i); //得到name元素的值 String str = name.getTextContext(); System.out.println(str); } } } 使用jaxp 添加 元素: *1.创建解析工厂 * 2.创建解析器 * 3.解析xml返回Document对象 * 4.得到所有的p1标签,用item(int index)得到指定下标的元素 * 5.创建sex标签 createElement() * 6.创建文本标签 createTextNode() * 7.把文本添加到sex下面 * 8.把sex添加到p1下面 * 9.回写xml 使用jaxp 修改 节点: * 1.创建解析工厂 * 2.创建解析器 * 3.解析xml返回document对象 * 4.得到sex元素 * 5.修改sex里面的值 setTextContent() * 6.回写xml 使用jaxp 删除 节点: * 1.创建解析工厂 * 2.创建解析器 * 3.解析xml返回document对象 * 4.得到sex元素 * 5.得到sex的父节点 父节点删除节点:removeChild() * 6.删除sex * 7.回写xml 使用jaxp 遍历 节点: * 1.创建解析工厂 * 2.创建解析器 * 3.解析xml返回document对象 * * ===使用递归得到所有节点 * 4.得到根节点 * 5.得到根节点的子节点 * 6.得到根节点的子节点的子节点
<?xml version="1.0" encoding="utf-8" standalone="no"?> <person> <p1> <name>zhangSan</name> <age>20</age> </p1> <p1> <name>liSi</name> <age>22</age> </p1> </person> /**使用jaxp实现xml的解析 * @ProjectName:xml * @ClassName:TestJaxp * @author xkf * @email 2547951466@qq.com * @date 2015年9月18日 * @Description:无 */ public class TestJaxp { /**查询person.xml中所有name元素的值 * @Title:selectAll * @Description: * @throws Exception * @return void */ public static void selectAll() throws Exception{ //1.创建解析器工厂 DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); //2.创建解析器 DocumentBuilder builder = builderFactory.newDocumentBuilder(); //3.解析xml返回Document Document docuemnt = builder.parse("src/person.xml"); //4.得到所有的name属性 NodeList list = docuemnt.getElementsByTagName("name"); //5.遍历集合 for (int i = 0; i < list.getLength(); i++) { Node name = list.item(i); //得到name元素的值 String strName = name.getTextContent(); System.out.println(strName); } } /**查询xml中的第一个name元素的值:list.item(指定的下标); * @Title:selectSingnal * @Description: * @return void */ public static void selectSingnal() throws Exception{ //1.创建解析工厂 DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); //2.创建解析器 DocumentBuilder builder = builderFactory.newDocumentBuilder(); //3.解析xml返回Document Document document = builder.parse("src/person.xml"); //4.得到所有的name元素 NodeList list = document.getElementsByTagName("name"); //使用下标得到第一个name元素 Node name = list.item(0); //得到name元素的值 String strName = name.getTextContent(); System.out.println(strName); } /**使用jaxp添加一个节点:sex * 1.创建解析工厂 * 2.创建解析器 * 3.解析xml返回Document对象 * 4.得到所有的p1标签,用item(int index)得到指定下标的元素 * 5.创建sex标签 createElement() * 6.创建文本标签 createTextNode() * 7.把文本添加到sex下面 * 8.把sex添加到p1下面 * 9.回写xml * @Title:addElement * @Description: * @return void */ public static void addElement() throws Exception{ //1.创建解析器工厂 DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); //2.创建解析器 DocumentBuilder builder = builderFactory.newDocumentBuilder(); //3.解析xml返回Document对象 Document document = builder.parse("src/person.xml"); //4.得到第一个p1标签:得到所有的p1,使用item()下标得到 NodeList list = document.getElementsByTagName("p1"); Node p1 = list.item(0); //5.创建sex标签createElement() Element sex = document.createElement("sex"); //6.创建文本createTextNode() Text text = document.createTextNode("男"); //7.把文本添加到sex下面 sex.appendChild(text); //8.把sex添加到p1下面 p1.appendChild(sex); //9.回写xml,不回写的话就不会在xml中显示刚刚添加的节点 //这个回写操作不需要掌握,用的时候直接来复制即可 TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.transform(new DOMSource(document),new StreamResult("src/person.xml")); } /**修改p1里面的sex为女:setTextContent() * 1.创建解析工厂 * 2.创建解析器 * 3.解析xml返回document对象 * 4.得到sex元素 * 5.修改sex里面的值 setTextContent() * 6.回写xml * @Title:modifyElement * @Description: * @return void */ public static void modifyElement() throws Exception{ DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = builderFactory.newDocumentBuilder(); Document document = builder.parse("src/person.xml"); Node sex = document.getElementsByTagName("sex").item(0); sex.setTextContent("女"); TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.transform(new DOMSource(document),new StreamResult("src/person.xml")); } /**使用jaxp删除节点 * 1.创建解析工厂 * 2.创建解析器 * 3.解析xml返回document对象 * 4.得到sex元素 * 5.得到sex的父节点 * 6.删除sex * 7.回写xml * @Title:removeElement * @Description: * @return void */ public static void removeElement() throws Exception{ DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = builderFactory.newDocumentBuilder(); Document document = builder.parse("src/person.xml"); Node sex = document.getElementsByTagName("sex").item(0); Node p1 = sex.getParentNode(); p1.removeChild(sex); TransformerFactory transformerFactory = TransformerFactory.newInstance(); Transformer transformer = transformerFactory.newTransformer(); transformer.transform(new DOMSource(document),new StreamResult("src/person.xml")); } /**使用jaxp遍历节点:打印所有元素的名称 * 1.创建解析工厂 * 2.创建解析器 * 3.解析xml返回document对象 * * ===使用递归得到所有节点 * 4.得到根节点 * 5.得到根节点的子节点 * 6.得到根节点的子节点的子节点 * @Title:forEachElement * @Description: * @return void */ public static void forEachElement() throws Exception{ DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = builderFactory.newDocumentBuilder(); Document document = builder.parse("src/person.xml"); //用一个方法实现递归遍历所有节点 listNodes(document); } private static void listNodes(Node node) { if(node.getNodeType() == node.ELEMENT_NODE){ System.out.println("属性名:" + node.getNodeName()); } //得到一层子节点 NodeList list = node.getChildNodes(); //遍历list for (int i = 0; i < list.getLength(); i++) { //得到每一个节点 Node node1 = list.item(i); //递归调用 listNodes(node1); } } public static void main(String[] args) { try { // selectAll(); // selectSingnal(); // addElement(); // modifyElement(); // removeElement(); forEachElement(); } catch (Exception e) { e.printStackTrace(); } } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |