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&role=editor&role=administrator&role=useradmin&role=reader&role=editeur_n1&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");
CodePudding user response:
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.
CodePudding user response:
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&role=editor&role=administrator&role=useradmin&role=reader&role=editeur_n1&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&role=editor&role=administrator&role=useradmin&role=reader&role=editeur_n1&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>