Web基础:xml

来源:互联网 发布:腾讯手游模拟器mac版 编辑:程序博客网 时间:2024/06/07 22:08

XML

eXtensible Markup Language,主要用于自定义标记。

相较于它的兄弟HTML,XML语法十分严谨,不像HTML能够交叉嵌套,甚至有些标签可以省略掉结束标签。由于其语法的严谨性,能保证使用一个

统一的解析器进行解析,从而能确保跨平台的实现,以及互操作性。

常用解析器包括:MSXML、OpenXML、IBM XML4J、Apache Xerces、Oracel XML Parser等。


应用范围

数据交换

web service

数据管理(数据库)

系统配置


技术体系

校验(DTD+Schema)

显示与转换(XSL)

查询(XPath)

API(DOM+SAX)

链接(XLinker+XPointer)


构成


XML文档声明

<?xml version="1.0" encoding = "utf-8"? standalone="yes">

文档声明有以下两个规范。

1.声明放在XML文档的开头。

2.声明一般包括三部分:

version

版本,目前常用XML1.0。

encoding

字符编码,默认为UTF-8。

standalone

文档定义是否在同一个文件内。

*处理指令:

以“<?”开始,以“?>”结束,用于被解析器解析。


文档类型声明

DOCTYPE,紧随XML声明,包含实体声明等DTD内容。

<!DOCTYPE 根元素 [<!ENTITY 实体名 "实体内容">]>


实体

相当于全局变量的作用,置于文档类型声明中。

实体定义格式为:

<!ENTITY 实体名 实体内容>

预定义实体:

<:&lt;

>:&gt;

&:&amp;

":&quot;

':&apos;

引用实体:

&实体名;,例:

<!DOCTYPE currencyType [<!ENTITY dollar "$">]><currencyType >$</currencyType >


根元素

每个XML文档的根元素有且仅有一个。


文本内容

PCDATA(Parsed Character Data)。文本内容中的特殊字符,需要用实体代替。

<![PCDATA[content]]>

其中的标签字符将被解析器当做元素处理,实体将展开。


纯文本内容

CDATA(Character Data),全部当做文本处理,其中的任何字符都不被解析器解析。

<![CDATA[content]]>


注释

<!--注释内容-->

注释不能嵌套,不能出现在标记内部。


属性

属性值用引号包住,不能包含特殊符号(需转义)。


良构

一个良构的XML文档能够被解析器正确解析。良构需要满足以下两方面的要求。

结构规范

1.必须有声明语句。

2.必须有且仅有一个根元素。

3.属性值用引号包含。

4.标记成对,无交叉嵌套,空标记正确关闭。

元素规范

1.不能以数字和下划线开头。

2.不能以任何大小写xml开头。

3.不能包含空格。

4.不能包含冒号。

如下是一个良构的XML。


<?xml version="1.0" encoding = "utf-8" standalone="yes"?><person><job><name>CEO</name><type>IT</type><money>$10</money></job><family><wife sex="female"></wife><house area="200" money="$3000000"></house><cars><car brand="benz"></car><car brand="landroller"></car></cars></family></person>


DTD

Document Type Definition,一套用于校验、规范XML的规,能够指示XML文档的良构。

DTD不能跨平台,Schema弥补了这一缺陷。

定义位置

1.XML文档内部

<!DOCTYPE person[...]>

2.引用外部DTD

<!DOCTYPE person SYSTEM "person_dtd.dtd">

3.引用公共DTD

<!DOCTYPE person PUBLIC "url">


元素规范

用于规范元素的结构、内容,定义在文档类型声明中,其格式为:

<!ELEMENT 元素名 (规范内容)>

例:

<?xml version="1.0"?><!DOCTYPE books[<!ELEMENT books (book+)><!ELEMENT book (price?,name?)><!ELEMENT price (#PCDATA)><!ELEMENT name (#PCDATA)>]>

上例中的规范意义如下:

#PCDATA:元素内容可为任意字符串,但不再包含子元素。

EMPTY:元素必须为空。

ANY:元素内容可包含任意在DTD中定义的元素。

其中,符号的意义为:

?:出现且仅出现一次。

+:出现不少于一次。

*:不出现或出现任意次。

():给子元素分组。

|:选择一个子元素。

,:指定元素出现的顺序。


属性规范

用于规范属性的值,格式如下:

<!ATTLIST 元素 属性名1 属性类型/属性值 约束属性名2 属性类型/属性值 约束......>

约束包括:

#REQUIRED必填属性。

#IMPLIED:属性可有可无。

#FIXED:属性值必须为属性类型指定的内容。

"默认值":为属性提供默认值。

例:

<!ATTLIST personname CDATA #REQUIREDage CDATA #REQUIREDsex (male|female) #REQUIREDoccupation CDATA #IMPLIEDnationality "CHINESE" #FIXEDsalary CDATA "0.0">


实例

如下的XML文档(books.xml)将被下文使用。

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE books [<!ELEMENT books (category+)><!ELEMENT category (book+)><!ELEMENT book (title?,author?)><!ELEMENT title (#PCDATA)><!ELEMENT author (#PCDATA)><!ATTLIST categoryid CDATA #REQUIREDname CDATA #REQUIRED><!ATTLIST bookid CDATA #REQUIREDprice CDATA"0.0">]><books><category id="01" name="Novel"><book id="0101" price="100.5"><title>War And Peace</title><author>Tolstoy</author></book><book id="0102"  price="101"><title>Gone With The Wind</title><author>Margaret</author></book><book id="0103"  price="101.5"><title>The Old Man And The Sea</title><author>Hemingway</author></book></category><category id="02" name="Economics"><book id="0201" price="50"><title>The Currency Wars</title><author>Song</author></book><book id="0202" price="60"><title>Principle Of Economics</title><author>Mankiw</author></book></category><category id="03" name="Psychology"><book id="0301" price="40"><title>Psychology And Life</title><author>Gerrig</author></book><book id="0302" price="45"><title>Social Psychology</title><author>Miles</author></book></category></books>

Java解析XML

DOM4J

一次性读取整个XML文档,可以访问任意节点,适用于小型XML文档。

JAR

dom4j-1.6.1.jar

API

SAXReader类

read

Document doc = new SAXReader().read(inputStream);

由SAXReader对象读取指定的XML文件,获取Document类对象。


Document类

selectNodes / selectObject

List<Element> selectNodes(nodePath);

读取指定路径的元素,包括其所有子元素,返回一个树形结构的元素List。

两者虽然名字不同,但在我的使用过程中并未发现任何不同。

元素路径nodePath包含三类定义:

1.绝对路径:如"a/b/c",指向a->b->c元素。

2.查找路径:"//c",获取所有的c元素。

3.属性值过滤:如"//c[@id!=1]",获取所有id属性值不为1的c元素。


Element类

getName

String getName();

获取元素名。


attributeValue

String attributeValue(attributeName);

获取指定名称的属性值。


element

Element element(childNodeName);

获取指定名称的子元素对象。


elements

List<Element> elements();

获取所有子元素。


getText

String getText();

获取元素内的文本内容。


getPath

String getPath();

获取元素路径。


getParent

Element getParent();

获取父元素对象。


实例


如下是一个利用DOM4J对上文中的books.xml进行解析的实例。

public class TestDom4j {public static void main(String[] args) {SAXReader reader = new SAXReader();try {Document doc = reader.read(new FileInputStream("xml/books.xml"));List<Element> categories = (List<Element>) doc.selectNodes("//category");for (Element element : categories) {System.out.println(element.getName()+element.attributeValue("id")+":"+element.attributeValue("name"));List<Element> books = element.elements();for (Element element2 : books) {Element bookTitle = element2.element("title");Element bookAuthor = element2.element("author");String bookPrice = element2.attributeValue("price");System.out.println("\t<<"+bookTitle.getText()+">> by "+bookAuthor.getText()+" of $"+bookPrice);}}} catch (FileNotFoundException e) {e.printStackTrace();} catch (DocumentException e) {e.printStackTrace();}}}


SAX

SAX(Simple API for XML),适用于大文件,从上至下解析。解析时多次读取,由事件驱动。

JAR

jaxen-1.1-beta-7.jar

限于篇幅,这里仅放出示例代码。

/** * SAX事件驱动解析方式 * @author hsdsmljj * */public class SAX_XML {/** * @param args */public static void main(String[] args) {try {//取得一个解析工厂实例SAXParserFactory factory=SAXParserFactory.newInstance();//得到解析器SAXParser parse=factory.newSAXParser();//开始解析[1:文件  2:事件]parse.parse("xml/books.xml", new ParseHandler());} catch (ParserConfigurationException e) {e.printStackTrace();} catch (SAXException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}}/** * 定义一个默认事件驱动 * @author hsdsmljj * */class ParseHandler extends DefaultHandler{static int i=0;List<Book> books=new ArrayList<Book>();Book book;String bookAuthor="";String bookPrice="";String bookTitle="";String qName="";@Overridepublic void startElement(String uri, String localName, String qName,Attributes attrs) throws SAXException {//如果在book元素的开始时if(qName.equals("book")){bookAuthor=attrs.getValue(0);bookPrice=attrs.getValue(1);book=new Book();book.setName(bookAuthor);book.setPrice(bookPrice);}//记录当前在解析哪个元素this.qName=qName;}@Overridepublic void characters(char[] ch, int start, int length)throws SAXException {if(qName.equals("title") && book.getTitle()==null){System.out.println("============"+qName);book.setTitle(String.valueOf(ch, start, length));}}@Overridepublic void endElement(String uri, String localName, String qName)throws SAXException {System.out.println("------"+this.bookTitle);//当book节点结束时就进行扫尾处理if(qName.equals("book")){books.add(book);this.bookAuthor="";this.bookPrice="";this.bookTitle="";this.qName="";book=null;}}//文档结束@Overridepublic void endDocument() throws SAXException {for (Book book : books) {//自动调用toString方法System.out.println(book);}}}


JS解析XML

由于XML与HTML同根同源,因此解析XML时与解析HTML并无太大区别,诸如getElementById、getElementsByTagName等均能直接使用于XML元素节点上。
区别在于HTML的载入在初始化时就自动进行,并且自动实例化了document对象,而对于XML则需要手动载入,生存文档对象。

function loadxml(xmlFile){var xmlDoc;if(window.ActiveXObject){//创建组件对象xmlDoc=new ActiveXObject('Microsoft.XMLDOM');//是否异步加载xml文件 如果为ture,程序不论xml文件是否全部载入就开始运行下面程序,所以如果接下来就操作xml文件可能出错 xmlDoc.async = false;//加载xmlxmlDoc.load(xmlFile);  }else if(document.implementation && document.implementation.createDocument)   { xmlDoc = document.implementation.createDocument('', '', null);   xmlDoc.load(xmlFile);  }else{  return null;  }  return xmlDoc;}
原创粉丝点击