我的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;
}
}

最新文章

  1. 模拟赛1031d1
  2. 关于STM8的用户数据空间读写问题
  3. HDOJ 1870
  4. Google十大惊人产品
  5. QT5.4关联VS2010,配置VAssistX关联Qt类
  6. ios 加载本地html css文件 ps:css和html必须在同一文件夹下面
  7. STL源码剖析—stl_config
  8. ArcGIS for WPF 访问外部资源
  9. Javascript获取浏览器版本
  10. 用上Google才是正事 分享几个訪问Google的IP和域名
  11. flex4 list 自动适应高度
  12. win2008 401 - 未授权: 由于凭据无效,访问被拒绝。解决方法
  13. 2017-10-27模拟赛2-T1 选举(election.*)
  14. 【原创】控制perl和python脚本执行过程中脚本文件是否关闭的方法
  15. .NET Core中使用IHostedService结合队列执行定时任务
  16. [BZOJ 4671]异或图
  17. jquery-- json字符串没有自动包装为 json对象
  18. python 小练习 6
  19. Java ssl认证记录
  20. win7下设置环境变量

热门文章

  1. 让 VAGRANT 启动并运行起来
  2. OA与BPM的区别
  3. git worktree 是什么及其使用场景
  4. 函数 for 循环有return 返回是0的原因
  5. Ubuntu 16.04安装Maven
  6. HTML-XML数据解析
  7. ROADS POJ - 1724(分层最短路)
  8. android第二课:运行你的应用
  9. [luogu3834]静态区间第k小【主席树】
  10. Powershell script to install Windows Updates (msu) from folder