简体   繁体   中英

Xpath insert sequence of nodes under a node - Java

I am trying to add sequence of nodes under a node, below is my reference xml:

 <?xml version="1.0" encoding="UTF-8"?> <transformation> <info> <name>Bulkload</name> <description/> <extended_description/> <trans_version/> <trans_type>Normal</trans_type> <trans_status>0</trans_status> <directory>&#x2f;</directory> </info> <connection> <name>con_name</name> <server>server</server> <type>SYBASE</type> <access>Native</access> <database>database</database> <port>port</port> <username>user</username> <password>Encrypted xyz</password> </connection> <step> <name>Extract</name> <type>TextFileOutput</type> <fields> **HERE** <field> </field> </fields> <cluster_schema/> <remotesteps> <input> </input> <output> </output> </remotesteps> <GUI> <xloc>300</xloc> <yloc>168</yloc> <draw>Y</draw> </GUI> </step> </transformation> 

I want to add below xml block inside field tag:

 <field> <name>field_name</name> <type>Integer</type> <format>&#x23;&#x3b;-&#x23;</format> <currency/> <decimal>.</decimal> <group>,</group> <nullif/> <trim_type>none</trim_type> <length>9</length> <precision>0</precision> </field> 

My requirement is to create new xml documents from the above template. I only found a method in Xpath to insert node before a node so I updated my template and added a blank field node in it inside fields node and with that I was able to insert a node with the below code:

        File dest =new File("H:\\Project_Documents\\reference.ktr");
        DocumentBuilderFactory factory = DocumentBuilderFactory
                    .newInstance();
            factory.setIgnoringComments(true);
            DocumentBuilder builder = factory.newDocumentBuilder();
            String newLine = System.getProperty("line.separator");
            Document document = builder.parse(dest);
            XPathFactory xpathFactory = XPathFactory.newInstance();
            XPath xpath = xpathFactory.newXPath();

            NodeList nodes = document.getElementsByTagName("field");
            Text a = document.createTextNode("Anup");
            Element p =document.createElement("field");
            p.appendChild(a);
nodes.item(0).getParentNode().insertBefore(p, nodes.item(0));

but again I faced the dame problem for child nodes ie name, type, format, etc. Could anybody please show me a way to achieve my purpose?

If I cannot achieve it with Xpath then which parser I should use?

One solution, which works:

You have to manage two XML Documents, find the tag you want, and replace.

With XPath you can select more precisely, but no use there.

1 get a DOM for your global XML

Document document= ...

2 get the node you want to insert

Document document_to_insert = builder.parse(new InputSource(new StringReader(xml_to_insert))); // ...

//GET NODE field
NodeList nodes_field_to_insert=document_to_insert.getElementsByTagName("field");

Element node_field_to_insert=null;

for(int i=0; i<nodes_field_to_insert.getLength(); i++)
{
 Node the_node = nodes_field_to_insert.item(i);

 // WE TAKE THE FIRST ONE
 if(the_node instanceof Element)
    {
     node_field_to_insert=(Element) the_node;
     break;
    }
}

3 go to the field node in the global XML

4 replace inside the node

// GET NODE field
NodeList nodes=document.getElementsByTagName("field");

for(int i=0; i<nodes.getLength(); i++)
{
   Node the_node = nodes.item(i);

   if(the_node instanceof Element)
     {
     Element a_child = (Element) the_node;
     Node newNode = document.importNode(node_field_to_insert, true);

     // FATHER
     Node the_parent=a_child.getParentNode();
     the_parent.replaceChild(newNode,a_child);

     // WE STOP
     break;
 }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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