最近学了下XML以及在java中的XML编程,先加以小结。
说到XML,就不能不说下HTML,因为它们同属于SGML的简化子集。但是HTML由
于自身特点的限制,有了很多的局限性,而XML的语言的产生则解决了许多问题。
它的最大优点是它的数据存储格式不受显示格式的制约.一篇文档包括三个要素:
数据、结构和显示方式。XML把文档的三要素分开来处理。首先把显示格式从数据
内容中独立出来,保存在样式表文件(stylesheet)中,这样如果需要改变文档的
显示方式,只要修改样式表文件就行了。
下面是一个简单的XML例子:
<?xml version="1.0" encoding="UTF-8"?>
<publication>
<book>
<Title>The Mythical Man-month</Title>
<Wtiter>Frederick P.Brooks JR.</Wtiter>
<PublishDate>1975-03-12</PublishDate>
</book>
<book>
<Title>Think In Java</Title>
<Wtiter>Bruce Eckel</Wtiter>
<PublishDate>1999-04-01</PublishDate>
</book>
</publication>
一个规范的XML文件是从一个"XML申明"开始的,即:
<?xml version="1.0" standalone="no" encoding="UTF-8"?>
显而易见,第一个version是版本号,而后两个则是XML的属性,为可选项。
其中standalone是表明该文件是否有另外一个配套的DTD文件进行标记申明,
encoding则是编码标准,其中最常用的是GB2312,即国标码。
XML对于语法标记的规定和注释不用多说,下面来看看之前说到DTD(Document
Type Definition).DTD描述了一个标记语言的语法和词汇表,也就是定义了文件
的整体结构一级文件的语法。它可以嵌套在XML中,也可以通过外部的DTD的使用
。
对于嵌套在XML中的DTD,只要在申明后面加入DTD规范。基于上面的例子,它
的DTD如下:
<!DOCTYPE puclication[
<!ELEMENT publication(book)*>
<!ELEMENT book(Title,Writer,PublishDate)>
<!ELEMENT Title(#PCDATA)>
<!ELEMENT Writer(#PCDATA)>
<!ELEMENT PublishDate(#PCDATA)>
<!ATTLIST book hot(true|false) "false">
]>
当然,也可以把上面的写成一个bookstore.dtd的文件,它是XML文件,所以
开头应该加上声明.
现在,我们来分析一下上面的DTD文件。可以看出,DTD的一半声明是:
<ELEMENT elementname (elementtype modifiers)>
其中,我们看到第一个ELEMENT之后有一个*号,它的意思就是book这个标签
可以在publication中可以不出现或者出现多次。另外类似的,?表示不出现或出现
一次,+表示出现多次但至少出现一次,|表示出现两者间的一个...
了解了DTD,你会发现它存在着一些不足,比如你想针对特定元素施加数据类
型就会遇到麻烦,所以有出现了功能更强大的XML Schema,即通常所说的XSD(详
细内容请参照XSD简述)。中对于
下面我们开始正式进入java中的XML编程,java中对于XML的操作主要是读取
和修改。为此,我们分别写了读取和编辑的两段程序加以说明。
请先看UseDomEditElements:
package com.src.xml;
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class UseDomPrintElement {
/**
* @param args
*/
public static void main(String[] args) {
try {
//To get a parser for XML file
//获得一个XML文件的解析器
DocumentBuilderFactory factory=
DocumentBuilderFactory.newInstance();
//To parser the XML file to generate the DOM
interface for reading the DOM
//解析XML文件生成DOM文档的接口类,以便访问DOM
DocumentBuilder
documentBuilder=factory.newDocumentBuilder();
//Documnet 接口描述了对应于整个XML文件的文档树
Document document=documentBuilder.parse(new
File("publication.xml"));
//获得根元素的子节点列表
Element element=document.getDocumentElement();
NodeList nodeList=element.getChildNodes();
// NodeList
nodeList=document.getElementsByTagName("publication");
getElement(nodeList);
} catch (Exception e) {
e.printStackTrace();
}
}
private static void getElement(NodeList nodeList) {
Node cnode;
String string;
if(nodeList.getLength()==0){
return;
}
for (int i = 0; i < nodeList.getLength(); i++) {
cnode = nodeList.item(i);
if (cnode.getNodeType()==Node.ELEMENT_NODE) {
System.out.println(cnode.getNodeName
());
getElement(cnode.getChildNodes());
}
else if (cnode.getNodeType()==Node.TEXT_NODE) {
string=cnode.getNodeValue().trim();
if (string.length()>0) {
System.out.println(" "+string);
}
}
}
}
}
通过上面的程序可以看出,在对于XML文件进行操作时,需要定义一个解析器,即
javax.xml.parsers包里的DucumentBuilder,然后通过解析器paese一个xml文件
得到document,继而得到document里的element和node,可以看见在读取xml里的
node时,用到了递归调用,我想这在xml的操作中应该是常用的操作。
下面是程序用到的publication.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<publication>
<book>
<Title>The Mythical Man-month</Title>
<Wtiter>Frederick P.Brooks JR.</Wtiter>
<PublishDate>1975-03-12</PublishDate>
</book>
<book>
<Title>Think In Java</Title>
<Wtiter>Bruce Eckel</Wtiter>
<PublishDate>1999-04-01</PublishDate>
</book>
</publication>
对于xml文件的编辑操作,开始同样要创建一个xml的解析器,然后通过
document.getDocumentElement()获取root,然后在root上进一步获取各个节点操
作。不过要注意的是对于Element和node的创建仍然是基于document的:
Element book=document.createElement("book");
Text textMsg = document.createTextNode("Applied Crytography");
而element和node实际的添加是用appendChild这一方法来实现的。
最后需要通过Transformer来把document转化为xml文件,这里需要用DOMSource和
StreamResult。参考代码如下:
package com.src.xml;
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;
public class UseDomEditElements {
/**
* @param args
*/
public static void main(String[] args) {
try {
DocumentBuilderFactory
factory=DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document=builder.parse(new File
("Publication.xml"));
Element root=document.getDocumentElement();
Element book=document.createElement("book");
Element title=document.createElement("Title");
Text textMsg = document.createTextNode("Applied
Crytography");
title.appendChild(textMsg);
book.appendChild(title);
Element author=document.createElement("Author");
textMsg = document.createTextNode("Bruce Schneier");
author.appendChild(textMsg);
book.appendChild(author);
Element date=document.createElement("PublishDate");
textMsg = document.createTextNode("1994-02-23");
date.appendChild(textMsg);
book.appendChild(date);
root.appendChild(book);
TransformerFactory
dFactory=TransformerFactory.newInstance();
Transformer transformer=dFactory.newTransformer();
DOMSource source=new DOMSource(document);
StreamResult result=new StreamResult(new File
("Publication.xml"));
transformer.transform(source, result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
可以看到,上面的xml的解析方法是采用DOM来解析的,事实上XMl还有其他的解析
方式:SAX,JDOM一级DOM4J,下面仅以代码描述其他XML操作方式的基本使用方法
:
1.SAX:
package com.src.xml.sax;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class UseSAXXMLRead extends DefaultHandler {
java.util.Stack tags = new java.util.Stack();
public UseSAXXMLRead() {
super();
}
public static void main(String args[]) {
long lasting = System.currentTimeMillis();
try {
SAXParserFactory sf =
SAXParserFactory.newInstance();
SAXParser sp = sf.newSAXParser();
UseSAXXMLRead reader = new UseSAXXMLRead();
sp.parse(new InputSource("publication.xml"),
reader);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("runTime:" +
(System.currentTimeMillis() - lasting)
+ "ms");
}
public void characters(char ch[], int start, int length)
throws SAXException {
String tag = (String) tags.peek();
if (tag.equals("Title")) {
System.out.println("Title:" + new String(ch,
start, length));
}
if (tag.equals("Wtiter")) {
System.out.println("Wtiter:" + new String(ch,
start, length));
}
if (tag.equals("PublishDate")) {
System.out.println("PublishDate:" + new String
(ch, start, length));
}
if (tag.equals("book")) {
System.out.println("book:" + new String(ch,
start, length));
}
}
public void startElement(String uri, String localName, String
qName,
Attributes attrs) {
tags.push(qName);
System.out.println(qName+"_tag");
}
}
2.JDOM
package com.src.xml.jdom;
import java.io.File;
import java.util.List;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
public class UseJDOMXMLRead {
public static void main(String arge[]) {
long lasting = System.currentTimeMillis();
try {
SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(new File
("publication.xml"));
Element foo = doc.getRootElement();
List allChildren = foo.getChildren();
for (int i = 0; i < allChildren.size(); i++) {
System.out.println("Title:" +
((Element) allChildren.get(i)).getChild("Title").getText());
System.out.println("Wtiter:" +
((Element) allChildren.get(i)).getChild("Wtiter").getText());
System.out.println("PublishDate:" +
((Element) allChildren.get(i)).getChild("PublishDate").getText());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
3:DOM4J
package com.src.xml.dom4j;
import java.io.File;
import java.util.Iterator;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class UseDOM4JXMLRead {
public static void main(String arge[]) {
long lasting = System.currentTimeMillis();
try {
File f = new File("publication.xml");
SAXReader reader = new SAXReader();
Document doc = reader.read(f);
Element root = doc.getRootElement();
Element foo;
for (Iterator i = root.elementIterator("book");
i.hasNext();) {
foo = (Element) i.next();
System.out.println("Title:" +
foo.elementText("Title"));
System.out.println("Writer:" +
foo.elementText("Writer"));
System.out.println("PublishDate:" +
foo.elementText("PublishDate"));
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
代码都通过测试,很简单,在这就不多讲了,这里只是对XML在java中的编程做一
个简单的介绍,深入的研究留在下次吧。