private static Element createChildNode(Element sourceElement , Document document){
        //当前元素下的所有属性
        NamedNodeMap sourceNNM=  sourceElement.getAttributes();
        System.out.println(sourceNNM.getLength());
        //当前的节点名称,并创建一个新的
        Element childElement = document.createElement(sourceElement.getNodeName());
        System.out.println("当前的sourceElement节点名称为:" + sourceElement.getNodeName());
        //添加属性
        for(int i = 0; i< sourceNNM.getLength(); i ++){
           System.out.println("+++setNodeValue +++");
           //将当前所有的属性内容全部放到新的elment中
           childElement.setAttribute(sourceNNM.item(i).getNodeName(), sourceNNM.item(i).getTextContent());
           
            System.out.println("NodeName==>" + sourceNNM.item(i).getNodeName() + " , TextContent==>" +
                    sourceNNM.item(i).getTextContent() + " ,NodeValue==>" + 
                            sourceNNM.item(i).getNodeValue());            
            
        }
        
        //如果存在子节点
        Node sourceNode = (Node)sourceElement;
        NodeList sourceChildNodeList =sourceNode.getChildNodes();
        for(int i =0; i < sourceChildNodeList.getLength(); i ++){
            System.out.println("子节点名称为:===》" + sourceChildNodeList.item(i).getNodeName() + " , 节点值为:" + sourceChildNodeList.item(i).getNodeValue() + " , 子节点内容为:" +
                    sourceChildNodeList.item(i).getTextContent());
            String strChildName = sourceChildNodeList.item(i).getNodeName();
            if(!strChildName.equals("#text")){
                //说明存在子节点
                System.out.println("说明存在子节点,此时strChildName=〉" + strChildName);
                Node tempChildNode =(Node)childElement;
                NodeList tempChildNodeList = tempChildNode.getChildNodes();
                Element smailChildElement = createChildNode((Element)sourceChildNodeList.item(i), document);
                childElement.appendChild(smailChildElement);
            }else{
                //不存在子节点
                System.out.println("说明不存在子节点,此时strChildName=〉" + strChildName);
            }
        }

        return childElement;
    }

 

最近因项目需要,做了一个将第三方需要的用到的xml文件,直接通过程序自动导入到mainfest.xml中。减少写那些申明,activity的麻烦。

下面以添加activity为例进行讲解:

思路分析: 1:先通过Document获取到mainest中的所有内容

     2: 从得到的内容中获取到application节点(activity都在application下)

     3:然后再通过一个递归进行获取appliation下的子节点(activity也可能会存在子节点)

      4: 生成获取到的节点,并通过TransformerFactory将文档创建出来。

 

先获得Document

public static ArrayList<String> getAllElementAttributeByTagName(
            String originFile, String tagName, String attributeName)
            throws SAXException, IOException, ParserConfigurationException {
        Document document = readXML(originFile);
        if (document == null)
            return null;
        NodeList nodeLists = document.getElementsByTagName(tagName);
        ArrayList<String> newArrayList = new ArrayList<String>();

        for (int i = 0; i < nodeLists.getLength(); i++) {
            Element element = (Element) nodeLists.item(i);
            if (element != null) {
                String attribute = element.getAttribute(attributeName);
                newArrayList.add(attribute);
            }
        }

        return newArrayList;
    }

得到application,并进行递归创建子节点

public static String appendElementWithTagName(String manifestFile,
            Element element,String rootName,String definiteFile) 
                    throws SAXException, IOException, ParserConfigurationException, 
                    TransformerException{
        Document document = readXML(manifestFile);
        if(document == null) return "解析" + manifestFile + "失败";
        
        System.out.println("到达这里,打印节点名称+++");
        System.out.println(element.getNodeName());
    
        //获取到当前的所有文档子节点
        NodeList docNodeList = document.getChildNodes();
        Node rootNode = null;
        NodeList childList =null;
        for(int i = 0; i <  docNodeList.getLength(); i++){
            String strNodeName = docNodeList.item(i).getNodeName();
            System.out.println("当前strNodeName==》" + strNodeName);
            if(strNodeName.equals("manifest")){
                childList = docNodeList.item(i).getChildNodes();
                int ilen = childList.getLength();
                System.out.println("childList的长度为:" + ilen);
                for(int j = 0; j <  ilen; j++){
                    String strChildNodeName = childList.item(j).getNodeName();
                    String strChildNodeValue = childList.item(j).getNodeValue();
                    String strCHildNodeContext = childList.item(j).getTextContent();
                    System.out.println("当前strChildNodeName==》" + strChildNodeName + " ,strChildNodeValue=>" + strChildNodeValue +
                            " , strCHildNodeContext=>" + strCHildNodeContext);
                    if (strChildNodeName.equals(rootName)){
                        rootNode = childList.item(j);
                    }
                }                
            }
        }

        Element partentElement = createChildNode(element,document);
        
        NodeList rootNodeList = rootNode.getChildNodes();
        rootNode.insertBefore(partentElement, rootNodeList.item(rootNodeList.getLength()- 1));
        System.out.println("加入节点完成");
        
        return writeXML(document, definiteFile);
    }

递归获取节点下的子节点,并生成新的节点

private static Element createChildNode(Element sourceElement , Document document){
        //当前元素下的所有属性
        NamedNodeMap sourceNNM=  sourceElement.getAttributes();
        System.out.println(sourceNNM.getLength());
        //当前的节点名称,并创建一个新的
        Element childElement = document.createElement(sourceElement.getNodeName());
        System.out.println("当前的sourceElement节点名称为:" + sourceElement.getNodeName());
        //添加属性
        for(int i = 0; i< sourceNNM.getLength(); i ++){
           System.out.println("+++setNodeValue +++");
           //将当前所有的属性内容全部放到新的elment中
           childElement.setAttribute(sourceNNM.item(i).getNodeName(), sourceNNM.item(i).getTextContent());
           
            System.out.println("NodeName==>" + sourceNNM.item(i).getNodeName() + " , TextContent==>" +
                    sourceNNM.item(i).getTextContent() + " ,NodeValue==>" + 
                            sourceNNM.item(i).getNodeValue());            
            
        }
        
        //如果存在子节点
        Node sourceNode = (Node)sourceElement;
        NodeList sourceChildNodeList =sourceNode.getChildNodes();
        for(int i =0; i < sourceChildNodeList.getLength(); i ++){
            System.out.println("子节点名称为:===》" + sourceChildNodeList.item(i).getNodeName() + " , 节点值为:" + sourceChildNodeList.item(i).getNodeValue() + " , 子节点内容为:" +
                    sourceChildNodeList.item(i).getTextContent());
            String strChildName = sourceChildNodeList.item(i).getNodeName();
            if(!strChildName.equals("#text")){
                //说明存在子节点
                System.out.println("说明存在子节点,此时strChildName=〉" + strChildName);
                Node tempChildNode =(Node)childElement;
                NodeList tempChildNodeList = tempChildNode.getChildNodes();
                Element smailChildElement = createChildNode((Element)sourceChildNodeList.item(i), document);
                childElement.appendChild(smailChildElement);
            }else{
                //不存在子节点
                System.out.println("说明不存在子节点,此时strChildName=〉" + strChildName);
            }
        }

        return childElement;
    }

其中

Element partentElement = createChildNode(element,document);
        
        NodeList rootNodeList = rootNode.getChildNodes();
        rootNode.insertBefore(partentElement, rootNodeList.item(rootNodeList.getLength()- 1));

是为了将新生成的节点放在父节点的最下方,做到和原文件一个的格式。
生成了出了子节点后,我们需要将当前的document转移到我们的mainfest.xml中去。就使用到了TransformerFactory

方法如下

private static String writeXML(Document document, String fileName)
            throws TransformerException, FileNotFoundException {
        TransformerFactory factory = TransformerFactory.newInstance();
        Transformer former = factory.newTransformer();
        Properties outFormat = new Properties();
        outFormat.setProperty(OutputKeys.ENCODING, "UTF-8");
        outFormat.setProperty(OutputKeys.INDENT, "yes");
        outFormat.setProperty(OutputKeys.METHOD, "xml");
        outFormat.setProperty("{http://xml.apache.org/xslt}indent-amount",
                "2");
        former.setOutputProperties(outFormat);

        DOMSource domSource = new DOMSource(document);
        OutputStream output = new ByteArrayOutputStream();
        StreamResult result = new StreamResult(output);

        StreamResult domResult = new StreamResult(new File(fileName));
        former.transform(domSource, domResult);
        return "解析成功!";
    }

写完这个功能后,对minfest里的节点问题清楚多了。