Reputation: 33353
I have the following method to update node values in XML file
static public void updateRepositoryValue(String fileName, String xpath, String value){
try {
String rootPath = Paths.get(".").toAbsolutePath().normalize().toString();
String path = rootPath + "/src/main/resources/repository/" + fileName + ".xml";
DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
DocumentBuilder b = f.newDocumentBuilder();
Document doc = b.parse(new File(path));
XPath xPath = XPathFactory.newInstance().newXPath();
Node updatedNode = (Node) xPath.compile(xpath).evaluate(doc, XPathConstants.NODE);
updatedNode.setTextContent(value);
Transformer tf = TransformerFactory.newInstance().newTransformer();
tf.setOutputProperty(OutputKeys.INDENT, "yes");
tf.setOutputProperty(OutputKeys.METHOD, "xml");
tf.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
DOMSource domSource = new DOMSource(doc);
StreamResult sr = new StreamResult(new File(path));
tf.transform(domSource, sr);
}catch (Exception e){
e.printStackTrace();
}
}
Functionally it works.
The problem is that after each node update this code adds an empty lines between every file content lines (nodes).
Currently I use the code above to update the secret
node value, but I don't think it matters what value do I update.
So from this
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<general>
<environment>staging</environment>
<tenantNameDev>automationdev</tenantNameDev>
<tenantName>automation5</tenantName>
<tenantNameProd>automation3</tenantNameProd>
<userName>[email protected]</userName>
<userNameDev>[email protected]</userNameDev>
<incompleteDetailsNotification>Some of the details are incomplete or invalid</incompleteDetailsNotification>
<ui>
<multiValueAtt>Gender</multiValueAtt>
<incompleteDetailsNotification>Some of the details are incomplete or invalid</incompleteDetailsNotification>
</ui>
<api>
<ownerIdAnn>3052cb88-a5a6-40db-af95-e1225ecf45fe</ownerIdAnn>
<schemaIdAnn>f60566b1-be2b-40b1-9663-a7bb52ba2d3f</schemaIdAnn>
<ownerId>e3bd1480-09b5-4268-9126-6962238e9a1e</ownerId>
<schemaId>fd2941ad-276e-42b7-88fb-5054e8acdc8c</schemaId>
<ownerIdProd>5218f707-96de-4d4c-92c6-ebedd9ccbdbf</ownerIdProd>
<schemaIdProd>f50f2ac3-8e38-4733-adac-4817e3c58643</schemaIdProd>
<envClientId>PYJYF7XU017OGFH5RJ8Q</envClientId>
<secret>6MmE3bELLzO29r1ToG7LoVspWqanNJNGZCP0tG0N</secret>
<workspaceId>e3bd1480-09b5-4268-9126-6962238e9a1e</workspaceId>
<partnerId>b0f95322-a898-4af1-8fc1-9a8951d0c13a</partnerId>
<email>[email protected] </email>
<alternativeWorkspaceId>81e15977-070a-4e68-8808-e2e6bb134f25</alternativeWorkspaceId>
<alternativeEnvClientId>PQSWUCNXVRL1LALUJBRJ</alternativeEnvClientId>
<alternativeSecret>VYpdpQ81n6p7i5C8FL2ni1RVOrHlD34ESxI1FW8U</alternativeSecret>
<serverDeployDelay>3500</serverDeployDelay>
</api>
</general>
After 4 calling the method above I receive this:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<general>
<environment>staging</environment>
<tenantNameDev>automationdev</tenantNameDev>
<tenantName>automation5</tenantName>
<tenantNameProd>automation3</tenantNameProd>
<userName>[email protected]</userName>
<userNameDev>[email protected]</userNameDev>
<incompleteDetailsNotification>Some of the details are incomplete or
invalid</incompleteDetailsNotification>
<ui>
<multiValueAtt>Gender</multiValueAtt>
<incompleteDetailsNotification>Some of the details are incomplete or invalid</incompleteDetailsNotification>
</ui>
<api>
<ownerIdAnn>3052cb88-a5a6-40db-af95-e1225ecf45fe</ownerIdAnn>
<schemaIdAnn>f60566b1-be2b-40b1-9663-a7bb52ba2d3f</schemaIdAnn>
<ownerId>e3bd1480-09b5-4268-9126-6962238e9a1e</ownerId>
<schemaId>fd2941ad-276e-42b7-88fb-5054e8acdc8c</schemaId>
<ownerIdProd>5218f707-96de-4d4c-92c6-ebedd9ccbdbf</ownerIdProd>
<schemaIdProd>f50f2ac3-8e38-4733-adac-4817e3c58643</schemaIdProd>
<envClientId>PYJYF7XU017OGFH5RJ8Q</envClientId>
<secret>6MmE3bELLzO29r1ToG7LoVspWqanNJNGZCP0tG0N</secret>
<workspaceId>e3bd1480-09b5-4268-9126-6962238e9a1e</workspaceId>
<partnerId>b0f95322-a898-4af1-8fc1-9a8951d0c13a</partnerId>
<email>[email protected] </email>
<alternativeWorkspaceId>81e15977-070a-4e68-8808-e2e6bb134f25</alternativeWorkspaceId>
<alternativeEnvClientId>PQSWUCNXVRL1LALUJBRJ</alternativeEnvClientId>
<alternativeSecret>VYpdpQ81n6p7i5C8FL2ni1RVOrHlD34ESxI1FW8U</alternativeSecret>
<serverDeployDelay>3500</serverDeployDelay>
</api>
</general>
How can I prevent that?
Upvotes: 0
Views: 1203
Reputation: 22157
Here is a conceptual example for XSLT.
The XSLT itself is somewhat generic. It should work for any XSLT without namespaces.
We are passing two parameters to XSLT, i.e. XML element name and its new value:
transformer.setParameter("elementToFind", "test2");
transformer.setParameter("elementValue", "Prophet");
Input XML
<?xml version="1.0"?>
<test>
<abc value="10">data1</abc>
<bbc value="200">data2</bbc>
<abc value="20">
<test2>subdata1</test2>
</abc>
</test>
Output XML
<?xml version='1.0' encoding='utf-8' ?>
<test>
<abc value="10">data1</abc>
<bbc value="200">data2</bbc>
<abc value="20">
<test2>Prophet</test2>
</abc>
</test>
Java
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.*;
public class Process3 {
public static void main(String[] args) {
String XSLTFILE = "e:\\Temp\\Process.xslt";
String INFILE = "e:/Temp/Input.xml";
String OUTFILE = "e:/Temp/Output.xml";
try {
// I/O
StreamSource input = new StreamSource(new File(INFILE));
StreamSource xslt = new StreamSource(new File(XSLTFILE));
StreamResult output = new StreamResult(new File(OUTFILE));
// Transformation
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer(xslt);
// XSLT parameters
transformer.setParameter("elementToFind", "test2");
transformer.setParameter("elementValue", "Prophet");
transformer.transform(input, output);
} catch (TransformerConfigurationException tce) {
tce.printStackTrace();
} catch (TransformerException te) {
te.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
XSLT
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="utf-8" indent="yes" omit-xml-declaration="no"/>
<xsl:strip-space elements="*"/>
<xsl:param name="elementToFind" select="'test2'"/>
<xsl:param name="elementValue" select="'Prophet'"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[local-name()=$elementToFind]">
<xsl:copy>
<xsl:value-of select="$elementValue"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1
Reputation: 163262
You haven't shown your source XML or your stylesheet - options like xsl:strip-space
and xsl:output indent="yes"
make a big difference.
My guess would be that you are copying all of the whitespace text nodes from the source document, and only some of the element nodes.
Upvotes: 1