我的xml文章 

 xml转换: xml/map转换器

 xml合并: xml合并

dupliate()方法思路图:

左报文为:
<PACKET>
<HEAD>
<REQUEST_TYPE>type1</REQUEST_TYPE>
<ERROR_CODE>0001</ERROR_CODE>
<ERROR_MESSAGE>message01</ERROR_MESSAGE> </HEAD>
<BODY>
<BOOK_LIST>
<BOOK>
<NAME>abc</NAME>
<PRICE>12.3</PRICE>
</BOOK>
<BOOK>
<NAME>same</NAME>
<PRICE>4</PRICE>
</BOOK>
</BOOK_LIST>
<VHL>
<A>1</A>
<B>3</B>
<C>4</C>
<D></D>
</VHL> </BODY>
</PACKET>
右报文为:
<PACKET>
<HEAD>
<REQUEST_TYPE>type2</REQUEST_TYPE>
<ERROR_CODE>0002</ERROR_CODE>
<ERROR_MESSAGE>message02</ERROR_MESSAGE> </HEAD>
<BODY>
<BOOK_LIST>
<BOOK>
<NAME>YUI</NAME>
<PRICE>12.3</PRICE>
</BOOK>
<BOOK>
<NAME>OIY</NAME>
<PRICE>4</PRICE>
</BOOK>
</BOOK_LIST>
<VHL>
<A>89</A>
<B>39</B>
<C></C>
<D>have</D>
<E>00</E>
</VHL> </BODY>
</PACKET>
最终效果为:
<?xml version="1.0" encoding="UTF-8"?>
<PACKET>
<HEAD>
<REQUEST_TYPE>type1|type2</REQUEST_TYPE>
<ERROR_CODE>0001</ERROR_CODE>
<ERROR_MESSAGE>message01</ERROR_MESSAGE> </HEAD>
<BODY>
<BOOK_LIST>
<BOOK>
<NAME>abc</NAME>
<PRICE>12.3</PRICE>
</BOOK>
<BOOK>
<NAME>same</NAME>
<PRICE>4</PRICE>
</BOOK>
<BOOK>
<NAME>YUI</NAME>
<PRICE>12.3</PRICE>
</BOOK>
<BOOK>
<NAME>OIY</NAME>
<PRICE>4</PRICE>
</BOOK>
</BOOK_LIST>
<VHL>
<A>1</A>
<B>3</B>
<C>4</C>
<D>have</D>
<E>00</E>
</VHL> </BODY>
</PACKET>
同事文亮大师代码,非常棒,值得借鉴.抽空再找个时间来分析.(mark)
package d;

import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Date;
import java.util.HashMap;
import java.util.Map; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult; import org.apache.commons.lang.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource; //******************************************************************
/**
* 类名:com.testdemo.pcis.common.utils.XMLMergeUtils
*
* <pre>
* 描述: xml文件内容合并
* 基本思路:
* public方法:
* 特别说明:
* 编写者:wlsun
* Email:wlsun@isoftstone.com
* 版权: Copyright (C) 2017 软通动力版权所有
* 创建时间:2017年2月23日 下午9:58:09
* 修改说明: 类的修改说明
* </pre>
*/
// *****************************************************************
public class XMLMergeUtils { /**
* ******************************************************************
* XML文件的合并处理,不做任何处理,直接合并 <br><pre>
* 方法xmlMerging2Str的详细说明 <br>
* 编写者:wlsun
* Email:wlsun@isoftstone.com
* 创建时间:2017年2月25日 下午3:45:40 </pre>
* @param mainXml 待合并处理的xml文件,合并后将更新此文件
* @param subXml 被合并的xml文件
* @return 合并成功返回合并版本,否则返回未合并报文第一个参数
* @throws Exception
*******************************************************************
*/
public static String xmlMerging2Str(String mainXml, String subXml) throws Exception {
return xmlMerging2Str(mainXml, subXml, new HashMap(), new HashMap());
} //******************************************************************
/**
* XML文件的合并处理 <br><pre>
* 方法xmlMerging2Str的详细说明 <br>
* 编写者:wlsun
* Email:wlsun@isoftstone.com
* 创建时间:2017年2月23日 下午10:38:37 </pre>
* @param mainXml 待合并处理的xml文件,合并后将更新此文件
* @param subXml 被合并的xml文件
* @param Map<String, String> dupliateNodes 合并节点不替换集合
* 当前节点相同需要合并 如<COVERAGE_LIST> 中的 <COVERAGE>需要合并
* @param Map<String, String> dupliateTexts 合并节点内容替换集合
* 当前节点相同不合并节点,合并指定节点内容处理如<HEAD> 中的<REQUEST_TYPE>
* @return 合并成功返回合并版本,否则返回未合并报文第一个参数
* @throws Exception
*/
//*****************************************************************
public static String xmlMerging2Str(String mainXml, String subXml,
Map<String, String> dupliateNodes, Map<String, String> dupliateTexts) throws Exception {
if(dupliateNodes == null) dupliateNodes = new HashMap<String, String>();
if(dupliateTexts == null) dupliateTexts = new HashMap<String, String>(); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = null;
try {
db = dbf.newDocumentBuilder();
} catch (ParserConfigurationException e) {
e.printStackTrace();
System.err.println(e); // 出现异常时,输出异常信息
}
Document doc_main = null;
Document doc_vice = null;
// 获取两个XML文件的Document
try {
doc_main = db.parse(new InputSource(new StringReader(mainXml)));
doc_vice = db.parse(new InputSource(new StringReader(subXml)));
} catch (Exception e) {
e.printStackTrace();
System.err.println(e);
} // 获取两个文件的根节点
Element root_main = (Element) doc_main.getDocumentElement();
Element root_vice = (Element) doc_vice.getDocumentElement();
// 下面添加被合并文件根节点下的每个节点
NodeList messageItems = root_vice.getChildNodes();
int item_number = messageItems.getLength();
// 如果去掉根节点下的第一个节点,那么i从item_number开始,否则i从1开始
for (int i = 1; i < item_number; i = i + 2) {
// 调用dupliate(),依次复制被合并XML文档中根节点下的节点
Element messageItem = (Element) messageItems.item(i);
dupliate(doc_main, root_main, messageItem, dupliateNodes, dupliateTexts);
}
String result = outResultString(doc_main);
return result;
} /**
* ******************************************************************
* Document 转换为xml字符串内容<br><pre>
* 方法outResultString的详细说明 <br>
* 编写者:wlsun
* Email:wlsun@isoftstone.com
* 创建时间:2017年2月23日 下午10:38:37 </pre>
* @param Document doc_main
* @return String 说明
* @throws 异常类型 说明
*******************************************************************
*/
private static String outResultString(Document doc_main) throws TransformerFactoryConfigurationError, IOException {
// 创建输出(目标) 创建输出流 创建输出格式
StringWriter strWtr = new StringWriter();
StreamResult strResult = new StreamResult(strWtr);
TransformerFactory tfac = TransformerFactory.newInstance();
String result = "";
try {
javax.xml.transform.Transformer t = tfac.newTransformer();
// 设置xml的输出编码和是否去掉头文件
t.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
t.setOutputProperty(OutputKeys.INDENT, "yes");
t.setOutputProperty(OutputKeys.METHOD, "xml"); // xml, html, text
t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
t.transform(new DOMSource(doc_main.getDocumentElement()), strResult);
// 输出格式化的串到目标中,执行后。
result = strResult.getWriter().toString();
} catch (Exception e) {
e.printStackTrace();
System.err.println("DocumentToXmlString error:" + e);
} finally {
if(strWtr != null) strWtr.close();
}
return result;
} //******************************************************************
/**
* 合并节点 <br><pre>
* 方法dupliate的详细说明 <br>
* 编写者:wlsun
* Email:wlsun@isoftstone.com
* 创建时间:2017年2月23日 下午10:19:39 </pre>
* @param Map<String, String> dupliateNodes 需合并节点不替换集合
* @param Map<String, String> dupliateTexts 需合并节点内容替换集合
* @return boolean 说明
* @throws Exception
*/
//*****************************************************************
private static boolean dupliate(Document doc_dup, Element father, Element son,
Map<String, String> dupliateNodes, Map<String, String> dupliateTexts) throws Exception {
boolean isdone = false;
Element parentElement = null; CopyChildElementObject childElementObject = isChildElement(father, son, dupliateNodes, dupliateTexts);
if (!childElementObject.isNeedCopy()) {
// 节点相同不用合并
isdone = true;
parentElement = childElementObject.getElement();
} else if (childElementObject.getElement() != null) {
parentElement = childElementObject.getElement();
} else {
parentElement = father;
} String son_name = son.getNodeName();
Element subITEM = null;
if (!isdone) {
subITEM = doc_dup.createElement(son_name);
//判断是否存在子节点,存在则不取节点文本,否则取文本节点
NodeList sub_messageItems = son.getChildNodes();
int sub_item_number = sub_messageItems.getLength();
if (sub_item_number < 2) {
subITEM.appendChild(doc_dup.createTextNode(son.getTextContent()));
} // 复制节点的属性
if (son.hasAttributes()) {
NamedNodeMap attributes = son.getAttributes();
for (int i = 0; i < attributes.getLength(); i++) {
String attribute_name = attributes.item(i).getNodeName();
String attribute_value = attributes.item(i).getNodeValue();
subITEM.setAttribute(attribute_name, attribute_value);
}
}
parentElement.appendChild(subITEM);
} else {
subITEM = parentElement;
}
// 复制子结点
NodeList sub_messageItems = son.getChildNodes();
int sub_item_number = sub_messageItems.getLength();
if (sub_item_number < 2) {
// 如果没有子节点,则返回
isdone = true;
} else {
for (int j = 1; j < sub_item_number; j = j + 2) {
// 如果有子节点,则递归调用本方法
Element sub_messageItem = (Element) sub_messageItems.item(j);
isdone = dupliate(doc_dup, subITEM, sub_messageItem, dupliateNodes, dupliateTexts);
}
}
return isdone;
} //******************************************************************
/**
* 判断是否存在子节点 <br><pre>
* 方法isChildElement的详细说明 <br>
* 编写者:wlsun
* Email:wlsun@isoftstone.com
* 创建时间:2017年2月23日 下午10:20:12 </pre>
* @param Element father
* @param Element son
* @param Map<String, String> dupliateNodes 需合并节点不替换集合
* @param Map<String, String> dupliateTexts 需合并节点内容替换集合
* @return CopyChildElementObject 说明
* @throws 异常类型 说明
*/
//*****************************************************************
private static CopyChildElementObject isChildElement(Element father, Element son,
Map<String, String> dupliateNodes, Map<String, String> dupliateTexts) {
CopyChildElementObject childElementObject = new CopyChildElementObject(); NodeList messageItems = father.getChildNodes();
int item_number = messageItems.getLength();
// 首先遍历所有节点,查找是否有完全相同的节点,防止同一节点已定义多次
for (int i = 1; i < item_number; i = i + 2) {
Element messageItem = (Element) messageItems.item(i);
if (!messageItem.getNodeName().equals(son.getNodeName())) {
continue;
}
if (messageItem.isEqualNode(son)) {// 同时判断子节点是否一致
childElementObject.setNeedCopy(false);
childElementObject.setElement(messageItem);
return childElementObject;
}
}
for (int i = 1; i < item_number; i = i + 2) {
Element messageItem = (Element) messageItems.item(i);
// 判断节点是否处于同一级别
String msgItemNodeName = messageItem.getNodeName();
if (!msgItemNodeName.equals(son.getNodeName())) {
continue;
}
if (isEqualNode(messageItem, son)) {// 仅判断当前节点是否一致
if (hasEqualAttributes(messageItem, son)
&& !msgItemNodeName.equalsIgnoreCase(dupliateNodes.get(msgItemNodeName))) {
// 1、当前节点完全相同不需要合并
// 2、当前节点相同需要合并 如<COVERAGE_LIST> 中的 <COVERAGE>需要合并
// 3、当前节点相同不合并节点,合并指定节点内容处理如<HEAD> 中的<REQUEST_TYPE>
String keyName = messageItem.getParentNode().getNodeName() + "/" + msgItemNodeName;
if(keyName.equals(dupliateTexts.get(keyName))) {
messageItem.setTextContent(messageItem.getTextContent() + "|" + son.getTextContent());
} else {
//4、当前节点相同,报文一节点不存在内容,报文二节点存在内容,已存在内容的替换
if("".equals(messageItem.getTextContent())
&& !"".equals(son.getTextContent())) {
messageItem.setTextContent(son.getTextContent());
}
}
childElementObject.setNeedCopy(false);
childElementObject.setElement(messageItem);
return childElementObject;
} else {// 当前节点的属性不相同,需要合并
childElementObject.setNeedCopy(true);
childElementObject.setElement(father);
return childElementObject;
}
}
}
// 目标文档该节点不存在,需要合并到目标文档中
childElementObject.setNeedCopy(true);
childElementObject.setElement(father);
return childElementObject;
} //******************************************************************
/**
* 判断两个节点是否相同,未判断节点的属性<br><pre>
* 方法isEqualNode的详细说明 <br>
* 编写者:wlsun
* Email:wlsun@isoftstone.com
* 创建时间:2017年2月23日 下午10:20:35 </pre>
* @param 参数类型 参数名 说明
* @return boolean 说明
*/
//******************************************************************
private static boolean isEqualNode(Node arg0, Node arg) {
if (arg == arg0) {
return true;
}
if (arg.getNodeType() != arg0.getNodeType()) {
return false;
} if (arg0.getNodeName() == null) {
if (arg.getNodeName() != null) {
return false;
}
} else if (!arg0.getNodeName().equals(arg.getNodeName())) {
return false;
} if (arg0.getLocalName() == null) {
if (arg.getLocalName() != null) {
return false;
}
} else if (!arg0.getLocalName().equals(arg.getLocalName())) {
return false;
} if (arg0.getNamespaceURI() == null) {
if (arg.getNamespaceURI() != null) {
return false;
}
} else if (!arg0.getNamespaceURI().equals(arg.getNamespaceURI())) {
return false;
} if (arg0.getPrefix() == null) {
if (arg.getPrefix() != null) {
return false;
}
} else if (!arg0.getPrefix().equals(arg.getPrefix())) {
return false;
} if (arg0.getNodeValue() == null) {
if (arg.getNodeValue() != null) {
return false;
}
} else if (!arg0.getNodeValue().equals(arg.getNodeValue())) {
return false;
}
return true;
} //******************************************************************
/**
* 判断节点的属性是否相同<br><pre>
* 方法hasEqualAttributes的详细说明 <br>
* 编写者:wlsun
* Email:wlsun@isoftstone.com
* 创建时间:2017年2月23日 下午10:22:29 </pre>
* @param 参数类型 参数名 说明
* @return boolean 说明
* @throws 异常类型 说明
*/
//*****************************************************************
private static boolean hasEqualAttributes(Node arg0, Node arg) {
NamedNodeMap map1 = arg0.getAttributes();
NamedNodeMap map2 = arg.getAttributes();
int len = map1.getLength();
if (len != map2.getLength()) {
return false;
} for (int i = 0; i < len; i++) {
Node n1 = map1.item(i);
if (n1.getNodeName() != null) {
Node n2 = map2.getNamedItem(n1.getNodeName());
if (n2 == null) {
return false;
} else if (!n1.getNodeValue().equals(n2.getNodeValue())) {
return false;
}
}
}
return true;
} public static void main(String[] args) {
try { FileHelper fileHelper = new FileHelper();
String sourcefile = "src/d/file1.xml";
String main = fileHelper.readTxt(sourcefile, "UTF-8");
String targetfile = "src/d/file2.xml";
String sub = fileHelper.readTxt(targetfile, "UTF-8"); long start = new Date().getTime();
Map<String, String> dupliateNodes = new HashMap<String, String>();
dupliateNodes.put("COVERAGE", "COVERAGE"); Map<String, String> dupliateTexts = new HashMap<String, String>();
dupliateTexts.put("HEAD/REQUEST_TYPE", "HEAD/REQUEST_TYPE"); String mergStr = XMLMergeUtils.xmlMerging2Str(main, sub, dupliateNodes, dupliateTexts);
long end = new Date().getTime();
System.out.println(mergStr);
System.out.println((end-start));
} catch (Exception e) {
e.printStackTrace();
}
}
} //******************************************************************
/**
* 类名:com.isoftstone.pcis.common.utils.CopyChildElementObject <pre>
* 描述: 复制子节点对象, 记录该节点是否需要复制, 记录该节点的父节点
* 基本思路:
* public方法:
* 特别说明:
* 编写者:wlsun
* Email:wlsun@isoftstone.com
* 版权: Copyright (C) 2017 软通动力版权所有
* 创建时间:2017年2月23日 下午10:39:45
* 修改说明: 类的修改说明
* </pre>
*/
//*****************************************************************
class CopyChildElementObject {
private boolean needCopy = true;// 记录该节点是否需要复制
private Element element = null;// 记录该节点的父节点 public CopyChildElementObject() {
super();
} public boolean isNeedCopy() {
return needCopy;
} public void setNeedCopy(boolean needCopy) {
this.needCopy = needCopy;
} public Element getElement() {
return element;
} public void setElement(Element element) {
this.element = element;
}
}

xml合并工具【原】的更多相关文章

  1. 高通AR和友盟SDK的AndroidManifest.xml合并

    高通AR和友盟SDK的AndroidManifest.xml合并 因为高通的AR在android中一开始就要启动,所有主Activity要设置为高通的Activity,即android:name=&q ...

  2. CSS 和 JS 文件合并工具

    写 CSS 和 JavaScript 的时候, 我们会遇到一个两难的局面: 要么将代码写在一个大文件, 要么将代码分成多个文件. 前者导致文件难以管理, 代码复用性差, 后者则因为需要在载入多个文件令 ...

  3. Java XML解析工具 dom4j介绍及使用实例

    Java XML解析工具 dom4j介绍及使用实例 dom4j介绍 dom4j的项目地址:http://sourceforge.net/projects/dom4j/?source=directory ...

  4. svn的差异查看器和合并工具换成BCompare.exe

    svn的差异查看器和合并工具换成BCompare.exe

  5. Mergely – 免费的在线文档对比和合并工具

    任何类型的文件(无论是否代码),我们可能要比较不同的版本,看发生了什么变化. 有些编辑器都有这个内置功能,其中一些则没有. Mergely 是一个免费使用的 Web 应用程序,帮你你迅速作出文档的差异 ...

  6. Vimdiff---VIM的比较和合并工具

    本文来自IBMDW   http://www.ibm.com/developerworks/cn/linux/l-vimdiff/ 源程序文件(通常是纯文本文件)比较和合并工具一直是软件开发过程中比较 ...

  7. C# 版dll 程序集合并工具

    C# 版dll 程序集合并工具 最近要开发一个控件给同事用,开发中会引用一些第三方DLL,这样交给用户很不方便,希望的效果是直接交付一个DLL文件.网上找了一些资料. 1.       使用 Cost ...

  8. CSS Sprite小图片自动合并工具

    css-sprite是将css样式中零星的小图标,小图片合并成大图显示,这样能减小服务器并发连接数,减小服务器负载和带宽使用,有很高的实用价值.这里介绍一些自动合并图片并生成样式的工具. NodeJS ...

  9. 文件合并工具DiffMerge发布4.2版本

    DiffMerge一直是文件对比合并工具的佼佼者,其最大特点是多文件对比与合并,并提供可视化界面用于编辑. 此次DiffMerge v4.2发布,提高了文件差异对比,并提供了快速匹配功能,以及更好的用 ...

随机推荐

  1. PAT L3-008 喊山

    https://pintia.cn/problem-sets/994805046380707840/problems/994805050709229568 喊山,是人双手围在嘴边成喇叭状,对着远方高山 ...

  2. Array与Object

    typeof([ ])的返回值是object,因为数组叫做数组对象. Array有length属性,而Object没有length属性,所以可以根据length属性来判断数据属于数组还是对象. Arr ...

  3. [转帖]git命令参考手册

                      git init                                                  # 初始化本地git仓库(创建新仓库) git ...

  4. reshape、shuffle、save_weights

    #-*- coding: utf-8 -*- import pandas as pd from random import shuffle import matplotlib.pyplot as pl ...

  5. CnPack实用功能推荐

    已经使用CnPack好几年了,这个插件太好了,现在离开它我都不会写代码了,现在将使用心得与大家分享一下: 1.代码助手非常好用,只需要输入几个字符后,自动出现提示列表,真是懒人的福音呀. 2.代码高亮 ...

  6. ERP开源框架 + 二次开发平台 介绍

    经历了多年软件开发,深受网络大侠们的资源共享才得以有所成绩, 本人主要是做企业ERP软件,一直有个感受,开发具体某个功能不难,但随着需求的增加,管理庞大的代码却成了最大的问题 而为企业管理所做的开发, ...

  7. 【题解】ID分配

    题目描述 您正在处理要为每个客户端分配唯一ID的特定系统的后端.但是,系统是分布式的,并且有许多组件,每个组件都必须能够为客户端分配ID.换句话说,您希望每个组件都使用尽可能少的组件之间的通信来分配I ...

  8. 日志收集-Elk6

    一:前言 ELK是三个开源软件的缩写,分别表示:Elasticsearch , Logstash, Kibana , 它们都是开源软件.新增了一个FileBeat,它是一个轻量级的日志收集处理工具(A ...

  9. SQL注入方法之:获取列名

    select col_name(object_id('table'),1) from sysobjects where name='table'

  10. Educational Codeforces Round 4 B. HDD is Outdated Technology

    题目链接:http://codeforces.com/problemset/problem/612/B 解题思路: 一开始看错了题意,他要求的是从1-n所耗费的时间,n表示的是数值而不是下标, 实现代 ...