Java XML How to – Use xpath to find and add/replace more children to a Nodelist in an XML file

huangapple go评论54阅读模式
英文:

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

问题

public void Write2XMLfile(){

    XPathFactory xpathFact = XPathFactory.newInstance();
    XPath xpath = xpathFact.newXPath();

    try {

        // ...
        
        // Retrieve the node corresponding to the 'planlagtAntallPerUndergruppe' array
        Node planlagtAntallPerUndergruppe = (Node) xpath.evaluate("/map/array[@key='planlagtAntallPerUndergruppe']", doc, XPathConstants.NODE);
        if (null != planlagtAntallPerUndergruppe) {
            // Loop through the array elements
            for (int j = 0; j < planlagtAntallPerUndergruppe_antall_value.length; j++) {
                // Create a new 'map' element
                Element mapElement = doc.createElement("map");

                // Create 'number' element for 'antall' and set its value
                Element antallElement = doc.createElement("number");
                antallElement.setAttribute("key", "antall");
                antallElement.appendChild(doc.createTextNode(planlagtAntallPerUndergruppe_antall_value[j]));
                mapElement.appendChild(antallElement);

                // Create 'string' element for 'kode' and set its value
                Element kodeElement = doc.createElement("string");
                kodeElement.setAttribute("key", "kode");
                kodeElement.appendChild(doc.createTextNode(planlagtAntallPerUndergruppe_kode_value[j]));
                mapElement.appendChild(kodeElement);

                // Append the 'map' element to 'planlagtAntallPerUndergruppe'
                planlagtAntallPerUndergruppe.appendChild(mapElement);
            }
        }

        // ...

        // 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();
    }
}
英文:

I have an xml file (ToThis.xml) that i am updating with array variables. Am using Xpath to update to this xml file but i can only update the first array element. see below .

xml file (ToThis.xml) what i get

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

xml file that i would like to get should be like this below

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

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 = &quot;E:/utils/Tothis.xml&quot;;
//
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(filepath);
planlagtAntallPerUndergruppe_antall_value[0] = &quot;67&quot;;                
planlagtAntallPerUndergruppe_kode_value[0] = &quot;SLAKTEGRIS&quot;;
planlagtAntallPerUndergruppe_antall_value[1] = &quot;4&quot;;                
planlagtAntallPerUndergruppe_kode_value[1] = &quot;UNGSAU&quot;;        
//2.  planlagtAntallPerUndergruppe **************************
System.out.println(&quot;\n This is second&quot; );
Node planlagtAntallPerUndergruppe = (Node) xpath.evaluate(&quot;/map/array[@key=&#39;planlagtAntallPerUndergruppe&#39;]/*&quot;, doc, XPathConstants.NODE);
if(null != planlagtAntallPerUndergruppe) {
NodeList nodeList = planlagtAntallPerUndergruppe.getChildNodes();
for (int i = 0;null!=nodeList &amp;&amp; i &lt; nodeList.getLength(); i++) {
Node nod = nodeList.item(i);
if(nod.getNodeType() == Node.ELEMENT_NODE){
NodeList arrayElements_18 = (NodeList) xpath.evaluate(&quot;/map/array[@key=&#39;planlagtAntallPerUndergruppe&#39;]/*&quot;, doc, XPathConstants.NODESET);
//System.out.println(&quot;\n number of elements&quot; + arrayElements_18.getLength());
for (int j = 0; j &lt; arrayElements_18.getLength(); j++) {
//.  antall
Node antall = (Node) xpath.evaluate(&quot;(/map/array/map/number[@key=&#39;antall&#39;])[1]&quot;, doc, XPathConstants.NODE);
antall.setTextContent(planlagtAntallPerUndergruppe_antall_value[j]);
// end antall
//.  kode
Node kode = (Node) xpath.evaluate(&quot;(/map/array/map/string[@key=&#39;kode&#39;])[1]&quot;, doc, XPathConstants.NODE);
kode.setTextContent(planlagtAntallPerUndergruppe_kode_value[j]);
//System.out.println(&quot;\n\n antall: &quot; + 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(&quot;Done Updating The Api_XML_Format.xml&quot;);
} 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();
}
}

答案1

得分: 2

XPath被有意地用于跟踪/读取XML,但不能用于修改XML。

因此,我将代码从使用XPath更改为使用DOM解析器。

try {
    DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
    DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
    Document doc = docBuilder.newDocument();
    
    // 创建根元素 "map"
    Element rootElement = doc.createElement("map");
    doc.appendChild(rootElement);
    
    // 根元素下的子元素
    
    // 1. 创建 "string" 元素 "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);

    // 创建 "array" 元素 "planlagtAntallPerUndergruppe"
    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++) {
            Element map1 = doc.createElement("map");
            planlagtAntallPerUndergruppe.appendChild(map1);
            
            // 添加 "number" 元素 "antall"
            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);
            
            // 添加 "string" 元素 "kode"
            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);
        }
    }
    // 结束 "planlagtAntallPerUndergruppe"

    // 将内容写入XML文件
    DOMSource source = new DOMSource(doc);
    StreamResult result = new StreamResult(new File("E:/utils/students-new.xml"));

    TransformerFactory transformerFactory = TransformerFactory.newInstance();
    Transformer transformer = transformerFactory.newTransformer();
    // 格式化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();
}
英文:

Xpath is purposely used to trace/read through an xml but cannot be used to modify an xml.

So, I changed my code from using XPath to using DOM Parser.

try
{
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.newDocument();
// Map root element
Element rootElement = doc.createElement(&quot;map&quot;);
doc.appendChild(rootElement);
//ROOT map
//1. ankomstDato
Element ankomstDato = doc.createElement(&quot;string&quot;);
Attr attrType_ankomstDato = doc.createAttribute(&quot;key&quot;);
attrType_ankomstDato.setValue(&quot;ankomstDato&quot;);
ankomstDato.setAttributeNode(attrType_ankomstDato);
ankomstDato.appendChild(doc.createTextNode(ankomstDato_value));
rootElement.appendChild(ankomstDato);
//. planlagtAntallPerUndergruppe
// planlagtAntallPerUndergruppe element
if (planlagtAntallPerUndergruppe_Count !=0){
Element planlagtAntallPerUndergruppe = doc.createElement(&quot;array&quot;);
rootElement.appendChild(planlagtAntallPerUndergruppe);
Attr attr = doc.createAttribute(&quot;key&quot;);
attr.setValue(&quot;planlagtAntallPerUndergruppe&quot;);
planlagtAntallPerUndergruppe.setAttributeNode(attr);
for (int i = 0; i &lt; planlagtAntallPerUndergruppe_Count; i ++){
//to add &quot;map&quot; element
Element map1 = doc.createElement(&quot;map&quot;);
planlagtAntallPerUndergruppe.appendChild(map1);
// antall element
Element antall = doc.createElement(&quot;number&quot;);
Attr attrType = doc.createAttribute(&quot;key&quot;);
attrType.setValue(&quot;antall&quot;);
antall.setAttributeNode(attrType);
antall.appendChild(doc.createTextNode(planlagtAntallPerUndergruppe_antall_value[i]));
map1.appendChild(antall);
//kode element
Element kode = doc.createElement(&quot;string&quot;);
Attr attrType1 = doc.createAttribute(&quot;key&quot;);
attrType1.setValue(&quot;kode&quot;);
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(&quot;E:/utils/students-new.xml&quot;));
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
// Beautify the format of the resulted XML
transformer.setOutputProperty(OutputKeys.INDENT, &quot;yes&quot;);
transformer.setOutputProperty(&quot;{http://xml.apache.org/xslt}indent-amount&quot;, &quot;4&quot;);
transformer.transform(source, result);
}
catch(Exception ex)
{
ex.printStackTrace();
}
}

答案2

得分: 1

将收集到的数组作为参数传递给 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>
英文:

pass collected arrays into Write2XMLfile method as parameters

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(&quot;map&quot;);
doc.appendChild(rootElement);
Element mainString = doc.createElement(&quot;string&quot;);
mainString.setAttribute(&quot;key&quot;, &quot;ankomstDato&quot;);
rootElement.appendChild(mainString).setTextContent(&quot;2020-08-20&quot;);
Element array = doc.createElement(&quot;array&quot;);
array.setAttribute(&quot;key&quot;, &quot;planlagtAntallPerUndergruppe&quot;);
rootElement.appendChild(array);
if(planlagtAntallPerUndergruppe_antall_value.length&gt;0){
for (int i = 0; i &lt; planlagtAntallPerUndergruppe_antall_value.length; i++) {
Element map = doc.createElement(&quot;map&quot;);
array.appendChild(map);
Element number =  doc.createElement(&quot;number&quot;);
number.setAttribute(&quot;key&quot;, &quot;antall&quot;);
map.appendChild(number).setTextContent(planlagtAntallPerUndergruppe_antall_value[i]);
Element string =  doc.createElement(&quot;string&quot;);
string.setAttribute(&quot;key&quot;, &quot;kode&quot;);
map.appendChild(string).setTextContent(planlagtAntallPerUndergruppe_kode_value[i]);
}
}
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, &quot;yes&quot;);
transformer.setOutputProperty(&quot;{http://xml.apache.org/xslt}indent-amount&quot;, &quot;2&quot;);
DOMSource source = new DOMSource(doc);
StreamResult output = new StreamResult(new File(&quot;output.xml&quot;));
transformer.transform(source, output);
} catch (Exception e) {
e.printStackTrace();
}
}

output.xml

&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;
&lt;map&gt;
&lt;string key=&quot;ankomstDato&quot;&gt;2020-08-20&lt;/string&gt;
&lt;array key=&quot;planlagtAntallPerUndergruppe&quot;&gt;
&lt;map&gt;
&lt;number key=&quot;antall&quot;&gt;67&lt;/number&gt;
&lt;string key=&quot;kode&quot;&gt;SLAKTEGRIS&lt;/string&gt;
&lt;/map&gt;
&lt;map&gt;
&lt;number key=&quot;antall&quot;&gt;4&lt;/number&gt;
&lt;string key=&quot;kode&quot;&gt;UNGSAU&lt;/string&gt;
&lt;/map&gt;
&lt;/array&gt;
&lt;/map&gt;

huangapple
  • 本文由 发表于 2020年9月11日 15:28:21
  • 转载请务必保留本文链接:https://go.coder-hub.com/63842584.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定