Android--合并2个Xml

简介: 版权声明:本文为博主原创文章,转载请标明出处。 https://blog.csdn.net/chaoyu168/article/details/70227837 方法一:Dom4J处理XMLimport java.
版权声明:本文为博主原创文章,转载请标明出处。 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

Dom4J处理XML,合并2个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;  
    }  
}  


目录
相关文章
|
6月前
|
XML API PHP
Android使用XML-RPC实现blog客户端
Android使用XML-RPC实现blog客户端
58 2
|
3月前
|
存储 Java 数据库
基于全志H713 Android 11:给TvSettings添加default.xml默认值
本文介绍了在全志H713 Android 11平台上为TvSettings应用添加HDMI CEC功能的默认设置值的方法,通过修改SettingsProvider的源码和配置文件来实现默认值的设置,并提供了详细的步骤和测试结果。
90 0
基于全志H713 Android 11:给TvSettings添加default.xml默认值
|
3月前
|
XML Android开发 UED
"掌握安卓开发新境界:深度解析AndroidManifest.xml中的Intent-filter配置,让你的App轻松响应scheme_url,开启无限交互可能!"
【8月更文挑战第2天】在安卓开发中,scheme_url 通过在`AndroidManifest.xml`中配置`Intent-filter`,使应用能响应特定URL启动或执行操作。基本配置下,应用可通过定义特定URL模式的`Intent-filter`响应相应链接。
114 12
|
3月前
|
Shell Android开发
安卓scheme_url调端:在AndroidManifest.xml 中如何配置 Intent-filter?
为了使Android应用响应vivo和oppo浏览器的Deep Link或自定义scheme调用,需在`AndroidManifest.xml`中配置`intent-filter`。定义启动的Activity及其支持的scheme和host,并确保Activity可由外部应用启动。示例展示了如何配置HTTP/HTTPS及自定义scheme,以及如何通过浏览器和adb命令进行测试,确保配置正确无误。
|
5月前
|
Android开发 开发者
Android UI设计中,Theme定义了Activity的视觉风格,包括颜色、字体、窗口样式等,定义在`styles.xml`。
【6月更文挑战第26天】Android UI设计中,Theme定义了Activity的视觉风格,包括颜色、字体、窗口样式等,定义在`styles.xml`。要更改主题,首先在该文件中创建新主题,如`MyAppTheme`,覆盖所需属性。然后,在`AndroidManifest.xml`中应用主题至应用或特定Activity。运行时切换主题可通过重新设置并重启Activity实现,或使用`setTheme`和`recreate()`方法。这允许开发者定制界面并与品牌指南匹配,或提供多主题选项。
85 6
|
5月前
|
XML 存储 JavaScript
50. 【Android教程】xml 数据解析
50. 【Android教程】xml 数据解析
66 1
|
6月前
|
Android开发
android string.xml文件中的整型和string型代替
android string.xml文件中的整型和string型代替
49 0
|
6月前
|
XML Android开发 数据格式
Caused by: android.view.InflateException: Binary XML file line #11: Error inflating class
Caused by: android.view.InflateException: Binary XML file line #11: Error inflating class
61 0
|
6月前
|
XML 数据格式
android.view.InflateException: Binary XML file line #0: Attempt to invoke virtual
android.view.InflateException: Binary XML file line #0: Attempt to invoke virtual
32 0
|
XML Java Android开发
#4,Android Studio Android程序结构 工程目录介绍 文件作用 运行配置文件AndroidManifest.xml
#4,Android Studio Android程序结构 工程目录介绍 文件作用 运行配置文件AndroidManifest.xml