码迷,mamicode.com
首页 > 编程语言 > 详细

Java+XSL合并多个XML文件

时间:2017-01-17 16:06:46      阅读:247      评论:0      收藏:0      [点我收藏+]

标签:pass   目标   out   介绍   取出   for   conf   create   dom   

使用 Java 解析 XML 文件有许多成熟的工具,如 dom4j 等等。但在一些场景中,我们可能使用 Ant、Maven 等构建工具对多个 XML 文件进行合并,我们希望可以直接通过脚本文件,或者简单的程序就能完成这样的功能,那么使用 XSL 是一个非常不错的选择。本文将介绍通过简单的 Java 程序加上 XSL 文件来完成多个 XML 文件的合并操作。(XSL 是一种样式表语言,可用以描述如何显示一个 XML 文件)

背景

  1. Config.xml 文件的结构与 FinalConfig.xml 文件相似;
  2. 需要将 Config.xml 文件的内容合并到 FinalConfig.xml 文件;
  3. 若 FinalConfig.xml 文件中已存在 Config.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)

Java+XSL合并多个XML文件

标签:pass   目标   out   介绍   取出   for   conf   create   dom   

原文地址:http://www.cnblogs.com/ethanzhong/p/6293444.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!