I'm trying to update xml file with system date in specific value based on key name,below is the sample xml file,here i want to update 10-25-2018 to present system date using java code,Please help me to achieve this.
<appSettings>
<add key="CommandTimeOut" value="7200"/>
<!--<add key="Bill" value="0"/>-->
<add key="Ism" value="1"/>
<add key="Cule" value="en-US"/>
<add key="Date" value="10-25-2018"/>
<add key="CreatedUser" value="SCHEDULER"/>
</appSettings>
Just try this code For updating your xml file .
public class XML_Parser {
public static void main(String[] args) {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse("D:\\test.xml");
XPathFactory xPathfactory = XPathFactory.newInstance();
XPath xpath = xPathfactory.newXPath();
XPathExpression expr = xpath.compile("//appSettings/add[#key]");
NodeList nl = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
for (int c = 0; c < nl.getLength(); c++) {
Node currentItem = nl.item(c);
if (currentItem.getAttributes().getNamedItem("key").getNodeValue().equalsIgnoreCase("Date")) {
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = new Date();
currentItem.getAttributes().getNamedItem("value").setNodeValue(dateFormat.format(date));
}
}
doc.getDocumentElement().normalize();
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File("D:\\test.xml"));
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.transform(source, result);
System.out.println("XML file updated successfully");
} catch (Exception e) {
e.printStackTrace();
}
}
}
Related
I have an xml file (ToThis.xml) that i am updating with array variables. Am using Xpath to update to this xml file but i can only update the first array element. see below .
xml file (ToThis.xml) what i get
<?xml version="1.0" encoding="UTF-8"?><map xmlns="http://www.w3.org/2005/xpath-functions">
<string key="ankomstDato">2020-08-20</string>
<array key="planlagtAntallPerUndergruppe">
<map>
<number key="antall">67</number>
<string key="kode">SLAKTEGRIS</string>
</map>
</array>
</map>
xml file that i would like to get should be like this below
<?xml version="1.0" encoding="UTF-8"?><map xmlns="http://www.w3.org/2005/xpath-functions">
<string key="ankomstDato">2020-08-20</string>
<array key="planlagtAntallPerUndergruppe">
<map>
<number key="antall">67</number>
<string key="kode">SLAKTEGRIS</string>
</map>
<map>
<number key="antall">4</number>
<string key="kode">UNGSAU</string>
</map>
</array>
</map>
Below is portion of the code where it get me the first result. NOTE( The two array variable in real scenario are not hard coded they are assigned dynamically)
public void Write2XMLfile(){
XPathFactory xpathFact = XPathFactory.newInstance();
XPath xpath = xpathFact.newXPath();
try {
//
String filepath = "E:/utils/Tothis.xml";
//
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(filepath);
planlagtAntallPerUndergruppe_antall_value[0] = "67";
planlagtAntallPerUndergruppe_kode_value[0] = "SLAKTEGRIS";
planlagtAntallPerUndergruppe_antall_value[1] = "4";
planlagtAntallPerUndergruppe_kode_value[1] = "UNGSAU";
//2. planlagtAntallPerUndergruppe **************************
System.out.println("\n This is second" );
Node planlagtAntallPerUndergruppe = (Node) xpath.evaluate("/map/array[#key='planlagtAntallPerUndergruppe']/*", doc, XPathConstants.NODE);
if(null != planlagtAntallPerUndergruppe) {
NodeList nodeList = planlagtAntallPerUndergruppe.getChildNodes();
for (int i = 0;null!=nodeList && i < nodeList.getLength(); i++) {
Node nod = nodeList.item(i);
if(nod.getNodeType() == Node.ELEMENT_NODE){
NodeList arrayElements_18 = (NodeList) xpath.evaluate("/map/array[#key='planlagtAntallPerUndergruppe']/*", doc, XPathConstants.NODESET);
//System.out.println("\n number of elements" + arrayElements_18.getLength());
for (int j = 0; j < arrayElements_18.getLength(); j++) {
//. antall
Node antall = (Node) xpath.evaluate("(/map/array/map/number[#key='antall'])[1]", doc, XPathConstants.NODE);
antall.setTextContent(planlagtAntallPerUndergruppe_antall_value[j]);
// end antall
//. kode
Node kode = (Node) xpath.evaluate("(/map/array/map/string[#key='kode'])[1]", doc, XPathConstants.NODE);
kode.setTextContent(planlagtAntallPerUndergruppe_kode_value[j]);
//System.out.println("\n\n antall: " + planlagtAntallPerUndergruppe_antall_value[j]);
// end kode
}
}
}
}
// end array planlagtAntallPerUndergruppe
// write the content into xml file
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File(filepath));
transformer.transform(source, result);
System.out.println("Done Updating The Api_XML_Format.xml");
} catch (ParserConfigurationException pce) {
pce.printStackTrace();
} catch (TransformerException tfe) {
tfe.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (SAXException sae) {
sae.printStackTrace();
} catch (XPathExpressionException xee) {
xee.printStackTrace();
}
}
Xpath is purposely used to trace/read through an xml but cannot be used to modify an xml.
So, I changed my code from using XPath to using DOM Parser.
try
{
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.newDocument();
// Map root element
Element rootElement = doc.createElement("map");
doc.appendChild(rootElement);
//ROOT map
//1. ankomstDato
Element ankomstDato = doc.createElement("string");
Attr attrType_ankomstDato = doc.createAttribute("key");
attrType_ankomstDato.setValue("ankomstDato");
ankomstDato.setAttributeNode(attrType_ankomstDato);
ankomstDato.appendChild(doc.createTextNode(ankomstDato_value));
rootElement.appendChild(ankomstDato);
//. planlagtAntallPerUndergruppe
// planlagtAntallPerUndergruppe element
if (planlagtAntallPerUndergruppe_Count !=0){
Element planlagtAntallPerUndergruppe = doc.createElement("array");
rootElement.appendChild(planlagtAntallPerUndergruppe);
Attr attr = doc.createAttribute("key");
attr.setValue("planlagtAntallPerUndergruppe");
planlagtAntallPerUndergruppe.setAttributeNode(attr);
for (int i = 0; i < planlagtAntallPerUndergruppe_Count; i ++){
//to add "map" element
Element map1 = doc.createElement("map");
planlagtAntallPerUndergruppe.appendChild(map1);
// antall element
Element antall = doc.createElement("number");
Attr attrType = doc.createAttribute("key");
attrType.setValue("antall");
antall.setAttributeNode(attrType);
antall.appendChild(doc.createTextNode(planlagtAntallPerUndergruppe_antall_value[i]));
map1.appendChild(antall);
//kode element
Element kode = doc.createElement("string");
Attr attrType1 = doc.createAttribute("key");
attrType1.setValue("kode");
kode.setAttributeNode(attrType1);
kode.appendChild(doc.createTextNode(planlagtAntallPerUndergruppe_kode_value[i]));
map1.appendChild(kode);
}
}
//end planlagtAntallPerUndergruppe
// Write the content into XML file
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File("E:/utils/students-new.xml"));
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
// Beautify the format of the resulted XML
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
transformer.transform(source, result);
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
pass collected arrays into Write2XMLfile method as parameters
public void Write2XMLfile(String[] planlagtAntallPerUndergruppe_antall_value, String[] planlagtAntallPerUndergruppe_kode_value) {
try {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.newDocument();
Element rootElement = doc.createElement("map");
doc.appendChild(rootElement);
Element mainString = doc.createElement("string");
mainString.setAttribute("key", "ankomstDato");
rootElement.appendChild(mainString).setTextContent("2020-08-20");
Element array = doc.createElement("array");
array.setAttribute("key", "planlagtAntallPerUndergruppe");
rootElement.appendChild(array);
if(planlagtAntallPerUndergruppe_antall_value.length>0){
for (int i = 0; i < planlagtAntallPerUndergruppe_antall_value.length; i++) {
Element map = doc.createElement("map");
array.appendChild(map);
Element number = doc.createElement("number");
number.setAttribute("key", "antall");
map.appendChild(number).setTextContent(planlagtAntallPerUndergruppe_antall_value[i]);
Element string = doc.createElement("string");
string.setAttribute("key", "kode");
map.appendChild(string).setTextContent(planlagtAntallPerUndergruppe_kode_value[i]);
}
}
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
DOMSource source = new DOMSource(doc);
StreamResult output = new StreamResult(new File("output.xml"));
transformer.transform(source, output);
} catch (Exception e) {
e.printStackTrace();
}
}
output.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<map>
<string key="ankomstDato">2020-08-20</string>
<array key="planlagtAntallPerUndergruppe">
<map>
<number key="antall">67</number>
<string key="kode">SLAKTEGRIS</string>
</map>
<map>
<number key="antall">4</number>
<string key="kode">UNGSAU</string>
</map>
</array>
</map>
I have been trying to modify values of more than one XML tag in java. So far I am able to get the values of the two nodes that I want to modify but while setting up values it always overrides the first one with the second one.
XML
<driver>
<BirthDate>1977-07-18</BirthDate>
<Age>40</Age>
<Gender>M</Gender>
<PrimaryResidence>OwnCondo</PrimaryResidence>
</driver>
I am trying to change Gender and PrimaryResidence tags.
Code
// Modifies multiple XML nodes
public static String changeCoreDiscountType(String reqXML) {
Document document = null;
String updatedXML = null;
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(reqXML));
document = builder.parse(is);
XPath xPath = XPathFactory.newInstance().newXPath();
XPathExpression expression = xPath.compile("/driver/Gender | /driver/PrimaryResidence");
NodeList nodeList = (NodeList) expression.evaluate(document,XPathConstants.NODESET);
for(int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
node.setTextContent("F");
node.setTextContent("OwnCondo");
String value = node.getTextContent();
}
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(new StringWriter());
transformer.transform(source, result);
updatedXML = result.getWriter().toString();
} catch (Exception ex) {
ex.printStackTrace();
}
return updatedXML;
}
Any help is appreciated.
You need to check you are updating the correct node first, e.g.
for(int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
if(node.getNodeName() == "Gender")
node.setTextContent("F");
if(node.getNodeName() == "PrimaryResidence")
node.setTextContent("OwnCondo");
}
Full Demo
I am trying to update multiple nodes in xml using nodelist. I am able to do it but i don't think my code is efficient. For updating two nodes I am repeating my code twice. I dont know how to loop it. I tried it from for loop, or tried making it an arraylist and everything but it is not working at all.
Here is my code:
String expressionDisclosure = "/DOCUMENT/ishobject/ishfields/ishfield[#name='FHPIDISCLOSURELEVEL']";
String expressionLanguage = "/DOCUMENT/ishobject/ishfields/ishfield[#name='DOC-LANGUAGE']";
String key = "";
String value = "";
try {
DocumentBuilderFactory documentbuilderfactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentbuilder = documentbuilderfactory.newDocumentBuilder();
Document doc = documentbuilder.parse(filepath);
XPath xPath = XPathFactory.newInstance().newXPath();
Node updateNode = null;
NodeList nodelistLanguage = (NodeList) xPath.evaluate(expressionLanguage,
doc.getDocumentElement(), XPathConstants.NODESET);
NodeList nodelistDisclosure = (NodeList) xPath.evaluate(expressionDisclosure,
doc.getDocumentElement(), XPathConstants.NODESET);
key = nodelistLanguage.item(0).getTextContent();
if (key != null) {
value = getHashmap().get(key);
updateNode = nodelistLanguage.item(0);
updateNode.setTextContent(value);
}
key = nodelistDisclosure.item(0).getTextContent();
if (key != null) {
value = getHashmap().get(key);
updateNode = nodelistDisclosure.item(0);
updateNode.setTextContent(value);
}
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult stream = new StreamResult(new File(filepath));
transformer.transform(source, stream);
} catch (Exception ex) {
ex.printStackTrace();
}
I am updating the node twice. Is this the proper way to do or can it be more efficient?
I have an XML document which has null values in its Value tag (something similar to below)
<ns2:Attribute Name="Store" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
<ns2:AttributeValue/>
</ns2:Attribute>
Now, I have to write Java code to modify the values as below.
<ns2:Attribute Name="Store" NameFormat="urn:oasis:names:tc:SAML:2.0:attrname-format:uri">
<ns2:AttributeValue>ABCDEF</ns2:AttributeValue>
</ns2:Attribute>
I am using DOM parser to parse the XML. I am able to delete the null tag for " but not able to add new values. I am not even sure if we have a direct way to replace or add the values.
Below is the code I am using to remove the child("")
Node aNode = nodeList.item(i);
eElement = (Element) aNode;
eElement.removeChild(eElement.getFirstChild().getNextSibling());
Thanks in advance
Just add data through setTextContent to the element. Sample code is as below:
public static void main(String[] args) throws IOException, SAXException, ParserConfigurationException, TransformerException {
String xml = "<ns2:Attribute Name=\"Store\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\"><ns2:AttributeValue/></ns2:Attribute>";
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(new ByteArrayInputStream(xml.getBytes()));
doc.getDocumentElement().normalize();
NodeList nList = doc.getElementsByTagName("ns2:AttributeValue");
for (int i=0;i<nList.getLength();i++) {
Element elem = (Element)nList.item(i);
elem.setTextContent("Content"+i);
}
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(System.out);
transformer.transform(source, result);
System.out.println(nList.getLength());
}
xml file content
<distributionChannels><distributionChannel type="Wap" id="1"><contentChannelRefs>
<contentChannelRef id="2"><categories><category
link="http://images/11.gif" id="1"><names><name lang="de">Top Downloads</name><name
lang="ww">Tops</name></names></category></categories></contentChannelRef>
</contentChannelRefs></distributionChannel>
</distributionChannels>
how do i delete the unwanted content which i am reading from an xml file and the output should look as shown below:
<category link="http://images/11.gif" id="1"><names><name lang="de">Top Downloads</name><name lang="ww">Tops</name></names></category>
Reliable solution - use an XML parser. Simple solution is
s = s.substring(s.indexOf("<categories>"), s.indexOf("</categories>") + 13);
if you want to read categories one by one use regex
Matcher m = Pattern.compile("<category.*?>.*?</category>").matcher(xml);
for(int i = 0; m.find(); i++) {
System.out.println(m.group());
}
Pattern matching with XML is not recommended. Use a parser to get your nodes and the manage them accordingly. If you are interested in printing them I have included code to print the nodes.
public static void main(String[] args)
throws ParserConfigurationException, SAXException,
IOException, XPathExpressionException {
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setNamespaceAware(true);
DocumentBuilder builder = domFactory.newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(s)));
XPathFactory factory = XPathFactory.newInstance();
XPath xpath = factory.newXPath();
XPathExpression expr
= xpath.compile("//categories//category");
Object result = expr.evaluate(doc, XPathConstants.NODESET);
NodeList nodes = (NodeList) result;
//This is where you are printing things. You can handle differently if
//you would like.
for (int i = 0; i < nodes.getLength(); i++) {
System.out.println(nodeToString(nodes.item(i)));
}
}
private static String nodeToString(Node node) {
StringWriter sw = new StringWriter();
try {
Transformer t = TransformerFactory.newInstance().newTransformer();
t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
t.setOutputProperty(OutputKeys.INDENT, "yes");
t.transform(new DOMSource(node), new StreamResult(sw));
} catch (TransformerException te) {
te.printStackTrace();
}
return sw.toString();
}