作为W3C推出的拳头标准,XML的强大优势之一就是它可以方便的被转换成其他格式的XML或者其他不同类型的文件,如PDF、HTML等都是常见的XML转换的输出格式。
为了实现这个功能,我们需要利用到eXtensible Stylesheet Language for Transformations (XSLT)。XSL文件是这样一些样式表,它们指定如何从一个XML文件转换出其他的格式。这个是不是多少让你想起MFC的文档-视图结构或者MVC模式?
[XML学习笔记][2.4]XML作为消息传递载体
由于XML的平台和技术独立性,它经常被用来在不同的系统之间传递消息,基于XML这一特性而产生的常见的技术和规范包括:SOAP、Web Services、UDDI和WSDL。
SOAP的全称是Simple Object Access Protocol,它定义了一类XML如何创建、打包和传送,可以直接通过HTTP方式同步或异步的传递;Web Services在很大程度上依赖于SOAP;UDDI相当于在网上存储和共享Web Services的位置信息,供使用者在需要调用某个Web Service时查询;而WSDL是Web Services Dercription Language的缩写,用于在UDDI上描述Web服务。
[XML学习笔记][2.5]XML数据操作
XML的另一个重要的应用是数据操作。
就数据操作而言,一个基本的概念是XPath,XPath是一种语言,用于通过某种文本形式的途径表示XML文档中的元素或者另一个XML文档等等,基于XPath,我们才能够在XML中相对方便的引用到相关的内容,以致使用到XSLT这样的东东。
为什么会有这样的语言?因为在很多时候XML文档所代表的数据是相互关联的,而并非独立的一个一个元素和文档,XPath等语言使得很多高级的操作得以简单的完成。
[XML学习笔记][2.6]XML存储
XML文档只能以文本文件的形式存在吗?错。
常见的XML存储形式有:
- 文本文件
- 关系数据库
- 二进制文件
- XML数据库(这个是不是有点过分了,呵呵)
以文本形式储存XML数据当然在很多情况下是适用的,也是我们最常看到的XML存储方式,因为我们在J2EE中接触最多的就是XML的配置文件嘛,如果不是文本的,我们改起来是不是就有点别扭了?只不过文本的东西每次用的时候都需要做转换,影响到执行的效率罢了。所以通常我们在做项目时也会用一些自动化的工具将我们的XML在系统运行或调试前做一些转换。
这样看,我们还真的不能想当然了。
[XML学习笔记][3]在Java的世界中使用XML
在我们的日常Java编程中,需要处理XML通常是如下情形:
I- 从XML中读取和分析数据
II- 利用XLST将XML转换成其他格式
在接下来的笔记中,我们就分别来看看这两种工作如何通过JAXP来完成。
[XML学习笔记][3.1]通过JAXP使用SAX
在前面的笔记中,我们曾经提到读取XML数据的两种截然不同的方式,SAX就是其中一种。来看一段代码:
* Created on 2005-2-24
* All rights reserved.
*
*/
package sean.home.test;
import java.io.File;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
/**/ /**
* @author Sean GAO
* <p>
* gaoyuxiang@gmail.com
* </p>
*
*/
public class Main {
public static void main(String[] args) throws Exception {
SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();
DefaultHandler myHandler = new DefaultHandler() {
public void startDocument() throws SAXException {
System.out.println("XML document starts ");
}
public void endDocument() throws SAXException {
System.out.println("XML document ends ");
}
public void startElement(String uri, String localName,
String qualifiedName, Attributes attributes)
throws SAXException {
System.out.println("element " + qualifiedName + "starts ");
}
public void endElement(String uri, String localName,
String qualifiedName) throws SAXException {
System.out.println("element " + qualifiedName + "ends ");
}
public void characters(char[] ch, int start, int length) {
System.out.println(new String(ch, start, length));
}
};
parser.parse(new File(args[0]), myHandler);
}
}
在这段代码中,我们通过SAXParserFactory获取一个parser,然后自定义一个Handler去处理由SAX读取XML文件时触发的事件,如startDocument表示文档开始,endElement表示元素读取结束,characters表示在元素体内读到内容等等。这里我为了方便直接写成匿名内部类了,Exception也没有做任何处理,这在实际中通常是不合理的。
基本上SAX的实现和使用都很直截了当,就是处理一个个事件罢了。
DOM的调用方法看上去跟SAX也很类似:
* Created on 2005-2-24
* All rights reserved.
*
*/
package sean.home.test;
import java.io.File;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
/**/ /**
* @author Sean GAO
* <p>
* gaoyuxiang@gmail.com
* </p>
*
*/
public class DOMTest {
public static void main(String[] args) throws Exception {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document myDocument = builder.parse(new File(args[0]));
Node root = myDocument.getDocumentElement();
// 这时我们已经有一个完整的反映出所处理XML文档的树型结构,并取得了它的根节点
System.out.println(root.getNodeName());
//
}
}
在这里,我们取得了想要的DOM模型,之后我们就可以对它进行遍历或操作了。对于org.w3c.dom.Document类型的对象,我们可以调用如下常用的方法:
getDocumentElement()
getElementsByTagName(String)
getChildNodes()
getParentNode()
getFirstChild()
getLastChild()
getPreviousSibling()
获取到org.w3c.dom.Node对象后,我们可以:
getAttributes()
getNodeName()
getNodeType()
getNodeValue()
getNamespaceURI()
hasAttributes()
hasChildNodes()
这些方法从名称就知道是干什么的了,对吧?我就不多解释了。
最后我们来看看如何通过JAXP调用XSLT,同样很简单:
* Created on 2005-2-24
* All rights reserved.
*
*/
package sean.home.test;
import java.io.File;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
/**/ /**
* @author Sean GAO
* <p>
* gaoyuxiang@gmail.com
* </p>
*
*/
public class XSLTest {
public static void main(String[] args) throws Exception {
TransformerFactory factory = TransformerFactory.newInstance();
Source xmlSource = new StreamSource(new File(args[0]));
Source xlsSource = new StreamSource(new File(args[1]));
Transformer transformer = factory.newTransformer(xlsSource);
transformer.transform(xmlSource, new StreamResult(new File(args[3])));
}
}
是不是也跟SAX、DOM的接口很像?也是通过工厂方法获取一个Transformer实例然后提供输入和输出的文件路径,用它来transform即可。
至此我的XML学习笔记就截止了,大家也看到,这些都是十分基础的内容,然而我们平时很少去关心它。我的初衷是在做了N久的J2EE后回过头来温习一下XML的基本概念和用法,并不要求自己太深入,目的也达到了。具体的语法细节我想大家可以参考W3C和SUN官网上的资料和JavaDoc。
希望能当作XML的Java版快速入门来看,这些都是我们做Java的需要了解的最基本的XML常识,了解这些以后对一般的XML处理工作也基本上够了。
谢谢大家!祝大家天天开心,日日上进!:)