版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/chaoyu168/article/details/70227837
方法一:Dom4J处理XML
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
* 合并并输出2个xml文档,所需要jar:dom4j-1.6.1.jar,jaxen-1.1.1.jar
* 将某个xml文档的某个标签下或该标签上一级下所有内容插入到另一个xml文档的某个标签下
* @date 2011-04-13
* @author RobotJi
* @version 1.0
public class UniteXML {
public UniteXML() {}
* 根据is获取doc,这里的is可以是本地流或者网络流
* @param is
* @return
public static Document getDocument(InputStream is){
Document doc=null;
try {
doc=new SAXReader().read(is);
} catch (DocumentException e) {
e.printStackTrace();
}
return doc;
}
public static InputStream getInputStream(String path){
File f=new File(path);
if(!f.exists()){
return null;
}
InputStream is=null;
try {
is = new FileInputStream(f);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return is;
}
* 获取子Element
* @param doc 要获取的文档
* @param tagName 文档对应的标签
* @return
public Element getSubElement(Document doc,String tagName){
Element el=(Element)doc.selectSingleNode("//"+tagName);
return el;
}
* 输出xml文档
* @param doc 要输出的文档
* @param fileName 路径
public void writeXML(Document doc,String fileName){
try {
XMLWriter writer=new XMLWriter(new FileWriter(fileName));
writer.write(doc);
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
* 合并doc
* @param path1 主文档
* @param path2 被合并的文档
* @param tagName1 在主文档中要插入的标签
* @param tagName2 被合并文档的标签
* @param isContain 是否包含被合并文档标签的上一级标签下的所有结点
* @return
public Document unitXMl(String path1,String path2,String tagName1,String tagName2,boolean isContain){
Document doc1=getDocument(getInputStream(path1));
Document doc2=getDocument(getInputStream(path2));
Element elSub2=getSubElement(doc2,tagName2);
Element elSub1=getSubElement(doc1,tagName1);
if(isContain){
// doc1.getRootElement().appendContent(elSub2.getParent());//直接插入的根标签下
elSub1.appendContent(elSub2.getParent());//插入到tagName1标签下
}else{
// doc1.getRootElement().appendContent(elSub2);
elSub1.appendContent(elSub2);
}
return doc1;
}
public static void main(String[] args) {
UniteXML ux=new UniteXML();
//将c标签下所有内容插入到aa标签下,若参数设为true则可将c标签上一级下的所有内容插入到aa标签下
Document doc=ux.unitXMl("F:\\test\\a.xml", "F:\\test\\b.xml", "aa", "c", false);
ux.writeXML(doc, "F:\\test\\a_test.xml");
}
}
//测试用的2个xml如下:
a.xml
方法二:
import java.io. *; //Java基础包,包含各种IO操作
import java.util. *; //Java基础包,包含各种标准数据结构操作
import javax.xml.parsers. *; //XML解析器接口
import org.w3c.dom. *; //XML的DOM实现
import javax.xml.transform. *;
import javax.xml.transform.dom. *;
import javax.xml.transform.stream. *;
/**
* XML文件合并工具类
* @author GhostFromHeaven
*/
public class XMLMergeUtil {
/**
* XML文件的合并处理
* @param mainFileName 待合并处理的xml文件,合并后将更新此文件
* @param subFilename 被合并的xml文件
* @return 合并成功返回true,否则返回false
* @throws Exception
*/
public static boolean isMerging(String mainFileName, String subFilename)
throws Exception {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = null;
try {
db = dbf.newDocumentBuilder();
} catch (ParserConfigurationException pce) {
System.err.println(pce); // 出现异常时,输出异常信息
}
Document doc_main = null;
Document doc_vice = null;
// 获取两个XML文件的Document
try {
doc_main = db.parse(mainFileName);
doc_vice = db.parse(subFilename);
} catch (DOMException dom) {
System.err.println(dom.getMessage());
} catch (Exception ioe) {
System.err.println(ioe);
}
// 获取两个文件的根节点
Element root_main = doc_main.getDocumentElement();
Element root_vice = doc_vice.getDocumentElement();
// 下面添加被合并文件根节点下的每个节点
NodeList messageItems = root_vice.getChildNodes();
int item_number = messageItems.getLength();
// 如果去掉根节点下的第一个节点,那么i从3开始,否则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);
}
// 调用 write To(),将合并得到的Document写入目标XML文档
boolean isWritten = writeTo(doc_main, mainFileName);
return isWritten;
}
/**
*
* @param doc_dup
* @param father
* @param son
* @return
* @throws Exception
*/
private static boolean dupliate(Document doc_dup, Element father, Element son)
throws Exception {
boolean isdone = false;
Element parentElement = null;
DuplicateChildElementObject childElementObject = isChildElement(father, son);
if(!childElementObject.isNeedDuplicate()){
//节点相同不用合并
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);
// 复制节点的属性
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);
}
}
return isdone;
}
private static boolean writeTo(Document doc, String fileName) throws Exception {
boolean isOver = false;
DOMSource doms = new DOMSource(doc);
File f = new File(fileName);
StreamResult sr = new StreamResult(f);
try {
TransformerFactory tf = TransformerFactory.newInstance();
Transformer t = tf.newTransformer();
Properties properties = t.getOutputProperties();
properties.setProperty(OutputKeys.ENCODING, "UTF-8");
t.setOutputProperties(properties);
t.transform(doms, sr);
isOver = true;
} catch (TransformerConfigurationException tce) {
tce.printStackTrace();
} catch (TransformerException te) {
te.printStackTrace();
}
return isOver;
}
private static DuplicateChildElementObject isChildElement(Element father, Element son){
DuplicateChildElementObject childElementObject = new DuplicateChildElementObject();
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.setNeedDuplicate(false);
childElementObject.setElement(messageItem);
return childElementObject;
}
}
for (int i = 1; i < item_number; i = i + 2) {
Element messageItem = (Element) messageItems.item(i);
//判断节点是否处于同一级别
if(!messageItem.getNodeName().equals(son.getNodeName())){
continue;
}
if(isEqualNode(messageItem,son)){//仅判断当前节点是否一致
if(hasEqualAttributes(messageItem,son)){//当前节点完全相同不需要合并
childElementObject.setNeedDuplicate(false);
childElementObject.setElement(messageItem);
return childElementObject;
}else{//当前节点的属性不相同,需要合并
childElementObject.setNeedDuplicate(true);
childElementObject.setElement(father);
return childElementObject;
}
}
}
//目标文档该节点不存在,需要合并到目标文档中
childElementObject.setNeedDuplicate(true);
childElementObject.setElement(father);
return childElementObject;
}
/**
* 判断两个节点是否相同,未判断节点的属性
* @param arg0
* @param arg
* @return
*/
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;
}
/**
* 判断节点的属性是否相同
* @param arg0
* @param arg
* @return
*/
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 {
String sourcefile = "d:/a.xml";
String targetfile = "d:/b.xml";
boolean isdone = XMLMergeUtil.isMerging(sourcefile, targetfile);
if (isdone)
System.out.println("XML files have been merged.");
else
System.out.println("XML files have NOT been merged.");
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 复制子节点对象
* @author Administrator
*
*/
class DuplicateChildElementObject{
private boolean needDuplicate = true;//记录该节点是否需要复制
private Element element = null;//记录该节点的父节点
public DuplicateChildElementObject() {
super();
}
public boolean isNeedDuplicate() {
return needDuplicate;
}
public void setNeedDuplicate(boolean needDuplicate) {
this.needDuplicate = needDuplicate;
}
public Element getElement() {
return element;
}
public void setElement(Element element) {
this.element = element;
}
}