使用 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 文件结构:

 <gameconfig>
<games>
<game>
<gameid>100</gameid>
<gamename>Fly to the Moon</gamename>
<gamedesc>This is Fly to the Moon</gamedesc>
</game>
<game>
<gameid>101</gameid>
<gamename>10 Miles</gamename>
<gamedesc>This is 10 Miles</gamedesc>
</game>
</games>
</gameconfig>

Config.xml 文件结构:

 <gameconfig>
<games>
<game>
<gameid>100</gameid>
<gamename>Fly to the Sun</gamename>
<gamedesc>This is Fly to the Sun</gamedesc>
</game>
</games>
</gameconfig>

我们假定 gameid 是固定值,不会变。在合并完成后,<gameid>为 100 的 node 被更新。希望得到新的 FinalConfig.xml 文件如下:

 <gameconfig>
<games>
<game>
<gameid>100</gameid>
<gamename>Fly to the Sun</gamename>
<gamedesc>This is Fly to the Sun</gamedesc>
</game>
<game>
<gameid>101</gameid>
<gamename>10 Miles</gamename>
<gamedesc>This is 10 Miles</gamedesc>
</game>
</games>
</gameconfig>

一、Java 调用程序

 private void mergeXml(File xslFile, File configXml, File finalConfigXml){
DocumentBuilderFactory dbFac = DocumentBuilderFactory.newInstance();
DocumentBuilder builder;
Document destDoc = null;
FileInputStream input;
try{
builder = dbFac.newDocumentBuilder();
destDoc = builder.parse(finalConfigXml);
if(!finalConfigXml.exists())
{
finalConfigXml.createNewFile();
}
input = new FileInputStream(xslFile);
StreamSource source = new StreamSource(input);
Transformer transformer = TransformerFactory.newInstance().newTransformer(source);
//为xsl文件设置变量"configXmlPath",将configXml文件的路径传递给xsl
transformer.setParameter("configXmlPath", configXml.getPath());
transformer.transform(new DOMSource(destDoc), new StreamResult(finalConfigXml));
}catch(Exception e) {
e.printStackTrace();
}
}

二、XSL 文件

 <?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xml" indent="yes"/> <!-- pass the Config.xml file's path from Java code -->
<xsl:param name="configXmlPath"/>
<xsl:variable name="configXml" select="document($configXmlPath)"/> <xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template> <xsl:template match="/gamedata">
<xsl:copy>
<xsl:apply-templates select="games" mode="updateGames"/>
</xsl:copy>
</xsl:template> <xsl:template match ="games" mode="updateGames">
<xsl:variable name="gamesStr">
<xsl:for-each select="$configXml/gamedata/games/game">
<xsl:choose>
<xsl:when test="gameid">
<xsl:value-of select="concat('-',current()/gameid)"/>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:variable>
<games>
<xsl:for-each select="game">
<xsl:if test="not(contains($gamesStr,gameid))">
<xsl:copy-of select="current()"/>
</xsl:if>
</xsl:for-each>
<xsl:apply-templates select="$configXml/gamedata/games/game" />
</games>
</xsl:template>
</xsl:stylesheet>

三、XSL 文件解析

1.Java 传入参数 “configXmlPath” 为 Config.xml 文件的路径

 <xsl:param name="configXmlPath"/> 

2.取出 Config.xml 文件中所有的 gameid,此处为增强处理,即 Config.xml 文件中可以存在多个 <game> 节点

 <xsl:variable  name="gamesStr">
<xsl:for-each select="$configXml/gamedata/games/game">
<xsl:choose>
<xsl:when test="gameid">
<xsl:value-of select="concat('-',current()/gameid)"/>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:variable>

3.判断 FinalConfig.xml 的 <games> 子节点中是否存在当前的 gameid ,若不存在则复制

 <xsl:for-each select="game">
<xsl:if test="not(contains($gamesStr,gameid))">
<xsl:copy-of select="current()"/>
</xsl:if>
</xsl:for-each>

4.复制 Config.xml 文件中的所有 <game> 节点

<xsl:apply-templates select="$configXml/gamedata/games/game" />

(本文系从原博客迁移至此,并进行部分编辑。原文链接:http://thewaychung.iteye.com/blog/2072740)

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

  1. JAVA中通过Jaxp操作XML文件基础

    Java中有多种方式操作XML文件,目前讲一讲以SUN公司提供的DocumentBuilderFactory工厂类对象操作XML. 使用XML基本操作就是需要CRUD(增删改查),那么首先通过一个查询 ...

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

    相关资料:1.http://blog.csdn.net/luojianfeng/article/details/512198902.http://blog.csdn.net/avsuper/artic ...

  3. 使用java代码动态配置与xml文件结合的方式使用mybatis-generator生成代码配置

    1.使用java代码动态配置与xml文件结合的方式使用mybatis-generator生成代码配置 2.上代码:在resources目录下新建:generatorConfiguration.xml文 ...

  4. JAVA中使用DOM解析XML文件

    XML是一种方便快捷高效的数据保存传输的格式,在JSON广泛使用之前,XML是服务器和客户端之间数据传输的主要方式.因此,需要使用各种方式,解析服务器传送过来的信息,以供使用者查看. JAVA作为一种 ...

  5. java中采用dom4j解析xml文件

    一.前言 在最近的开发中用到了dom4j来解析xml文件,以前听说过来解析xml文件的几种标准方式:但是从来的没有应用过来,所以可以在google中搜索dmo4j解析xml文件的方式,学习一下dom4 ...

  6. Spring MVC框架下在java代码中访问applicationContext.xml文件中配置的文件(可以用于读取配置文件内容)

    <bean id="propertyConfigurer" class="com.****.framework.core.SpringPropertiesUtil& ...

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

    时间: 2016/02/17 目标:为telenor的ALU Femto接口写一个采集xml文件并解析出locationName标签里的值,然后更新到数据库中. 从网上搜了下,有四种常用的解析xml的 ...

  8. java中利用dom4j解析XML文件

    官网下载Dom4j地址:https://dom4j.github.io/ 注意:使用Dom4j开发,需下载dom4j相应的jar文件 题目:后台利用dom4j解析student.xml文件,并返回Li ...

  9. java struts2入门学习--基于xml文件的声明式验证

    一.知识点总结 后台验证有两种实现方式: 1 手工验证顺序:validateXxx(针对Action中某个业务方法验证)--> validate(针对Action中所有的业务方法验证) 2 声明 ...

随机推荐

  1. PHP获取指定页面的指定内容

    在刚入手PHP的时候,经理让我自己做一个文章的管理系统为了方便管理微信端发的消息.除了简单的添加分类.管理分类.添加文章.管理文章,还有一个功能就是要从微信文章网址中拿到网址上的标题.作者以及发表时间 ...

  2. 基于ZKWeb + Angular 4.0的开源管理后台Demo

    这是一套基于ZKWeb网页框架和Angular 4.0编写的开源管理后台Demo,实现了前后端分离和模块化开发, 地址是: https://github.com/zkweb-framework/ZKW ...

  3. SSO单点登录的研究

    一.单点登录的概述       单点登录(Single Sign On),简称为 SSO,SSO的定义是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统. 用以解决同一公司不同子产 ...

  4. JAVA并发编程实战---第二章:线程安全性

    对象的状态是指存储在状态变量中的数据.对象的状态可能包括其他依赖对象的域.例如HashMap的状态不仅存储在HashMap本身,还存储在许多Map.Entry对象中.对象的状态中包含了任何可能影响其外 ...

  5. 建造者(Builder)模式

    建造者模式是对象的创建模式.建造模式可以将一个产品的内部表象(internal representation)与产品的生产过程分割开来,从而可以使一个建造过程生成具有不同的内部表象的产品对象. 产品的 ...

  6. zepto全选按钮之全选会根据按钮是否被全部选中更改状态

    在做手机端二次开发购物车的时候,发现zepto全选,没找到,或者功能不是自己想要的 后来做好,分享给需要的人 //全选或多选处理      var CheckAll = $('#items_check ...

  7. 学java网络编程的心得体会

    网络编程简单思路 一.发送端1创建udp服务,通过DatagramSocket对象;2确定数据,封装成包DatagramPacket(byte[] buf, int length, InetAddre ...

  8. Java 8 Learn Notes

    Main reference: [1] http://winterbe.com/posts/2014/03/16/java-8-tutorial/ [2] https://plus.google.co ...

  9. 学习笔记TF018:词向量、维基百科语料库训练词向量模型

    词向量嵌入需要高效率处理大规模文本语料库.word2vec.简单方式,词送入独热编码(one-hot encoding)学习系统,长度为词汇表长度的向量,词语对应位置元素为1,其余元素为0.向量维数很 ...

  10. JavaSE教程-03Java中分支语句与四种进制转换-练习

    练习1: 老师如果带100或以上则请客吃饭 import java.util.Scanner; public class Test2{ public static void main(String[] ...