0

How do you edit values on xml that has been appended to a stringbuilder?

We have an xml file looking like the following, which we eventually reads in Java:

<?xml version="1.0" encoding="UTF-8"?>
<urn:receive
        xmlns:urn="urn:xxx"
        xmlns:ns="xxx"
        xmlns:ns1="xxx"
        xmlns:urn1="urn:xxx">
    <urn:give>
        <urn:giveNumber>
           <ns1:number>12345678</ns1:number>
        </urn:giveNumber>
        <urn:giveDates>
            <urn1:dateFrom>2021-07-01</urn1:dateFrom>
            <urn1:dateTo>2021-09-30</urn1:dateTo>
        </urn:giveDates>
    </urn:give>
</urn:receive>

The following is a snippet of code that we use to read an xml file by appending to a stringbuilder and eventually saving it to a string with .toString(). Do notice that there is an int for number and string for startDate and for endDate. These values must be inserted into the xml, and replace the number and dates. Keep in mind that we are not allowed to edit the xml file.

public class test {
    // Logger to print output in commandprompt
    private static final Logger LOGGER = Logger.getLogger(test.class.getName()); 
    public void changeDate() {

        number = 44444444;
        startDate = "2021-01-01";
        endDate   = "2021-03-31";

        try {
            // the XML file for this example
            File xmlFile = new File("requests/dates.xml");

            Reader fileReader = new FileReader(xmlFile);
            BufferedReader bufReader = new BufferedReader(fileReader);

            StringBuilder sb = new StringBuilder();
            String line = bufReader.readLine();

            while( line != null ) {
                sb.append(line).append("\n");
                line = bufReader.readLine();
            }
            String request = sb.toString();
            LOGGER.info("Request" + request);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

How do we replace the number and dates in the xml with number, startDate and endDate, but without editing the xml file?

LOGGER.info("Request" + request); should print the following:

<?xml version="1.0" encoding="UTF-8"?>
<urn:receive
        xmlns:urn="urn:xxx"
        xmlns:ns="xxx"
        xmlns:ns1="xxx"
        xmlns:urn1="urn:xxx">
    <urn:give>
        <urn:giveNumber>
           <ns1:number>44444444</ns1:number>
        </urn:giveNumber>
        <urn:giveDates>
            <urn1:dateFrom>2021-01-01</urn1:dateFrom>
            <urn1:dateTo>2021-03-31</urn1:dateTo>
        </urn:giveDates>
    </urn:give>
</urn:receive>
Buster3650
  • 470
  • 2
  • 8
  • 19
  • You'll need to create a DOM from the `StringBuilder` so `StringReader` is your friend – g00se Aug 31 '21 at 11:49
  • 1
    See if this helps https://stackoverflow.com/questions/31693670/how-to-update-xml-files-in-java/31694184 You dont really need StringBuilder – JCompetence Aug 31 '21 at 11:52

1 Answers1

0

Simple answer: you don't.

You need to parse the XML, and parsing the XML can be done perfectly easily by supplying the parser with the file name; reading the XML into a StringBuilder first is pointless effort.

The easiest way to make a small change to an XML document is to use XSLT, which can be easily invoked from Java. Java comes with an XSLT 1.0 processor built in. XSLT 1.0 is getting rather ancient and you might prefer to use XSLT 3.0 which is much more powerful but requires a third-party library; but for a simple job like this, 1.0 is quite adequate. The stylesheet needed consists of a general rule that copies things unchanged:

<xsl:template match="*">
  <xsl:copy><xsl:apply-templates/></xsl:copy>
</xsl:template>

and then a couple of rules for changing the things you want to change:

<xsl:param name="number"/>
<xsl:param name="startDate"/>
<xsl:param name="endDate"/>

<xsl:template match="ns1:giveNumber/text()" xmlns:ns1="xxx">
  <xsl:value-of select="$number"/>
</xsl:template>

<xsl:template match="urn1:dateFrom/text()" xmlns:urn1="urn:xxx">
  <xsl:value-of select="$dateFrom"/>
</xsl:template>

<xsl:template match="urn1:dateTo/text()" xmlns:urn1="urn:xxx">
  <xsl:value-of select="$dateTo"/>
</xsl:template>

and then you just run the transformation from Java as described at https://docs.oracle.com/javase/tutorial/jaxp/xslt/transformingXML.html, supplying values for the parameters.

Michael Kay
  • 156,231
  • 11
  • 92
  • 164
  • Hi Michael, thank you very much for your answer! Do you mind giving an example on how to do this? I am finding it a little difficult to figure out how to do this. – Buster3650 Aug 31 '21 at 12:56
  • Which part are you having trouble with? The Java end, or the XSLT end? – Michael Kay Aug 31 '21 at 13:33