XML概述 XML 指可扩展标记语言(EXtensible Markup Language) XML 是一种标记语言,很类似 HTML XML 和 HTML都是从SGML衍生出来的 XML 的设计宗旨是传输数据,而非显示数据 XML 标签没有被预定义。需要自行定义标签。 XML 文件后缀名为xml w3cshool是很好的教程,可去学习 XML和HTML的关系 XML 和 HTML 为不同的目的而设计: XML 被设计为传输和存储数据,其焦点是数据的内容。 HTML 被设计用来显示数据,其焦点是数据的外观。 HTML 旨在显示信息,而 XML 旨在传输信息。 XML 标签没有被预定义。需要自行定义标签。 HTML 是语法不严格的,XML是语法严格的(不能有任何错误) XML的特点 XML 是不作为的,即 XML 不会做任何事情。只是提供了一种独立于软件和硬件的数据存储方法。需要自己对XML进行解析并操作 XML 仅仅是纯文本,标签都是自定义的.有能力处理纯文本的软件都可以处理 XML。(跨平台,跨语言) XML 被设计用来结构化、存储以及传输信息。 XML 的主要用途:配置文件,存储数据 树结构 XML 文档形成了一种树结构,它从“根部”开始,然后扩展到“枝叶”。 XML 文档必须包含根元素。该元素是所有其他元素的父元素。 父、子以及同胞等术语用于描述元素之间的关系。父元素拥有子元素。相同层级上的子元素成为同胞(兄弟或姐妹)。 所有元素均可拥有文本内容和属性(类似 HTML 中)。 XML语法规则 XML是语法严格的(不能有任何错误) XML 文档必须有根元素 XML 元素必须有关闭标签 XML 标签对大小写敏感 XML 必须正确地嵌套 XML 的属性值必须加引号 XML语法 * 文档声明 位置:xml文档第一行 格式:<?xml version="1.0" encoding="编码" ?> version : 指xml版本,目前只有1.0 encoding : 文档内容编码(字符集) * 元素 XML元素就是XML中出现的标签 书写方式: <a>内容</a> | <a /> xml解析时会将空格和回车换行当做内容处理(和html不一样) 元素可包含其他元素、文本或者两者的混合物。元素也可以拥有属性。 XML元素命名规则: 名称可以含字母、数字以及其他的字符 名称不能以数字或者标点符号开始 名称不能以字符 “xml”(或者 XML、Xml)开始 名称不能包含空格 尽量避免 - . : * 属性 标签名称之后,使用空格分隔,属性名="属性值" ,属性值需要引号括住(一般使用双引号) * 注释 格式:<!-- 注释内容 --> 注意:注释内容中,不能使用"--"特殊字符 * 字符实体 * xml存在特殊的字符,xml语法中所使用的字符 < < > > & & * CDATA区 * 特殊的区域可以书写任意字符 格式:<![CDATA[ 任意内容 ]]> * 处理指令(processing instruction) (了解) * 指挥解析引擎如何解析XML文档内容 位置:文档声明下方 例如,通知XML解析引擎,使用css文件显示xml文档内容:<?xml-stylesheet type="text/css" href="1.css"?> XML中文乱码 * 文件编码 可以通过记事本打开,通过 文件-->另存为-->编码 查看(windows 默认编码GBK) * 内容编码 由文档声明的encoding属性来确定,浏览器根据此编码解析xml文件 * 两者统一即可解决中文乱码 约束 * 约束,规定如何编写xml内容 * 分类:DTD、schema XML DTD * DTD 的作用是定义 XML 文档的结构。它使用一系列合法的元素来定义文档结构 * 文件扩展名:dtd * 为XML文档添加DTD约束的方式 * 内部关联 将DTD约束内容编写在xml文档 格式:在文档声明下添加<!DOCTYPE 根元素 [约束内容]> * 外部关联 将DTD约束内容编写在DTD文档中,然后引入外部DTD文档 格式:在文档声明下添加<!DOCTYPE 根元素 SYSTEM "DTD文件路径"> * 公共关联 DTD文档在互联网上,框架使用的DTD都是公共关联 格式:在文档声明下添加<!DOCTYPE 根元素 PUBLIC "DTD名称" "DTD在web地址URL"> * DTD语法 * 从根元素开始,从上往下进行约束 * 元素约束 * 格式:<!ELEMENT 元素名称 内容约束> 内容约束:符号、类型 符号 ? --> 0或1个 * --> 0到多个 + --> 一个或多个 , --> 多个元素必须顺序使用 | --> 多个元素选择一个 () --> 分组 类型 (#PCDATA) -->标签体必须是文本,不能有其他标签 EMPTY -->不能有标签体,即不能有内容 * 示例: <!ELEMENT books (book+)> <!ELEMENT book (title?,price*,author)> <!ELEMENT title (#PCDATA)> <!ELEMENT price (#PCDATA)> <!ELEMENT author EMPTY> * 属性约束 * 格式:<!ATTLIST 元素名称 属性约束 属性约束...> 属性约束: 属性名 属性类型 约束 属性类型: CDATA --> 文本 (a|b|c) --> 多选一 ID --> 唯一标识,不能以数字开头,不能为空 IDREF --> ID引用 约束: #REQUIRED -->必须 required #IMPLIED -->可选 implied #FIXED value -->固定一个值 value为具体的值 默认值 * 示例: <!ATTLIST book id ID #REQUIRED lang CDATA #IMPLIED city (北京|上海|广州) "北京" company CDATA #FIXED "itcast"> 也可以分开写,如 <!ATTLIST book id ID #REQUIRED> <!ATTLIST book lang CDATA #IMPLIED> * 实体 * 相当于变量 * 引用实体(一般实体): 在DTD中定义,在xml中使用 DTD定义:<!ENTITY 实体名称 "内容"> xml使用:&实体名称; * 参数实体: 在DTD中定义,在DTD中使用 DTD定义:<!ENTITY % 实体名称 "内容"> DTD使用:%实体名称; * 示例: 在DTD定义实体 <!--引用实体--> <!ENTITY info "公司信息提示"> <!--参数实体--> <!ENTITY % part "title?,price*"> 在DTD中使用参数实体 <!ELEMENT book (%part;,author)> 在xml中使用引用实体 <title>&info;</title> * 完整示例: books2.dtd <?xml version="1.0" encoding="UTF-8"?> <!--根元素--> <!ELEMENT books (book+)> <!ELEMENT book (title?,price*;,author)> <!ELEMENT title (#PCDATA)> <!ELEMENT price (#PCDATA)> <!ELEMENT author EMPTY> <!-- 给book添加属性--> <!ATTLIST book id ID #REQUIRED lang CDATA #IMPLIED city (北京|上海|广州) "北京" company CDATA #FIXED "itcast" > books2.xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE books SYSTEM "books2.dtd"> <books> <book id="b001" lang="cn" city="上海"> <title></title> <price>abc</price> <price></price> <author /> </book> </books> XML Schema(不要求会写,要求能看懂) * XML Schema 是新的xml约束(比DTD复杂,比DTD强大) * schema文档本身就是xml * 文件扩展名:xsd(XML Schema Definition) * 命名空间(namespace): 将schema文档中元素和属性,与URL进行绑定,用来处理名字的冲突。相当于java中的包 * 创建schema文件 <?xml version="1.0" encoding="UTF-8"?> <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/books" xmlns:tns="http://www.example.org/books" elementFormDefault="qualified"> </schema> 说明: schema 为根元素,固定 xmlns="http://www.w3.org/2001/XMLSchema" 规定默认的命名空间,没有前缀的标签默认来自于此命名空间(如根标签schema).后面的命名空间规定了schema文档的格式(此命名空间自动引入) targetNamespace="http://www.example.org/books" 给当前schema文档定义命名空间,可以给别人使用.要求:全球唯一 xmlns:tns="http://www.example.org/books" 为命名空间指定前缀,前缀为tns. elementFormDefault="qualified" 指出任何 XML 实例文档所使用的且在此 schema 中声明过的元素必须被命名空间限定。 * 在xml中使用Schema约束 <?xml version="1.0" encoding="UTF-8"?> <books xmlns="http://www.example.org/books" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/books books.xsd"> </books> 说明: books 为根元素 xmlns="http://www.example.org/books" 规定默认的命名空间,没有前缀的标签默认来自于此命名空间(如根标签books).这个命名空间需要在下面引入 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 为命名空间指定前缀,前缀为xsi,后面的命名空间的作用是获取schema文档实例,引入后才可以使用schemaLocation属性(此命名空间自动引入) xsi:schemaLocation="http://www.example.org/books books.xsd" 确定xsd文件位置,需要 目标文件命名空间 和 xsd文件路径.可以有多个,用空格或换行隔开 * 小结 targetNamespace : 在xsd文件中使用,用来指定命名空间,即url xsi:schemaLocation : 在xml文件中使用,用来引入其他xsd文件,包括命名空间和文件位置 xmlns : 定义默认命名空间 xmlns:前缀 : 为命名空间指定前缀 注意:schemaLocation属性在w3c的一个命名空间中,所以要先添加 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" * schema示例: books2.xsd <?xml version="1.0" encoding="UTF-8"?> <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/books2" xmlns:tns="http://www.example.org/books2" elementFormDefault="qualified"> <!-- 1 确定根元素 --> <element name="books"> <!-- 2 确定元素成员是否复杂 <simpleType> 简单类型,具有简单类型的的元素只能包含字符数据,不能包含子元素,也不能有属性 <complexType> 复杂类型,具有复杂类型的元素可以有子元素和属性 3 确定元素成员出场顺序 <sequence> 顺序 ##>等价于dtd , <choice> 选择 ##> 等价于 dtd | <all> 任意 minOccurs 最小出现次数,默认值1 maxOccurs 最大出现次数,默认值1 minOccurs=0 , maxOccurs=1 等价于 ? minOccurs=1 , maxOccurs=unbounded 等价于 + minOccurs=0 , maxOccurs=unbounded 等价于 * --> <complexType> <sequence minOccurs="1" maxOccurs="unbounded"> <element name="book"> <complexType> <sequence> <element name="title" type="string"></element> <element name="price"> <complexType> <simpleContent> <extension base="int"> <attribute name="unit" use="required"></attribute> </extension> </simpleContent> </complexType> </element> </sequence> <!-- 确定属性 optional 表示可选 required 表示必须 --> <attribute name="id" use="required" type="ID"></attribute> </complexType> </element> </sequence> </complexType> </element> </schema> books2.xml <?xml version="1.0" encoding="UTF-8"?> <books xmlns="http://www.example.org/books2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/books2 books2.xsd"> <book id="b001"> <title></title> <price unit="元">123</price> </book> <book id="b002"> <title></title> <price unit="美元">123</price> <!--带属性和标签体的标签--> </book> </books> XML解析 * 解析方式:DOM 和 SAX * DOM方式:将整个文档加载到内存,获得一个Document对象,根据Document对象操作 w3c推出规范 优点:可完成增删改查操作 缺点:不易操作大文件,比较占用内存,极易出现内存溢出 * SAX方式:逐行解析,事件驱动 xml社区推出,民间 优点:占用内存小 缺点:只能读取,不能修改 * xml解析器:根据不同解析方式完成xml解析。操作比较繁琐 * xml解析开发包:根据解析器提供一些容易操作的api. * jaxp -- java提供(Java API for XML Processing) * dom4j -- 第三方提供,比较简单 jaxp--dom方式解析 * javax.xml.parsers包 * 代码示例: 在项目根目录下创建books.xml <?xml version="1.0" encoding="UTF-8"?> <books> <book id="b001"> <title>java编程思想</title> <price>68</price> </book> <book id="b002"> <title>数据结构</title> <price>32</price> </book> </books> java代码 package test; import java.io.File; import javax.xml.parsers.*; import javax.xml.transform.*; import javax.xml.transform.dom.*; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.*; public class Jaxp_dom { public static void main(String[] args) throws Exception { DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();//获得解析器工厂类 DocumentBuilder builder=factory.newDocumentBuilder();//获得解析器 Document document=builder.parse(new File("books.xml"));//获得指定xml文件的Document对象 //add(document,"books.xml");//增 //update(document,"books.xml");//改 //delete(document,"books.xml");//删 query(document);//查 } //查 private static void query(Document document){ NodeList list=document.getElementsByTagName("book");//获得指定名称的节点 for(int i=0;i<list.getLength();i++){ Element element=(Element)list.item(i);//获得每一个节点 String value=element.getAttribute("id");//获取指定名称的属性值 System.out.println("id-->"+value); NodeList list2=element.getChildNodes();//获取所有子节点(不只是元素节点,换行也算) for(int j=0;j<list2.getLength();j++){ Node node=list2.item(j); if(node.getNodeType()==Node.ELEMENT_NODE){//判断是否是元素节点 Element element2=(Element)node; String name=element2.getNodeName();//获取节点名称 String text=element2.getTextContent();//获取节点文本内容 System.out.println(name+":"+text); } } } } //增 private static void add(Document document,String fileName){ Element rootElement=document.getDocumentElement();//获得根元素 Element newElement=document.createElement("book");//创建新元素 newElement.setAttribute("id", "b003");//设置属性 Element newName=document.createElement("title");//添加一个子元素 newName.setTextContent("职业生涯规划");//设置元素文本 newElement.appendChild(newName); Element newAge=document.createElement("price");//添加一个子元素 newAge.setTextContent("22");//设置元素文本 newElement.appendChild(newAge); rootElement.appendChild(newElement);//把节点添加到document baoCun(rootElement,fileName);//保存 } //改 private static void update(Document document,String fileName){ //先查找再修改 NodeList list=document.getElementsByTagName("book");//获得指定名称的节点 for(int i=0;i<list.getLength();i++){ Element element=(Element)list.item(i); if("b002".equals(element.getAttribute("id"))){ NodeList list2=element.getElementsByTagName("title"); Element element2=(Element)list2.item(0); element2.setTextContent("数据结构2");//修改 } } Element rootElement=document.getDocumentElement(); baoCun(rootElement,fileName);//保存 } //删 private static void delete(Document document,String fileName){ //先查找再删除 NodeList list=document.getElementsByTagName("book");//获得指定名称的节点 for(int i=0;i<list.getLength();i++){ Element element=(Element)list.item(i); if("b002".equals(element.getAttribute("id"))){ element.getParentNode().removeChild(element);//删除 } } Element rootElement=document.getDocumentElement(); baoCun(rootElement,fileName);//保存 } //保存 private static void baoCun(Element element,String fileName){ try { //1 获得转换工厂 TransformerFactory transformerFactory = TransformerFactory.newInstance(); //2 获得转换器 Transformer transformer = transformerFactory.newTransformer(); //3.1 将节点封装成转换器需要的源 ,此处使用的是Source接口与dom有关的实现类DOMSource Source xmlSource = new DOMSource(element); //3.2 将保存文件的位置封装转换器需要的结果对象,此处使用的是Result与文件流有关的实现类SteamResult Result outputTarget = new StreamResult(new File(fileName)); //4 保存数据,及将指定的节点保存到指定的文件中 transformer.transform(xmlSource, outputTarget); System.out.println("保存成功"); } catch (Exception e) { throw new RuntimeException(e.getMessage(),e); } } //获取给定元素的所有属性 private static void getAttrs(Element element){ NamedNodeMap maps=element.getAttributes(); for(int i=0;i<maps.getLength();i++){ Attr attr=(Attr)maps.item(i); String name=attr.getName(); String value=attr.getValue(); System.out.println(name+"-->"+value); } } } jaxp--sax方式解析 * javax.xml.parsers包 * DefaultHandler是sax解析事件驱动默认处理类,什么功能都没有完成。需要覆写相应的方法 * 代码示例 在项目根目录下创建books.xml <?xml version="1.0" encoding="UTF-8"?> <books> <book id="b001"> <title>java编程思想</title> <price>68</price> </book> <book id="b002"> <title>数据结构</title> <price>32</price> </book> </books> 创建类 //1工厂 SAXParserFactory factory = SAXParserFactory.newInstance(); //2解析器 SAXParser saxParser = factory.newSAXParser(); //3解析 saxParser.parse(new File("books.xml"), new MyDefaultHandler()); 创建类MyDefaultHandler,继承于DefaultHandler,重写其中的方法即可,例 package test; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; public class MyDefaultHandler extends DefaultHandler { public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { System.out.println("-->元素开始 : " + qName); //获得属性 String id = attributes.getValue("id"); System.out.println("id --> " + id); } public void endElement(String uri, String localName, String qName) throws SAXException { System.out.println("-->元素结束 : " + qName); } public void characters(char[] ch, int start, int length) throws SAXException { System.out.println("## -->文本 @@ " + new String(ch,start,length)); } } dom4j(以dom方式解析xml) * 第三方实现对xml进行解析,需导入jar包.(/dom4j/) * 核心jar : dom4j-1.6.1.jar * 相关jar : xpath表达式 jaxen-1.1-beta-6.jar * dom4j是以dom方式解析xml的,dom4j在解析xml时,将生成dom4j的dom树 * 代码示例: 注意:代码中使用的xpath表达式,可以去w3cschool学习 在项目根目录下创建books.xml <?xml version="1.0" encoding="UTF-8"?> <books> <book id="b001"> <title>java编程思想</title> <price>68</price> </book> <book id="b002"> <title>数据结构</title> <price>32</price> </book> </books> java代码(需导入两个jar: dom4j-1.6.1.jar和jaxen-1.1-beta-6.jar) package test; import java.io.File; import java.io.FileOutputStream; import java.util.List; import org.dom4j.*; import org.dom4j.io.*; public class Test { public static void main(String[] args) throws Exception { //获取Document对象 SAXReader saxReader=new SAXReader(); Document document=saxReader.read(new File("books.xml")); //update(document,"books.xml");//改 //add(document,"books.xml");//增 //delete(document,"books.xml");//删 query(document);//查 } //查 private static void query(Document document){ //获取根元素 Element rootElement=document.getRootElement(); //获得所有元素 List allChildElements=rootElement.elements(); //循环 for(Object o : allChildElements){ Element element=(Element)o; String value=element.attributeValue("id");//获取属性值 System.out.println(value); List allChildElements2=element.elements(); for(Object o2 : allChildElements2){ Element element2=(Element)o2; String name=element2.getName();//获取元素名称 String text=element2.getTextTrim();//获取元素文本 System.out.println(name+":"+text); } } } //改 private static void update(Document document,String file) throws Exception{ //获取根元素 Element rootElement=document.getRootElement(); //修改 Node node=document.selectSingleNode("//book[@id='b001']/title"); //使用了xpath表达式,需添加jar包(jaxen-1.1-beta-6.jar) node.setText("java编程思想2"); //保存 XMLWriter write=new XMLWriter(new FileOutputStream(new File(file))); write.write(document); write.close(); System.out.println("修改成功"); } //增 private static void add(Document document,String file) throws Exception{ //获取根元素 Element rootElement=document.getRootElement(); //添加元素 Element newElement=rootElement.addElement("book"); newElement.addAttribute("id", "b003"); newElement.addElement("title").addText("职业生涯规划");//链式编程 newElement.addElement("price").addText("30"); //保存 FileOutputStream out=new FileOutputStream(new File(file)); //XMLWriter write=new XMLWriter(out); XMLWriter write=new XMLWriter(out,OutputFormat.createPrettyPrint());//第二个参数可格式化xml的格式 write.write(document); write.close(); System.out.println("增加成功"); } //删 private static void delete(Document document,String file) throws Exception{ //添加元素 Node node=document.selectSingleNode("//book[@id='b003']"); //使用了xpath表达式,需添加jar包(jaxen-1.1-beta-6.jar) node.getParent().remove(node); //保存 FileOutputStream out=new FileOutputStream(new File(file)); //XMLWriter write=new XMLWriter(out); XMLWriter write=new XMLWriter(out,OutputFormat.createPrettyPrint());//第二个参数可格式化xml的格式 write.write(document); write.close(); System.out.println("删除成功"); } }
xml
最新推荐文章于 2024-02-26 00:23:08 发布