Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update node value in xml java

Tags:

java

xml

I am currently working on a xml project. So far, I have successfully link my xml to my java class using Dom Parser. I have the code provide below. What I am struggling with is updating my startdate's month by one so something like this 2/1/2013, 3/1/2013... will change in the xml file accordingly. I have the method call updateDate at the bottom, but the xml file won't update it's value when I call it. Help will be appreciated

data.xml before

<?xml version="1.0" encoding="UTF-8">
<data>
    <username>hello123</username>
    <startdate>01/01/2011</startdate>
    <enddate>06/01/2013</enddate>
</data>

desire data.xml after

<?xml version="1.0" encoding="UTF-8">
<data>
    <username>hello123</username>
    <startdate>02/01/2011</startdate> <--- This will change 
    <enddate>06/01/2013</enddate>
</data>

main.java

public class main {

    public static void main(String[] args) {

        Calendar cal2 = null;

            String username = null;
            String startdate = null;
            String enddate = null;
            String date = null;
            String date_end = null;

            try {   

                File data = new File("data.xml");
                DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
                DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
                Document doc = dBuilder.parse(data);
                doc.getDocumentElement().normalize();
                for (int i = 0; i < nodes.getLength(); i++) {
                    Node node = nodes.item(i);         
                    if (node.getNodeType() == Node.ELEMENT_NODE) {     
                        Element element = (Element) node;
                        username = getValue("username", element);
                        startdate = getValue("startdate", element);
                        enddate = getValue("enddate", element);
                    }
                }  

                date = startdate;

                //end date
                Date date_end = new SimpleDateFormat("MM/dd/yyyy", Locale.ENGLISH).parse(enddate);
                Calendar end_date_cal = Calendar.getInstance();  
                end_date_cal.setTime(date_end);  

                // initial date
                Date date_int = new SimpleDateFormat("MM/dd/yyyy", Locale.ENGLISH).parse(date);
                cal2 = Calendar.getInstance();  
                cal2.setTime(date_int); 

                //call the method 
                updateDate(cal2);

                TransformerFactory transformerFactory = TransformerFactory.newInstance();
                Transformer transformer = transformerFactory.newTransformer();
                DOMSource source = new DOMSource(doc);
                StreamResult result = new StreamResult(new File("data.xml"));
                transformer.transform(source, result);

                System.out.println("Update Successfully");

            }

        } catch (Exception ex) {    
            log.error(ex.getMessage());     
            ex.printStackTrace();         
        }
    }

    private static void updateDate(Calendar cal2){

        cal2.add(Calendar.MONTH, 1);

        //need to push it back to the calendar
    }


    private static String getValue(String tag, Element element) {  
        NodeList nodes = element.getElementsByTagName(tag).item(0).getChildNodes();   
        Node node = (Node) nodes.item(0);   
        return node.getNodeValue();   
    }

    private static void setValue(String tag, Element element , String input) {  
        NodeList nodes = element.getElementsByTagName(tag).item(0).getChildNodes();   
        Node node = (Node) nodes.item(0); 
        node.setTextContent(input);
    }

}
like image 618
Big Ticket Avatar asked Aug 03 '15 05:08

Big Ticket


People also ask

How do you change values in XML?

The way to change the value of an attribute, is to change its text value. This can be done using the setAttribute() method or setting the nodeValue property of the attribute node.

What is node value in XML?

The nodeValue property is used to get the text value of a node. The getAttribute() method returns the value of an attribute.

How do I append a node to an existing XML file in Java?

Add a Node - appendChild() The appendChild() method adds a child node to an existing node. The new node is added (appended) after any existing child nodes. Note: Use insertBefore() if the position of the node is important.


1 Answers

Java 8's Time API

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("M/d/yyyy");
LocalDate ld = LocalDate.parse("2/1/2013", formatter);
System.out.println("From " + formatter.format(ld));
ld = ld.plusMonths(1);
System.out.println("To " + formatter.format(ld));

Which prints

From 2/1/2013
To 3/1/2013

BUT, you never apply the value back to the XML document. As I tried to demonstrate in your previous question, you need to change the textContent of the node...

node.setTextContent(formatter.format(ld))

which is why I suggested using xPath instead of walking the document content

For example...

import java.io.File;
import java.io.IOException;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

public class UpdateXML {

    public static void main(String[] args) {

        try {
            DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
            DocumentBuilder b = f.newDocumentBuilder();
            Document doc = b.parse(new File("Data.xml"));

            XPath xPath = XPathFactory.newInstance().newXPath();
            Node startDateNode = (Node) xPath.compile("/data/startdate").evaluate(doc, XPathConstants.NODE);
            startDateNode.setTextContent(addMonthTo(startDateNode.getTextContent()));

            xPath = XPathFactory.newInstance().newXPath();
            Node endDateNode = (Node) xPath.compile("/data/enddate").evaluate(doc, XPathConstants.NODE);
            endDateNode.setTextContent(addMonthTo(endDateNode.getTextContent()));

            Transformer tf = TransformerFactory.newInstance().newTransformer();
            tf.setOutputProperty(OutputKeys.INDENT, "yes");
            tf.setOutputProperty(OutputKeys.METHOD, "xml");
            tf.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");

            DOMSource domSource = new DOMSource(doc);
            StreamResult sr = new StreamResult(new File("AData.xml"));
            tf.transform(domSource, sr);
        } catch (ParserConfigurationException | SAXException | IOException | XPathExpressionException | DOMException | TransformerFactoryConfigurationError | IllegalArgumentException | TransformerException exp) {
            exp.printStackTrace();
        }
    }

    public static String addMonthTo(String value) {

        String patterns[] = {"M/d/yyyy", "M/dd/yyyy", "MM/d/yyyy", "MM/dd/yyyy"};

        LocalDate ld = null;
        for (String pattern : patterns) {
            try {
                ld = LocalDate.parse(value, DateTimeFormatter.ofPattern(pattern));
                break;
            } catch (DateTimeParseException exp) {
            }
        }

        if (ld == null) {
            throw new DateTimeParseException("Could not parse " + value + " with available patterns", value, -1);
        }

        ld = ld.plusMonths(1);
        return DateTimeFormatter.ofPattern("MM/dd/yyyy").format(ld);

    }

}

Which took...

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<data>
  <username>admin</username>
  <password>12345</password>
  <interval>1</interval>
  <timeout>90</timeout>
  <startdate>1/1/2013</startdate>
  <enddate>06/01/2013</enddate>
  <ttime>1110</ttime>
</data>

And outputted...

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<data>
  <username>admin</username>
  <password>12345</password>
  <interval>1</interval>
  <timeout>90</timeout>
  <startdate>02/01/2013</startdate>
  <enddate>07/01/2013</enddate>
  <ttime>1110</ttime>
</data>

i want the startdate 6 months earlier then the enddate

Java 8

String endDateValue = "07/01/2013";

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy");
LocalDate endDate = LocalDate.parse(endDateValue, formatter);
LocalDate startDate = endDate.minusMonths(6);

String startDateValue = formatter.format(startDate);

Calendar

I'd prefer Joda-Time, but

String endDateValue = "07/01/2013";
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");
Date endDate = sdf.parse(endDateValue);

Calendar cal = Calendar.getInstance();
cal.setTime(endDate);
cal.add(Calendar.MONTH, -6);

Date startDate = cal.getTime();
String startDateVaue = sdf.format(startDate);
like image 110
MadProgrammer Avatar answered Sep 29 '22 23:09

MadProgrammer