如何在xml java中更新节点值

时间:2015-08-03 05:56:41

标签: java xml

我目前正在开发一个xml项目。到目前为止,我已经使用Dom Parser成功将我的xml链接到我的java类。我在下面提供了代码。我正在努力的是将我的startdate的月份更新为1,因此像这样的2/2 / 2013,3 / 1/2013 ...将相应地在xml文件中更改。我在底部有方法调用updateDate,但是当我调用它时,xml文件不会更新它的值。帮助将不胜感激

data.xml 之前

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

之后需要data.xml
<?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);
    }

}

1 个答案:

答案 0 :(得分:5)

Java 8的Time API

        [Required(ErrorMessage = "*")]
        [Display(Name = "Account Name")]
        public string AccountName { get; set; }
        [Required(ErrorMessage = "*")]
        [Display(Name = "Contact Name")]
        public string ContactName { get; set; }

打印

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));

但是,您永远不会将该值应用回XML文档。当我尝试在您的previous question中进行演示时,您需要更改节点的From 2/1/2013 To 3/1/2013 ...

textContent

这就是为什么我建议使用xPath而不是走文档内容

例如......

node.setTextContent(formatter.format(ld))

这花了...

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);

    }

}

并输出......

<?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>
  

我希望startdate提前6个月,然后是enddate

Java 8

<?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>

日历

我更喜欢Joda-Time,但

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);