How to update node value in xml java

后端 未结 1 927
滥情空心
滥情空心 2021-01-12 10:10

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

相关标签:
1条回答
  • 2021-01-12 10:58

    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);
    
    0 讨论(0)
提交回复
热议问题