xml入门

来源:互联网 发布:中超2017点球数据 编辑:程序博客网 时间:2024/06/01 09:12

xml介绍

文档说明

一个良好的xml文件,需要对xml文件有一个基本的介绍和基础属性的设置.最基本的文档说明如下:

<span style="font-size:18px;"><?xml version="1.0" ?></span>


常见的文档说明如下

<span style="font-size:18px;"><?xml version="1.0" encoding="UTF-8" standalone="no"?><!--   version:声明版本号        <span style="color:#ff0000;">encoding:指定编码格式,例如 gb2312  utf-8     注意在编写文件中存取和读取的编码需一致</span>   standalone:文档是否独立 --></span>




元素(element)

声明格式以下两种xml声明格式

<span style="font-size:18px;"><!-- 声明格式1 --><a id="9527">...</a>  <!-- 常常把一个元素称为一个标签   --><!-- 声明格式2 --><a id="9527"/>    <!--此声明格式不含子标签 --></span>

xml元素需要注意一些规范

                          1.大小写区分,不能包含空格,不能有;号

                          2.不要以_开头,也不要以xml开头


  注意:在xml文件中空格和换行都算是text内容,会被程序解析(红刷笔刷过的地方)



demo

<?xml version="1.0" encoding="UTF-8" standalone="no"?><exam><!--  根节点为exam --><student id="1" ><!--  子标签student  包含一个属性id --><name>xiaosan</name><!--  子标签name,location,grade--><location>沈阳</location><grade>89</grade></student><student id="2" ><name>xiaowu</name><location>合肥</location><grade>29</grade></student></exam>
  

特殊语法

使用<![CDATA[ .... ]]>告诉解析器不解析内含字段,原样输出。

<span style="font-size:18px;"><![CDATA[ <student id="1" ><!--  子标签student  包含一个属性id --><name>xiaosan</name><!--  子标签name,location,grade--><location>沈阳</location><grade>89</grade></student> ]]></span>

一些特殊字段使用转义字符来表示








xml约束

所谓的约束,即编写xml文件的指导说明。常用的xml约束有两种:DTD和Schema.DTD语法简单但是对属性类型具有局限性,Schema相对更为严谨也更为复杂,两者都有成熟的文档,可以参考文档编写,一般能看懂即可。


DTD约束

DTD可以直接在相应的xml文档中声明,也可以单独为一个dtd文件。


1.直接在xml文件中定义

<?xml version="1.0" encoding="UTF-8"?><!--  内部DTD声明 ,格式为:<!DOCTYPE root_name     root_name为xml文件的根节点[....]>--><!DOCTYPE person[<!ELEMENT person (人+)><!ELEMENT 人 (姓名+,年龄,(住址*|家乡?))><!ELEMENT 姓名 (#PCDATA)><!ELEMENT 年龄 (#PCDATA)><!ELEMENT 住址 (#PCDATA)>]><person><人><姓名>小李</姓名><年龄>23</年龄><住址>岗头村</住址></人><人><姓名>小王</姓名><姓名>隔壁老王</姓名><年龄>30</年龄><家乡>二八村</家乡></人></person>

2.单独编写一个DTD文件


person.dtd文件

<?xml version="1.0" encoding="UTF-8"?><!ELEMENT person (人+)><!ELEMENT 人 (姓名+,年龄,(住址*|家乡?))><!ELEMENT 姓名 (#PCDATA)><!ELEMENT 年龄 (#PCDATA)><!ELEMENT 住址 (#PCDATA)>


对应的person.xml文件
<?xml version="1.0" encoding="UTF-8"?><!--  使用外部声明的DTD ,需要加入:<!DOCTYPE 根元素名称   SYSTEM/PUBLIC  "外部文档名称或路径.dtd"  >--><<!DOCTYPE person PUBLIC SYSTEM "person.dtd"><person><人><姓名>小李</姓名><年龄>23</年龄><住址>岗头村</住址></人><人><姓名>小王</姓名><姓名>隔壁老王</姓名><年龄>30</年龄><家乡>二八村</家乡></人></person>



DTD语法简介

<?xml version="1.0" encoding="UTF-8"?><!ELEMENT person (人+)><!ELEMENT 人 (姓名+,年龄,(住址*|家乡?))><!ELEMENT 姓名 (原名|昵称)><!ATTLIST 原名中文名CDATA #REQUIRED英文名CDATA#IMPLIED阿三名         CDATA   #FIXED "乌拉拉"   ><!ATTLIST 昵称QQ昵称(xiao|li|wang) "sb"><!ELEMENT 年龄 (#PCDATA)><!ELEMENT 住址 (#PCDATA)><!--元素内容使用<span style="font-size:18px;color:#ff0000;">,号</span>表示出现次序需要一致元素内容使用<span style="font-size:18px;color:#ff0000;">|号</span>表示只能选择其一<span style="font-size:18px;color:#ff0000;">元素中使用+、?、*表示元素出现次数</span>? 0次或1次  (人?)+ 1次或多次 (人+)* 0次或多次 (人*)<span style="font-size:18px;color:#ff0000;">对于标签可以使用ATTLIST为其设置属性</span><!ATTLIST 元素名属性1类型   设置说明属性2...   ... ...><span style="font-size:18px;color:#ff0000;">常见类型</span>:cdata为常见字符串(?|?|?)给定范围取值id表示唯一属性entity表示一个实体(类似一个宏定义)...<span style="font-size:18px;color:#ff0000;">设置说明</span>:#REQUIRED必须有此属性#IMPLIED可有#FIXED固定值"xxx"如果没表定,则默认值-->





schema语法

因为schema的语法和xml语法类似。

  一个schema文档必须有一个根节点,且根节点名称为schema。每个schema模式文档可以声明一个名称空间,同时用一个唯一的URI表示。


在schema文件中

schema.xsd文档声明

 <!--根元素schema。   使用xmlns关键字引入命名空间xs   同时限定该文档的约束对象URI:www.delphifan.com  --><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"  targetNamespace="http://www.delphifan.com" elementFormDefault="qualified">


对于的xml文件中

<!--  xmlns="http://www.delphifan.com" ->使用默认命名空间        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  ->  使用xsi命名空间 配置 xsi:schemaLocation属性    xsi:schemaLocation="http://www.delphifan.com shiporder.xsd"  ->  声明该文档的约束文档的URI和对于的文档名称 --><shiporderxmlns="http://www.delphifan.com"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.delphifan.com shiporder.xsd"orderid="23" >

注意: 在声明xsi:schemaLocation属性时候按照xsi:xsi:schemaLocation="{namespace} {location}" 格式声明。namespace和location之间的空格不能少



demo

shiporder.xsd约束文档

<?xml version="1.0" encoding="UTF-8"?><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"targetNamespace="http://www.delphifan.com" elementFormDefault="qualified"><xs:element name="shiporder"><xs:complexType>    <!--complexType表示一个复杂类型 --><xs:sequence>      <!--xs:sequence表示元素值必须按顺序声明 --><xs:element name="orderperson" type="xs:string" /><xs:element name="shipto"><xs:complexType><xs:sequence><xs:element name="name" type="xs:string" /><xs:element name="address" type="xs:string" /><xs:element name="city" type="xs:string" /><xs:element name="country" type="xs:string" /></xs:sequence></xs:complexType></xs:element><xs:element name="item" maxOccurs="unbounded"><xs:complexType><xs:sequence><xs:element name="title" type="xs:string" /><xs:element name="note" type="xs:string" minOccurs="0" /><xs:element name="quantity" type="xs:positiveInteger" /><xs:element name="price" type="xs:decimal" /></xs:sequence></xs:complexType></xs:element></xs:sequence><xs:attribute name="orderid" type="xs:string" use="required" /></xs:complexType></xs:element></xs:schema>

shiporder.xml文档

<?xml version="1.0" encoding="UTF-8"?><shiporderxmlns="http://www.delphifan.com"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.delphifan.com shiporder.xsd"orderid="23" ><orderperson>fan</orderperson><shipto><name>xiaofan</name><address>hefei</address><city>anhui</city><country>zhongguo</country></shipto><item><title>schema technology</title><note>so handsome</note><quantity>23</quantity><price>12.2</price></item></shiporder>







xml解析

解析方式分为两种:dom和sax

dom(document object model )解析:

   一次性读取xml文件,可对xml里数据操作。 优点CRUD操作方便,但占用内存大


sax(simple API for XML)解析:

     一点一点读取。优点是占用内存小,速度快,但CRUD操作不方便


常用的xml解析开发包

jaxp(官方的不需要外部jar包)与dom4j(需要外部jar包)



DOM解析(jaxp包)

整体流程如图所示


过程大致分为两部分

1.修改部分

使用DocumentBuilderFactory产生factory对象-->产生DocumentBuilder对象 -->使用parse()方法得到ducment对象

对document对象可以获取指定元素,作CRUD操作等



2.保存部分

使用TransformerFactory-->得到factory对象-->得到Transformer()对象-->使用transform()方法把改变后的document对象存储至xml文件中 





demo

任务需求:要求编写一个工具类

1.直接操作Student对象在xml文件中存储

2.在xml文件中通过examid属性查找对应的student标签

 3.通过name属性在xml文件中删除对于的student标签




设计思路如下图




1.studentDao负责对xml文件操作,包含三个方法,即增加学生对象,删除,查找操作

2.因为对xml操作中有大量重复代码,故定义工具类简化操作



student类

package org.nihao.domain;public class Student {private int idcard;private int examid;private String name;private String location;private double score;public int getIdcard() {return idcard;}public void setIdcard(int idcard) {this.idcard = idcard;}public int getExamid() {return examid;}public void setExamid(int examid) {this.examid = examid;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getLocation() {return location;}public void setLocation(String location) {this.location = location;}public double getScore() {return score;}public void setScore(double score) {this.score = score;}}

studentDao.java

 package org.nihao.dao;import org.nihao.domain.Student;import org.nihao.exception.StudentNotExistException;import org.nihao.util.XmlUtils;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.NamedNodeMap;import org.w3c.dom.Node;import org.w3c.dom.NodeList;public class StudentDao {public void add(Student s){try {Document document = XmlUtils.getDocument();//checked exception//1.创建标签Element element = document.createElement("student");//创建子标签并填充子标签Element nameElement = document.createElement("name");nameElement.setTextContent(s.getName());Element locationElement = document.createElement("location");locationElement.setTextContent(s.getLocation());Element gradeElement = document.createElement("grade");gradeElement.setTextContent(Double.toString(s.getScore()));//2.填充数据element.setAttribute("idcard", Integer.toString(s.getIdcard()));element.setAttribute("examid", Integer.toString(s.getExamid()));element.appendChild(nameElement);element.appendChild(locationElement);element.appendChild(gradeElement);document.getElementsByTagName("exam").item(0).appendChild(element);//3.保存标签XmlUtils.write2Xml(document);} catch (Exception e) {throw new RuntimeException(e);  //运行时的异常} }public Student find(int examid){try {Document document = XmlUtils.getDocument();NodeList list = document.getElementsByTagName("student");for (int i = 0; i < list.getLength(); i++) {Element student = (Element) list.item(i);String attribute = student.getAttribute("examid");if (attribute.equals(Integer.toString(examid))) {Student stu = new Student();stu.setExamid(examid);stu.setIdcard(Integer.parseInt(student.getAttribute("idcard").trim()));stu.setLocation(student.getElementsByTagName("location").item(0).getTextContent());stu.setName(student.getElementsByTagName("name").item(0).getTextContent());stu.setScore(Double.parseDouble(student.getElementsByTagName("grade").item(0).getTextContent()));return stu;}}return null;} catch (Exception e) {throw new RuntimeException(e);  //运行时的异常}}public void delete(String name) throws StudentNotExistException{try {Document document = XmlUtils.getDocument();NodeList list = document.getElementsByTagName("name");for (int i = 0; i < list.getLength(); i++) {if (list.item(i).getTextContent().equals(name)) {list.item(i).getParentNode().getParentNode().removeChild(list.item(i).getParentNode());XmlUtils.write2Xml(document);return;}}throw new StudentNotExistException(name+"不存在!");  //自定义异常,用于通知调用者未查找到学生信息}catch(StudentNotExistException e){throw e;}catch (Exception e ) {throw new RuntimeException(e);  //运行时的异常}}}

XmlUtils.java

package org.nihao.util;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.transform.Transformer;import javax.xml.transform.TransformerException;import javax.xml.transform.TransformerFactory;import javax.xml.transform.dom.DOMSource;import javax.xml.transform.stream.StreamResult;import org.w3c.dom.Document;public class XmlUtils {private static String filename = "src/exam.xml";public static Document getDocument() throws Exception {DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();DocumentBuilder documentBuilder = factory.newDocumentBuilder();return documentBuilder.parse(filename);}public static void write2Xml(Document document) throws TransformerException{TransformerFactory factory = TransformerFactory.newInstance();Transformer transformer = factory.newTransformer();transformer.transform(new DOMSource(document), new StreamResult(filename));}}

exam.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?><exam><student id="1" ><name>xiaosan</name><location>沈阳</location><grade>89</grade></student><student id="2" ><name>xiaowu</name><location>合肥</location><grade>29</grade></student></exam>



sax解析

采用事件处理的方式解析xml文件,分为两个部分:解析器和事件处理器

解析过程如下图


解析器:通过JAXP的api直接创建


事件处理器:

       每当解析到一个组成部分,就会调用事件处理器的一个方法,同时会把解析出来的内容作为方法参数传递。

       新建一个对象实现给定的ContentHandler,并实现其中方法,重写常用的三个方法startElement、endElement、characters方法

或者使用官方帮我们实现了几个常用的类  DefaultHandler,DefaultHandler2, ValidatorHandler, XMLFilterImpl, XMLReaderAdapter




demo

public class Demo1 {public static void main(String[] args) throws Exception {//1.通过工厂得到解析器SAXParserFactory factory = SAXParserFactory.newInstance();SAXParser parser = factory.newSAXParser();//2.通过解析器得到ReaderXMLReader xmlReader = parser.getXMLReader();//设置内容处理器xmlReader.setContentHandler(new handler());//3.解析xmlReader.parse("src/book.xml");}}class handler implements ContentHandler{@Overridepublic void setDocumentLocator(Locator locator) {}@Overridepublic void startDocument() throws SAXException {}@Overridepublic void endDocument() throws SAXException {}@Overridepublic void startPrefixMapping(String prefix, String uri)throws SAXException {}@Overridepublic void endPrefixMapping(String prefix) throws SAXException {}@Overridepublic void startElement(String uri, String localName, String qName,Attributes atts) throws SAXException {System.out.println("<"+qName+">");}@Overridepublic void endElement(String uri, String localName, String qName)throws SAXException {System.out.println("<"+qName+">");}@Overridepublic void characters(char[] ch, int start, int length)throws SAXException {System.out.println(new String(ch,start,length));}@Overridepublic void ignorableWhitespace(char[] ch, int start, int length)throws SAXException {}@Overridepublic void processingInstruction(String target, String data)throws SAXException {}@Overridepublic void skippedEntity(String name) throws SAXException {}}






使用dom4j对xml操作

dom4j的说明文档非常详细,其中包含强大的xpath正则表达式获取元素方法。这里只贴一些简单的demo,需要使用dom4j之间查看其官方的文档即可。

 

ADU操作

public void add() throws  Exception{SAXReader reader = new SAXReader();Document document =  reader.read(new File("src/book.xml"));Element book = document.getRootElement().element("书");List elements = book.elements();Element element = DocumentHelper.createElement("售价");element.setText("200yuan");elements.add(2, element);//修改完毕后,输出存储OutputFormat format = OutputFormat.createPrettyPrint();format.setEncoding("UTF-8");XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),format);writer.write(document);writer.close();}public void delete() throws  Exception{SAXReader reader = new SAXReader();Document document =  reader.read(new File("src/book.xml"));Element book = document.getRootElement().element("书");book.remove(book.element("售价"));OutputFormat format = OutputFormat.createPrettyPrint();format.setEncoding("UTF-8");XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),format);writer.write(document);writer.close();}public void update() throws  Exception{SAXReader reader = new SAXReader();Document document =  reader.read(new File("src/book.xml"));Element book = (Element) document.getRootElement().elements("书").get(1);book.element("售价").setText("2999元");OutputFormat format = OutputFormat.createPrettyPrint();format.setEncoding("UTF-8");XMLWriter writer = new XMLWriter(new FileOutputStream("src/book.xml"),format);writer.write(document);writer.close();<pre name="code" class="java">                  }



public class Demo3 {//基本的XPATH操作public void xpath() throws Exception{SAXReader reader = new SAXReader();Document document =  reader.read(new File("src/book.xml"));String text = document.selectSingleNode("//作者").getText();System.out.println(text);}}
















schema语法

因为schema的语法和xml语法类似,且对类型的限制远好于DTD的类型限制,故schema的使用会更加广泛。

 文档后缀名:xxx.xsd       一个schema文档必须有一个根节点,且根节点名称为schema 。每个schema模式文档可以声明一个名称空间,同时用一个唯一的URI表示。


在schema文件中

schema文档的头元素声明

<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"     根元素schema。  使用xmlns关键字引入命名空间xs  同时限定该文档的约束对象URI:www.delphifan.comtargetNamespace="http://www.delphifan.com" elementFormDefault="qualified">


对于的xml文件中

<?xml version="1.0" encoding="UTF-8"?><shiporderxmlns="http://www.delphifan.com"       使用默认命名空间   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    使用xsi命名空间  并声明该文档的约束文档的URI和对于的文档名称xsi:schemaLocation="http://www.delphifan.com shiporder.xsd"orderid="23" >
注意 在声明xsi:schemaLocation属性时候按照xsi:xsi:schemaLocation="{namespace} {location}" namespace和location之间的空格不能少。

具体的细节可以参考schema官方文档。


demo

shiporder.xsd约束文档

<?xml version="1.0" encoding="UTF-8"?><xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"targetNamespace="http://www.delphifan.com" elementFormDefault="qualified"><xs:element name="shiporder"><xs:complexType>    <!--complexType表示一个复杂类型 --><xs:sequence>      <!--xs:sequence表示元素值必须按顺序声明 --><xs:element name="orderperson" type="xs:string" /><xs:element name="shipto"><xs:complexType><xs:sequence><xs:element name="name" type="xs:string" /><xs:element name="address" type="xs:string" /><xs:element name="city" type="xs:string" /><xs:element name="country" type="xs:string" /></xs:sequence></xs:complexType></xs:element><xs:element name="item" maxOccurs="unbounded"><xs:complexType><xs:sequence><xs:element name="title" type="xs:string" /><xs:element name="note" type="xs:string" minOccurs="0" /><xs:element name="quantity" type="xs:positiveInteger" /><xs:element name="price" type="xs:decimal" /></xs:sequence></xs:complexType></xs:element></xs:sequence><xs:attribute name="orderid" type="xs:string" use="required" /></xs:complexType></xs:element></xs:schema>

shiporder.xml文档

<?xml version="1.0" encoding="UTF-8"?><shiporderxmlns="http://www.delphifan.com"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.delphifan.com shiporder.xsd"orderid="23" ><orderperson>fan</orderperson><shipto><name>xiaofan</name><address>hefei</address><city>anhui</city><country>zhongguo</country></shipto><item><title>schema technology</title><note>so handsome</note><quantity>23</quantity><price>12.2</price></item></shiporder>









0 0
原创粉丝点击