I would like to delete a child from an XML file and of course save the file after the modification.
Here is my XML file:
<?xml version="1.0" encoding="UTF-8" standalone="no"?><Customers>
<Marker>
<title>ABB EMEA</title>
</Marker>
<Marker>
<title>AllScripts</title>
</Marker>
<Marker>
<title>ARRIS (Motorola)</title>
</Marker>
<Marker>
<title>ARRIS (RWC)</title>
</Marker>
<Marker>
<title>BHS</title>
<site_location>Weinhammer, Hofhalde, Konstanz, Germany</site_location>
</Marker>
<Marker>
<title>Durst</title>
<site_location>Brixen, Italy</site_location>
</Marker>
<Marker>
<title>EMEA DEMO</title>
<site_location>AWS could</site_location>
</Marker>
<Marker>
<title>Harris</title>
</Marker>
</Customers>
I would like to complete remove the child that has the 'title' - 'Durst'.
Here is my code:
public static void Rebuild_Cords_XML (File ff)
{
try
{
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(ff);
NodeList nodes = doc.getElementsByTagName("Marker");
int x=0;
for(int i=0;i<nodes.getLength();i++)
{
Node nNode = nodes.item(i);
if (nNode.getNodeType() == Node.ELEMENT_NODE)
{
Element eElement = (Element) nNode;
if(eElement.getElementsByTagName("title").item(0).getTextContent().equals(("Durst")));
{
}
}
}
// write the DOM object to the file
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer=null;
try {
transformer = transformerFactory.newTransformer();
} catch (TransformerConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
DOMSource domSource = new DOMSource(doc);
StreamResult streamResult = new StreamResult(ff);
try {
transformer.transform(domSource, streamResult);
} catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
catch (ParserConfigurationException | IOException | SAXException e) {
;}
}
As you can see I am able to detect it manually, but I do not know who to remove it, trying to access a parent node deletes other 'Marker' children but not the required one.
Please assist.
I'm not entirely sure what you're trying to delete, so here's both ways.
This will remove the entire marker which contains the title durst:
for (int i = 0; i < nodes.getLength(); i++) {
Node nNode = nodes.item(i);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
if (eElement.getElementsByTagName("title").item(0).getTextContent().equals(("Durst"))) {
nNode.getParentNode().removeChild(nNode);
}
}
}
This will remove just the title tag in the marker:
for (int i = 0; i < nodes.getLength(); i++) {
Node nNode = nodes.item(i);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
if (eElement.getElementsByTagName("title").item(0).getTextContent().equals(("Durst"))) {
nNode.removeChild(eElement.getElementsByTagName("title").item(0));
}
}
Related
I have a xml with following scheme structure
<test>
<testcase classname="TestsQuarantine.CreateUsers" name="Administrator"/>
<testcase classname="TestsQuarantine.Login" name="documentMailQuarantine"/>
<testcase classname="TestsClerk.CreateUsers" name="John"/>
</test>
I need to reorganize it to
<test>
<testsuite name="Quarantine">
<testcase classname="TestsQuarantine.CreateUsers" name="Administrator"/>
<testcase classname="TestsQuarantine.Login" name="documentMailQuarantine"/>
</testsuite>
<testsuite name="Clerk">
<testcase classname="TestsClerk.CreateUsers" name="John"/>
</testsuite>
</test>
At this point I'm reading the file to NodeList, iterate through it, create new root and try to switch it with original to achieve the structure that I need but I get following error
HIERARCHY_REQUEST_ERR: An attempt was made to insert a node where it
is not permitted.
happening in line that performs switch of roots and I'm out of ideas why it is so.. Here is my code:
File file = new File(fullPath);
List<Element> clerk = null,
quara = null,
misc = null;
try {
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
Document doc = builder.parse(file);
NodeList nodes = doc.getElementsByTagName("test");
Element root = doc.getDocumentElement(),
newRoot = doc.createElement("test");
clerk = new ArrayList<Element>();
quara = new ArrayList<Element>();
misc = new ArrayList<Element>();
for(int i=0; i < nodes.getLength(); i++) {
Element node = (Element) nodes.item(i);
if(node.getAttribute("classname").contains("Clerk")) {
clerk.add(node);
} else if(node.getAttribute("classname").contains("Quarantine")) {
quara.add(node);
} else {
misc.add(node);
}
}
if(clerk.isEmpty() == false) {
Element clerkSuite = doc.createElement("testsuite");
clerkSuite.setAttribute("name", "Clerk");
for(Element el : clerk) {
clerkSuite.appendChild(el);
}
newRoot.appendChild(clerkSuite);
}
if(quara.isEmpty() == false) {
Element quaraSuite = doc.createElement("testsuite");
quaraSuite.setAttribute("name", "Quarantine");
for(Element el : quara) {
quaraSuite.appendChild(el);
}
newRoot.appendChild(quaraSuite);
}
if(misc.isEmpty() == false) {
Element miscSuite = doc.createElement("testsuite");
miscSuite.setAttribute("name", "Miscellaneous");
for(Element el : misc) {
miscSuite.appendChild(el);
}
newRoot.appendChild(miscSuite);
}
root.getParentNode().replaceChild(newRoot, root);
DOMSource original = new DOMSource(doc);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
StreamResult overritten = new StreamResult(fullPath);
transformer.transform(original, overritten);
} catch (Exception e) {
e.printStackTrace();
}
What do I have to change to make it work?
Your iteration over testcase nodes is incorrect. I changed that fragment to below one and Your code is working:
Node testNode = doc.getDocumentElement();
NodeList testCases= testNode.getChildNodes();
for(int i=0; i < testCases.getLength(); i++) {
Node n = testCases.item(i);
if (!(n instanceof Text)) {
Element testCase = (Element) n;
if (testCase.getAttribute("classname").contains("Clerk")) {
clerk.add(testCase);
} else if (testCase.getAttribute("classname").contains("Quarantine")) {
quara.add(testCase);
} else {
misc.add(testCase);
}
}
}
I am receiving a xml payload from a web service call and it is assigned in a String. This xml has 10 elements and I need to change the value of logtime to whatever I want. Since this is a String, is there a way to change any of the element's value.
This is my first java code please let me know if you need more explanation.
code
String xml = dto.getAuditTrail();
Xml
I want to know how can I suppose change the time value of logtime to another format, since this entire xml is a String?
Please help because I am new to it.
Thanks
You need to parse your String in order to obtain a Document object which you can read by tag.
Here you can find how to parse your string, then with Document object you're able to read specific tag:
public void readDocument(Document doc) {
try{
NodeList nList = doc.getElementsByTagName("Event");
System.out.println("----------------------------");
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
System.out.println("\nCurrent Element :" + nNode.getNodeName());
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
System.out.println("LogTime : " + eElement.getElementsByTagName("logTime").item(0).getTextContent());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
Source here
This is basic way for xml reading, but you can directly edit the xml too:
public void editDocument() {
try{
NodeList nList = doc.getElementsByTagName("Event");
System.out.println("----------------------------");
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
System.out.println("\nCurrent Element :" + nNode.getNodeName());
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
Node logTimeNode = eElement.getElementsByTagName("logTime").item(0);
String logTimeString = logTimeNode.getTextContent();
// Do some stuff with logTimeString
logTimeNode.setTextContent(logTimeString);
}
}
// write the content into xml file
String filepath = "/path/to/file.xml";
TransformerFactory transformerFactory = TransformerFactory
.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File(filepath));
transformer.transform(source, result);
} catch (Exception e) {
e.printStackTrace();
}
}
class HtmlTagmodifier {
public String htmlFileWriter(String cfile, String Listname, String Nodename, String nodevalue) {
try {
File fhtmlFile = new File(cfile);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fhtmlFile);
doc.getDocumentElement().normalize();
NodeList nList = doc.getElementsByTagName(Listname);
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
eElement.getElementsByTagName(Nodename).item(0).setTextContent(nodevalue);
}
}
Source source = new DOMSource(doc);
Result htmlresult = new StreamResult(fhtmlFile);
Transformer xformer = TransformerFactory.newInstance().newTransformer();
xformer.transform(source, htmlresult);
result2 = "Success";
} catch (Exception e) {
e.printStackTrace();
log.error("Error in html file writing " + e.toString());
JOptionPane.showMessageDialog(null, "Error in html file writing " + e.toString());
result2 = "Failed";
}
return result2;
}
public static void main(String[] args) {
HtmlTagmodifier.htmlfilewriter("test.html", "details", "customername", "customernamexxxxxx");
}
}
Output:
when i use this method to modify the tag values of html,tag name is changed successfully but meta data tag is added again in the html
please give me suggestion.
<report id="oleg">
<title>olegitimerade rapport</title>
<id_email>joch1</id_email>
<id_email>kang15</id_email>
</report>
I am using the following code with the DOM XML parser to extract the above list an xml file.
String tag = "report";
String[] elementTags = new String[] {"title", "id_email"};
NodeList nList = this.doc.getElementsByTagName(tag);
try{
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
HashMap<String, String> attribute = new HashMap<String, String>();
Element eElement = (Element) nNode;
if(eElement.hasAttribute("id")){
String id = eElement.getAttribute("id");
attribute.put("id", id);
for (String elementTag : elementTags){
try{
int index=0;
while(null!=eElement.getElementsByTagName(elementTag).item(index).getTextContent()){
attribute.put(elementTag, eElement.getElementsByTagName(elementTag).item(index).getTextContent());
index++;
}
}catch (Exception e){
//System.out.println("id : "+id+" - Attribute element '"+ elementTag+ "' not found in XML! ["+this.xmlFile+"]");
}
}
attributes.add(attribute);
}
}
}
}catch (Exception e) {
e.printStackTrace();
}
The problem is when I get the multiple tags....I cannot extract the 2nd ID (kang15).
Clearly the while loop is incorrect, so I need a little help here fixing the issue.
while(null!=eElement.getElementsByTagName(elementTag).item(index).getTextContent()){
attribute.put(elementTag, eElement.getElementsByTagName(elementTag).item(index).getTextContent());
index++;
}
Consider using XPath for this:
XPath xpath = XPathFactory
.newInstance()
.newXPath();
Element report = (Element) xpath.evaluate("//report", doc, XPathConstants.NODE);
String id = xpath.evaluate("#id", report);
String title = xpath.evaluate("title", report);
NodeList emails = (NodeList)
xpath.evaluate("id_email/text()", report, XPathConstants.NODESET);
System.out.println(id);
System.out.println(title);
for(int i=0; i<emails.getLength(); i++) {
System.out.println(emails.item(i).getTextContent());
}
I have an XML:
<?xml version="1.0" encoding="UTF-8"?>
<songs>
<song>
<title>Gracious</title>
<artist>Ben Howard</artist>
<genre>Singer/Songwriter</genre>
</song>
<song>
<title>Only Love</title>
<artist>Ben Howard</artist>
<genre>Singer/Songwriter</genre>
</song>
<song>
<title>Bad Blood</title>
<artist>Bastille</artist>
<genre>N/A</genre>
</song>
<song>
<title>Keep Your Head Up</title>
<artist>Ben Howard</artist>
<genre>Singer/Songwriter</genre>
</song>
<song>
<title>Intro</title>
<artist>Alt-J</artist>
<genre>Alternative</genre>
</song>
</songs>
and my Java code is:
public static void deleteSong(Song song) {
String songTitle = song.getTitle();
String songArtist = song.getArtist();
String songGenre = song.getGenre();
try {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
File file = new File("songs.xml");
Document doc = db.parse(file);
NodeList songList = doc.getElementsByTagName("song");
if (songList != null && songList.getLength() > 0) {
for (int i = 0; i < songList.getLength(); i++) {
Node node = songList.item(i);
Element e = (Element) node;
NodeList nodeList = e.getElementsByTagName("title");
String title = nodeList.item(0).getChildNodes().item(0)
.getNodeValue();
nodeList = e.getElementsByTagName("artist");
String artist = nodeList.item(0).getChildNodes().item(0)
.getNodeValue();
nodeList = e.getElementsByTagName("genre");
String genre = nodeList.item(0).getChildNodes().item(0)
.getNodeValue();
System.out.println(title + " Title");
System.out.println(songTitle + " SongTitle");
if (title.equals(songTitle)) {
if (artist.equals(songArtist)) {
if (genre.equals(songGenre)) {
doc.getFirstChild().removeChild(node);
}
}
}
}
}
MainDisplay.main(null);
} catch (Exception e) {
System.out.println(e);
}
}
The song to be deleted is passed into the method and then compared to the songs in the xml file. However, if the song matches a song in the xml, it isn't deleted? No exceptions come up.
You need to remove relevant node, in you code you are removing node of firstchild which seems to be incorrect.
And write back your changes to the file.
if (title.equals(songTitle) && artist.equals(songArtist) && genre.equals(songGenre) ) {
node.getParentNode().removeChild(node);
}
// write back to 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);
From what I see, you are only reading the documents. At some point, you will have to flush the changes back to the XML file.