使用XSLT转换XML2XML
在EDI(电子数据交换)系统中经常会遇到这样的事情,也就是在系统内定义的XML文档是一种格式,而外系统定义的则是另外的一种格式,或者是不同的外系统定义的格式不太一样,例如对于人员有些地方定义为<employee>,而其他的组织则使用<worker> 或者 <associate>.① 这个时候就需要一种XML转换成XML的格式了。
XSLT则就脱颖而出了,XSLT是XSL(EXtensible Stylesheet Language 扩展样式表语言)的一部分,专门负责XML转换成其他格式的一种语言。具体的学习可以参考网上的XSLT的资料。
如果你使用Java的话,很幸运,Java提供了一组API支持了XSLT的使用,可以不使用第三方的库就可以轻松的进行转换。进行转换只需要准备源文件(被转换的XML),转换的模板(XSLT文件),一段Java代码。
样例如下:
源文件:
<?xml version="1.0" encoding="UTF-8"?> <discussionForumHome> <messageBoard id="1" name="Java Programming"/> <messageBoard id="2" name="XML Programming"/> <messageBoard id="3" name="XSLT Questions"/> </discussionForumHome>
模板:
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="html"/> <!-- match the document root --> <xsl:template match="/"> <html> <head> <title>Discussion Forum Home Page</title> </head> <body> <h1>Discussion Forum Home Page</h1> <h3>Please select a message board to view:</h3> <ul> <xsl:apply-templates select="discussionForumHome/messageBoard"/> </ul> </body> </html> </xsl:template> <!-- match a <messageBoard> element --> <xsl:template match="messageBoard"> <li> <a href="viewForum?id={@id}"> <xsl:value-of select="@name"/> </a> </li> </xsl:template> </xsl:stylesheet>
Java代码
import java.io.File; import java.io.IOException; import java.net.URISyntaxException; import javax.xml.transform.Source; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; public class TestMain { public static void main(String[] args) throws IOException, URISyntaxException, TransformerException { TransformerFactory factory = TransformerFactory.newInstance(); Source xslt = new StreamSource(new File("D:\\dev\\learn\\discussionForumHome.xslt")); Transformer transformer = factory.newTransformer(xslt); Source text = new StreamSource(new File("D:\\dev\\learn\\discussionForumHome.xml")); transformer.transform(text, new StreamResult(new File("D:\\dev\\learn\\output.xml"))); } }
TIP 1.输出中文文件名有问题
如果你直接使用StreamResult进行文件输出时,会出现这样的现象,文件名变成%的ASCII格式,例如
transformer.transform(text, new StreamResult(new File( "D:\\dev\\learn\\小狗.xml")));
输出的文件名为:
%E5%B0%8F%E7%8B%97.xml
这个时候跟踪StreamResult的代码,发现 StreamResult在构造函数里面用文件的ASCII吗作为SystemID了。
setSystemId(f.toURI().toASCIIString());
这个时候可以通过设置OutputStream方式进行设置
StreamResult sr = new StreamResult(); sr.setOutputStream(new FileOutputStream(new File("D:\\dev\\learn\\小狗.xml"))); transformer.transform(text,sr);
注①。举例摘自《Java and XSLT》一书,同时XML文件内容也是如此