1

I'm new to xml parsing, I just need to modify the content of an xml response

Current xml bloc

  <app:control xmlns:vaext="http://www.vizrt.com/atom-ext">
        <app:draft>no</app:draft>
        <vaext:state name="published" href="http://test.com/escenic/content/state/workflow/online_staging/published?role=journalist&amp;role=editor&amp;role=administrator&amp;role=useradmin&amp;role=reader&amp;role=editeur_n1&amp;role=publicite"></vaext:state>
    </app:control>
I wanted to change it to :
<app:control xmlns:vaext="http://www.vizrt.com/atom-ext">
    <app:draft>no</app:draft>
    <vaext:state name="ready" href="http://test.comt/content/state/workflow/online_staging/published?role=editor">un-publish</vaext:state>
</app:control>

Currently, I can change the attributes "name" and "href" but the problem with the second part ( adding un-publish</vaext:state> )

          InputSource src = new InputSource(new StringReader(xmlString));
            Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(src);
            Node state = document.getElementsByTagName("state").item(0);
            Node currentstate = state.getAttributes().getNamedItem("name");
            currentstate.setTextContent("ready");
            Node href = state.getAttributes().getNamedItem("href");
                        href.setTextContent( "the new link");

2 Answers 2

1

It can assign by setTextContent() of Node of DOM in org.w3c.dom.Node

node.setTextContent("un-publish");

Demo Code as Modify.java file.

import org.w3c.dom.*;
import org.xml.sax.SAXException;

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.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.*;

public class Modify {
    private static final String FILENAME = "./before.xml";
    private static final String FORMAT_XSLT = "./before-format.xslt";

    public static void main(String[] args) {
        DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        dbf.setNamespaceAware(true);
        try (InputStream is = new FileInputStream(FILENAME)) {
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(is);
            System.out.println("-------------- Before ----------------");
            writeXml(doc, System.out);

            NodeList listOfState = doc.getElementsByTagName("vaext:state");
            Node state = listOfState.item(0);
            if (state.getNodeType() == Node.ELEMENT_NODE) {
                String name = state.getAttributes().getNamedItem("name").getTextContent();
                if ("published".equals(name.trim())) {
                    state.getAttributes().getNamedItem("name").setTextContent("ready");
                    state.setTextContent("un-publish");
                }
                String href = state.getAttributes().getNamedItem("href").getTextContent();
                // http://test.com/escenic/content/state/workflow/online_staging/published?role=journalist&role=editor&role=administrator&role=useradmin&role=reader&role=editeur_n1&role=publicite
                // System.out.println(href);
                String target = "http://test.comt/content/state/workflow/online_staging/published?role=editor";
                state.getAttributes().getNamedItem("href").setTextContent(target);
            }
            // output to console
            System.out.println("-------------- After ----------------");
            writeXml(doc, System.out);
        } catch (ParserConfigurationException | SAXException
                | IOException | TransformerException e) {
            e.printStackTrace();
        }
    }

    // write doc to output stream
    private static void writeXml(Document doc,
            OutputStream output)
            throws TransformerException, UnsupportedEncodingException {
        TransformerFactory transformerFactory = TransformerFactory.newInstance();
        // The default add many empty new line, not sure why?
        // https://stackoverflow.com/questions/58478632/how-to-avoid-extra-blank-lines-in-xml-generation-with-java
        // https://mkyong.com/java/pretty-print-xml-with-java-dom-and-xslt/
        // Transformer transformer = transformerFactory.newTransformer();
        // add a xslt to remove the extra newlines
        Transformer transformer = transformerFactory.newTransformer(
                new StreamSource(new File(FORMAT_XSLT)));
        // pretty print
        transformer.setOutputProperty(OutputKeys.INDENT, "yes");
        transformer.setOutputProperty(OutputKeys.STANDALONE, "no");

        DOMSource source = new DOMSource(doc);
        StreamResult result = new StreamResult(output);
        transformer.transform(source, result);
    }
}

Input XML as before.xml

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:app="http://www.w3.org/TR/html4/">
    <app:control xmlns:vaext="http://www.vizrt.com/atom-ext">
        <app:draft>no</app:draft>
        <vaext:state name="published" href="http://test.com/escenic/content/state/workflow/online_staging/published?role=journalist&amp;role=editor&amp;role=administrator&amp;role=useradmin&amp;role=reader&amp;role=editeur_n1&amp;role=publicite"></vaext:state>
    </app:control>
</xs:schema>

XSLT file as before-format.xslt name.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes" cdata-section-elements="address bio"/>
    <xsl:strip-space elements="*"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

Compile & Run it

$ javac Modify.java
$ java Modify
-------------- Before ----------------
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:app="http://www.w3.org/TR/html4/">
    <app:control xmlns:vaext="http://www.vizrt.com/atom-ext">
        <app:draft>no</app:draft>
        <vaext:state href="http://test.com/escenic/content/state/workflow/online_staging/published?role=journalist&amp;role=editor&amp;role=administrator&amp;role=useradmin&amp;role=reader&amp;role=editeur_n1&amp;role=publicite" name="published"/>
    </app:control>
</xs:schema>
-------------- After ----------------
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:app="http://www.w3.org/TR/html4/">
    <app:control xmlns:vaext="http://www.vizrt.com/atom-ext">
        <app:draft>no</app:draft>
        <vaext:state href="http://test.comt/content/state/workflow/online_staging/published?role=editor" name="ready">un-publish</vaext:state>
    </app:control>
</xs:schema>
Sign up to request clarification or add additional context in comments.

2 Comments

You don't need to write any XSLT code to achieve an identity transformation. Just use Transformer transformer = transformerFactory.newTransformer(). Also, the cdata-section-elements seems to be a leftover from a different problem.
If use as you mentioned it, it makes an extra empty line in every line. stackoverflow.com/questions/58478632/…
0

Do the transformation in XSLT:

<xsl:stylesheet version="3.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:vaext="http://www.vizrt.com/atom-ext">
  <xsl:mode on-no-match="shallow-copy"/>

  <xsl:template match="vaext:state">
    <vaext:state 
      href="http://test.comt/content/state/workflow/online_staging/published?role=editor" 
      name="ready">un-publish</vaext:state>   
  </xsl:template>
   
</xsl:stylesheet>

and invoke it from Java:

Processor proc = new Processor(false);
Xslt30Transformer trans = proc.newXsltCompiler.compile(stylesheet).load30();
trans.transform(
    new StreamSource(new File(input)), 
    proc.newSerializer(new File(output));

I've shown this using XSLT 3.0 and the Saxon API (disclaimer: my company's product) to save a few lines of code, but this one is well within the capabilities of the XSLT 1.0 processor that comes built in to the JDK.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.