Java+XSL合并多个XML文件

使用 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)

时间: 2024-10-23 12:50:45

Java+XSL合并多个XML文件的相关文章

Java使用相对路径读取xml文件

java使用相对路径读取xml文件 博客分类: java javaXMLJavaWeb 一.xml文件一般的存放位置有三个: 1.放在WEB-INF下: 2.xml文件放在/WEB-INF/classes目录下或classpath的jar包中: 3.放在与解析它的java类同一个包中,不一定是classpath: 二.相对应的两种使用相对路径的读取方法: 方法一:(未验证) 将xml文件放在WEB-INF目录下,然后 程序代码: InputStream is=getServletContext(

java基础之概谈xml文件解析

XML已经成为一种很通用的数据交换格式,它的平台无关性,语言无关性,系统无关性,给数据集成与交互带来了极大的方便.诸多web应用框架,其可配置的编程方式,给我们的开发带来了很大程度的便捷,但细细想来,它们的应用无一不是java bean与xml之间的转换解析.本文将对xml的两种操作标准DOM和SAX,从它们各自的特点.适用范围等方面进行简单介绍. DOM (Document Object Model) :DOM标准中,采用W3C标准表示XML,有多重语言支持,因此其跨平台性很好.采用DOM规范

关于Java Web工程中web.xml文件

提及Java Web工程中web.xml文件无人不知,无人不识,呵呵呵:系统首页.servlet.filter.listener和设置session过期时限,张口就来,可是你见过该文件中的error-page标签吗?下面直接以例子的形式说明error-page标签的使用: 一个servlet文件: package com.ghj.packageofservlet; import java.io.IOException; import javax.servlet.ServletException;

JAVA中使用DOM解析XML文件

JAVA中使用DOM解析XML文件: 创建DocumentBuilderFactory的对象                                 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 创建DocumentBuilder对象 通过documentBuilder对象的parser方法加载xml文件到当前项目下 获取所有XML文件内节点的集合    getElementsByTagName()方

Delphi调用JAVA的WebService上传XML文件(XE10.2+WIN764)

相关资料:1.http://blog.csdn.net/luojianfeng/article/details/512198902.http://blog.csdn.net/avsuper/article/details/8764165 注意事项: 1.生成WSDL文件时,D7可能有的无法生成,用XE版本可以全部生成. 返回字节流: 1 function GetByte(AString: string): TByteDynArray; 2 var 3 sByte: TByteDynArray;

java代码用dom4j解析xml文件的简单操作

时间: 2016/02/17 目标:为telenor的ALU Femto接口写一个采集xml文件并解析出locationName标签里的值,然后更新到数据库中. 从网上搜了下,有四种常用的解析xml的方式,包括DOM,JAXD,Dom4J,SAX(simple api for xml).我正好有Dom4j的jar包,就选择了Dom4j来解析xml. 前半截对xml的解析测试成功了.后面的数据库的连接,把数据更新到数据库的操作没有测试.对应的xml文件的行数有点多,没法上传,另写一个xml的文档上

Java修炼之路——读取XML文件

这次来跟记录下java下如何操作xml文件.其实用过python去爬虫的话,那么应该很容易上手.java中有一个库dom4j就跟python中的lxml类似. 这里要重点强调下,在使用dom4j库的时候,其实它还有一个依赖包,就是jaxen.不添加的可是会报错的.(dom4j和jaxen的下载链接都整理好了在底部) 这里主要就是讲讲怎么用dom4j来读取的xml文件(可以直接从网络上加载,或者本地) //这个是官网上copy的,直接从加载文件 public class Foo { public

dom4j 简单实例,通过java代码读,写xml文件

项目会用到下面两个jar包 package com.xml.writer; import java.io.BufferedReader;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.FileReader;import java.io.InputStreamReader;imp

Java之Pull方式生成xml文件和解析xml文件

Pull XML解析器早已经被google集成到android sdk当中,它是google官方推荐的解析器. 如果我们要在Java桌面.J2ME等当中使用Pull方式生成xml文件和解析xml文件,需要用到kxml2: KXML解析器是基于普通XML PULL解析器的一个小巧的解析器,官网是http://kxml.org/ 普通XML PULL解析器的官网是http://xmlpull.org/ 实验开始: 在Eclipse中新建一个java项目,其中新建一个libs文件夹,拷贝从网上下载的k