简体   繁体   English

Java XML How to - 使用 xpath 在 XML 文件中的节点列表中查找和添加/替换更多子项

[英]Java XML How to - Use xpath to find and add/replace more children to a Nodelist in an XML file

I have an xml file (ToThis.xml) that i am updating with array variables.我有一个 xml 文件 (ToThis.xml),我正在用数组变量更新它。 Am using Xpath to update to this xml file but i can only update the first array element.我正在使用 Xpath 更新到这个 xml 文件,但我只能更新第一个数组元素。 see below .见下文 。

xml file (ToThis.xml) what i get xml 文件 (ToThis.xml) 我得到了什么

<?xml version="1.0" encoding="UTF-8"?><map xmlns="http://www.w3.org/2005/xpath-functions">
    <string key="ankomstDato">2020-08-20</string>
    <array key="planlagtAntallPerUndergruppe">
       <map>
          <number key="antall">67</number>
          <string key="kode">SLAKTEGRIS</string>
       </map> 
    </array>   
 </map>

xml file that i would like to get should be like this below我想获得的 xml 文件应该如下所示

<?xml version="1.0" encoding="UTF-8"?><map xmlns="http://www.w3.org/2005/xpath-functions">
    <string key="ankomstDato">2020-08-20</string>
    <array key="planlagtAntallPerUndergruppe">
       <map>
          <number key="antall">67</number>
          <string key="kode">SLAKTEGRIS</string>
       </map> 
       <map>
          <number key="antall">4</number>
          <string key="kode">UNGSAU</string>
     </map>
    </array>   
 </map>

Below is portion of the code where it get me the first result.下面是代码的一部分,它让我得到第一个结果。 NOTE( The two array variable in real scenario are not hard coded they are assigned dynamically)注意(实际场景中的两个数组变量不是硬编码的,它们是动态分配的)

public void Write2XMLfile(){
    
            XPathFactory xpathFact = XPathFactory.newInstance();
        XPath xpath = xpathFact.newXPath();
    
        try {
    
            //
            String filepath = "E:/utils/Tothis.xml";
            //
    
            
            DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
            Document doc = docBuilder.parse(filepath);

            planlagtAntallPerUndergruppe_antall_value[0] = "67";                
            planlagtAntallPerUndergruppe_kode_value[0] = "SLAKTEGRIS";

            planlagtAntallPerUndergruppe_antall_value[1] = "4";                
            planlagtAntallPerUndergruppe_kode_value[1] = "UNGSAU";        
    
            //2.  planlagtAntallPerUndergruppe **************************
            System.out.println("\n This is second" );
            Node planlagtAntallPerUndergruppe = (Node) xpath.evaluate("/map/array[@key='planlagtAntallPerUndergruppe']/*", doc, XPathConstants.NODE);
            if(null != planlagtAntallPerUndergruppe) {
                NodeList nodeList = planlagtAntallPerUndergruppe.getChildNodes();
                for (int i = 0;null!=nodeList && i < nodeList.getLength(); i++) {
                    Node nod = nodeList.item(i);
                    if(nod.getNodeType() == Node.ELEMENT_NODE){
                        NodeList arrayElements_18 = (NodeList) xpath.evaluate("/map/array[@key='planlagtAntallPerUndergruppe']/*", doc, XPathConstants.NODESET);
                        //System.out.println("\n number of elements" + arrayElements_18.getLength());
                        for (int j = 0; j < arrayElements_18.getLength(); j++) {
                            //.  antall
                            Node antall = (Node) xpath.evaluate("(/map/array/map/number[@key='antall'])[1]", doc, XPathConstants.NODE);
                            antall.setTextContent(planlagtAntallPerUndergruppe_antall_value[j]);
                            // end antall
    
                            //.  kode
                            Node kode = (Node) xpath.evaluate("(/map/array/map/string[@key='kode'])[1]", doc, XPathConstants.NODE);
                            kode.setTextContent(planlagtAntallPerUndergruppe_kode_value[j]);
                            //System.out.println("\n\n antall: " + planlagtAntallPerUndergruppe_antall_value[j]);
    
                            // end kode                       
                        }                    
                    }
                         
                }
            }
    
            // end array planlagtAntallPerUndergruppe
            
    
            // write the content into xml file
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            DOMSource source = new DOMSource(doc);
            StreamResult result = new StreamResult(new File(filepath));
            transformer.transform(source, result);
    
            System.out.println("Done Updating The Api_XML_Format.xml");
    
        } catch (ParserConfigurationException pce) {
            pce.printStackTrace();
        } catch (TransformerException tfe) {
            tfe.printStackTrace();
        } catch (IOException ioe) {
            ioe.printStackTrace();
        } catch (SAXException sae) {
       

     sae.printStackTrace();
    } catch (XPathExpressionException xee) {
        xee.printStackTrace();
    }

    
  }

Xpath is purposely used to trace/read through an xml but cannot be used to modify an xml. Xpath 专门用于跟踪/读取 xml,但不能用于修改 xml。

So, I changed my code from using XPath to using DOM Parser.因此,我将代码从使用 XPath 更改为使用 DOM Parser。

try
            {
        DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
        Document doc = docBuilder.newDocument();
        // Map root element
        Element rootElement = doc.createElement("map");
        doc.appendChild(rootElement);
        //ROOT map
        
        //1. ankomstDato
        Element ankomstDato = doc.createElement("string");
        Attr attrType_ankomstDato = doc.createAttribute("key");
        attrType_ankomstDato.setValue("ankomstDato");
        ankomstDato.setAttributeNode(attrType_ankomstDato);
        ankomstDato.appendChild(doc.createTextNode(ankomstDato_value));
        rootElement.appendChild(ankomstDato);

        //. planlagtAntallPerUndergruppe
        // planlagtAntallPerUndergruppe element
        

        if (planlagtAntallPerUndergruppe_Count !=0){
            Element planlagtAntallPerUndergruppe = doc.createElement("array");
            rootElement.appendChild(planlagtAntallPerUndergruppe);

            Attr attr = doc.createAttribute("key");
            attr.setValue("planlagtAntallPerUndergruppe");
            planlagtAntallPerUndergruppe.setAttributeNode(attr);

            for (int i = 0; i < planlagtAntallPerUndergruppe_Count; i ++){
                //to add "map" element
                Element map1 = doc.createElement("map");
                planlagtAntallPerUndergruppe.appendChild(map1);


                    // antall element
                    Element antall = doc.createElement("number");
                    Attr attrType = doc.createAttribute("key");
                    attrType.setValue("antall");
                    antall.setAttributeNode(attrType);
                    antall.appendChild(doc.createTextNode(planlagtAntallPerUndergruppe_antall_value[i]));
                    map1.appendChild(antall);
                    
                    //kode element
                    Element kode = doc.createElement("string");
                    Attr attrType1 = doc.createAttribute("key");
                    attrType1.setValue("kode");
                    kode.setAttributeNode(attrType1);
                    kode.appendChild(doc.createTextNode(planlagtAntallPerUndergruppe_kode_value[i]));
                    map1.appendChild(kode);
            }
        }
        //end planlagtAntallPerUndergruppe

        
        // Write the content into XML file
        DOMSource source = new DOMSource(doc);
        StreamResult result = new StreamResult(new File("E:/utils/students-new.xml"));
        
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        Transformer transformer = transformerFactory.newTransformer();
        // Beautify the format of the resulted XML
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
        transformer.transform(source, result);
         }
        catch(Exception ex)
          {
            ex.printStackTrace();
        }
    
      }

pass collected arrays into Write2XMLfile method as parameters将收集的数组作为参数传递给Write2XMLfile方法

public void Write2XMLfile(String[] planlagtAntallPerUndergruppe_antall_value, String[] planlagtAntallPerUndergruppe_kode_value) {
   
   try {
       
         DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
         DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
         Document doc = dBuilder.newDocument();
         
         Element rootElement = doc.createElement("map");
         doc.appendChild(rootElement);

         Element mainString = doc.createElement("string");
         mainString.setAttribute("key", "ankomstDato");
         rootElement.appendChild(mainString).setTextContent("2020-08-20");
         
         
         Element array = doc.createElement("array");
         array.setAttribute("key", "planlagtAntallPerUndergruppe");
         rootElement.appendChild(array);
         

         if(planlagtAntallPerUndergruppe_antall_value.length>0){
             for (int i = 0; i < planlagtAntallPerUndergruppe_antall_value.length; i++) {
                Element map = doc.createElement("map");
                array.appendChild(map);
                
                Element number =  doc.createElement("number");
                number.setAttribute("key", "antall");
                map.appendChild(number).setTextContent(planlagtAntallPerUndergruppe_antall_value[i]);
                
                Element string =  doc.createElement("string");
                string.setAttribute("key", "kode");
                map.appendChild(string).setTextContent(planlagtAntallPerUndergruppe_kode_value[i]);
            }
         }

         TransformerFactory transformerFactory = TransformerFactory.newInstance();
         Transformer transformer = transformerFactory.newTransformer();
         transformer.setOutputProperty(OutputKeys.INDENT, "yes");
         transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
         DOMSource source = new DOMSource(doc);
         StreamResult output = new StreamResult(new File("output.xml"));
         transformer.transform(source, output);
         
      } catch (Exception e) {
         e.printStackTrace();
      }
}

output.xml输出文件

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<map>
  <string key="ankomstDato">2020-08-20</string>
  <array key="planlagtAntallPerUndergruppe">
    <map>
      <number key="antall">67</number>
      <string key="kode">SLAKTEGRIS</string>
    </map>
    <map>
      <number key="antall">4</number>
      <string key="kode">UNGSAU</string>
    </map>
  </array>
</map>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM