标签:pass 目标 out 介绍 取出 for conf create dom
使用 Java 解析 XML 文件有许多成熟的工具,如 dom4j 等等。但在一些场景中,我们可能使用 Ant、Maven 等构建工具对多个 XML 文件进行合并,我们希望可以直接通过脚本文件,或者简单的程序就能完成这样的功能,那么使用 XSL 是一个非常不错的选择。本文将介绍通过简单的 Java 程序加上 XSL 文件来完成多个 XML 文件的合并操作。(XSL 是一种样式表语言,可用以描述如何显示一个 XML 文件)
背景:
目标:程序执行完成后,生成一个唯一的 XML 文件 FinalConfig.xml;
FinalConfig.xml 文件结构:
1 <gameconfig> 2 <games> 3 <game> 4 <gameid>100</gameid> 5 <gamename>Fly to the Moon</gamename> 6 <gamedesc>This is Fly to the Moon</gamedesc> 7 </game> 8 <game> 9 <gameid>101</gameid> 10 <gamename>10 Miles</gamename> 11 <gamedesc>This is 10 Miles</gamedesc> 12 </game> 13 </games> 14 </gameconfig>
Config.xml 文件结构:
1 <gameconfig> 2 <games> 3 <game> 4 <gameid>100</gameid> 5 <gamename>Fly to the Sun</gamename> 6 <gamedesc>This is Fly to the Sun</gamedesc> 7 </game> 8 </games> 9 </gameconfig>
我们假定 gameid 是固定值,不会变。在合并完成后,<gameid>为 100 的 node 被更新。希望得到新的 FinalConfig.xml 文件如下:
1 <gameconfig> 2 <games> 3 <game> 4 <gameid>100</gameid> 5 <gamename>Fly to the Sun</gamename> 6 <gamedesc>This is Fly to the Sun</gamedesc> 7 </game> 8 <game> 9 <gameid>101</gameid> 10 <gamename>10 Miles</gamename> 11 <gamedesc>This is 10 Miles</gamedesc> 12 </game> 13 </games> 14 </gameconfig>
一、Java 调用程序
1 private void mergeXml(File xslFile, File configXml, File finalConfigXml){ 2 DocumentBuilderFactory dbFac = DocumentBuilderFactory.newInstance(); 3 DocumentBuilder builder; 4 Document destDoc = null; 5 FileInputStream input; 6 try{ 7 builder = dbFac.newDocumentBuilder(); 8 destDoc = builder.parse(finalConfigXml); 9 if(!finalConfigXml.exists()) 10 { 11 finalConfigXml.createNewFile(); 12 } 13 input = new FileInputStream(xslFile); 14 StreamSource source = new StreamSource(input); 15 Transformer transformer = TransformerFactory.newInstance().newTransformer(source); 16 //为xsl文件设置变量"configXmlPath",将configXml文件的路径传递给xsl 17 transformer.setParameter("configXmlPath", configXml.getPath()); 18 transformer.transform(new DOMSource(destDoc), new StreamResult(finalConfigXml)); 19 }catch(Exception e) { 20 e.printStackTrace(); 21 } 22 }
二、XSL 文件
1 <?xml version="1.0" encoding="UTF-8"?> 2 <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 3 4 <xsl:output method="xml" indent="yes"/> 5 6 <!-- pass the Config.xml file‘s path from Java code --> 7 <xsl:param name="configXmlPath"/> 8 <xsl:variable name="configXml" select="document($configXmlPath)"/> 9 10 <xsl:template match="@* | node()"> 11 <xsl:copy> 12 <xsl:apply-templates select="@* | node()"/> 13 </xsl:copy> 14 </xsl:template> 15 16 <xsl:template match="/gamedata"> 17 <xsl:copy> 18 <xsl:apply-templates select="games" mode="updateGames"/> 19 </xsl:copy> 20 </xsl:template> 21 22 <xsl:template match ="games" mode="updateGames"> 23 <xsl:variable name="gamesStr"> 24 <xsl:for-each select="$configXml/gamedata/games/game"> 25 <xsl:choose> 26 <xsl:when test="gameid"> 27 <xsl:value-of select="concat(‘-‘,current()/gameid)"/> 28 </xsl:when> 29 </xsl:choose> 30 </xsl:for-each> 31 </xsl:variable> 32 <games> 33 <xsl:for-each select="game"> 34 <xsl:if test="not(contains($gamesStr,gameid))"> 35 <xsl:copy-of select="current()"/> 36 </xsl:if> 37 </xsl:for-each> 38 <xsl:apply-templates select="$configXml/gamedata/games/game" /> 39 </games> 40 </xsl:template> 41 </xsl:stylesheet>
三、XSL 文件解析
1.Java 传入参数 “configXmlPath” 为 Config.xml 文件的路径
1 <xsl:param name="configXmlPath"/>
2.取出 Config.xml 文件中所有的 gameid,此处为增强处理,即 Config.xml 文件中可以存在多个 <game> 节点
1 <xsl:variable name="gamesStr"> 2 <xsl:for-each select="$configXml/gamedata/games/game"> 3 <xsl:choose> 4 <xsl:when test="gameid"> 5 <xsl:value-of select="concat(‘-‘,current()/gameid)"/> 6 </xsl:when> 7 </xsl:choose> 8 </xsl:for-each> 9 </xsl:variable>
3.判断 FinalConfig.xml 的 <games> 子节点中是否存在当前的 gameid ,若不存在则复制
1 <xsl:for-each select="game"> 2 <xsl:if test="not(contains($gamesStr,gameid))"> 3 <xsl:copy-of select="current()"/> 4 </xsl:if> 5 </xsl:for-each>
4.复制 Config.xml 文件中的所有 <game> 节点
<xsl:apply-templates select="$configXml/gamedata/games/game" />
(本文系从原博客迁移至此,并进行部分编辑。原文链接:http://thewaychung.iteye.com/blog/2072740)
标签:pass 目标 out 介绍 取出 for conf create dom
原文地址:http://www.cnblogs.com/ethanzhong/p/6293444.html