Fetching the XML without changing the order of the attributes - java

I am trying to fetch the xml from the file, but while fetching the order of the attributes are changing
I know it will not matter but in my case it does, as I am hashing the document
I am trying the below code but it is ordering the attributes in an alphabetical manner
File fXmlFile = new File("C:\\Users\\Desktop\\abc.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder;
dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
DOMSource domSource = new DOMSource(doc);
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.transform(domSource, result);
String xml=writer.toString();
this is the xml that I am trying to read
in the variable xml, I am getting the xml with the attributes sorted in an alphabetical order

Attribute order has no meaning in XML, and tools that process XML are at liberty to change the order.
When you are comparing documents for equivalence (which you appear to be doing) then you should use comparison and hash functions that do not depend on the order of attributes.

Related

TransformerFactory dropping Namespace on specific tag

I am parsing an XML using DocumentBuilderFactory and trying to store the same into another XML using TransformerFactory but in the process namespace of only one of the element getting removed while others were fine. Below is the java code.
DocumentBuilderFactory df;
df=DocumentBuilderFactory.new
Instance();
df.setNamespaceAware(true);
DocumentBuilder db=df.new
DocumentBuilder();
Document doc=db.parse("test.xml");
doc.setXmlStandalone(true);
TranformerFactory
tf=TransformerFactory.newInstance();
Transformer t=tf.new Transformer();
DOMSource s=new DOMSource(doc);
StreamResult sr=new StreamResult(new
File("output.xml");
tf.transform(s,sr);

Delete an xml Element and copy the same element in a new xml -- in java

I am having some problem in deleting and copying the same xml element. The problem is I have 2 xml files and after comparing both I want to delete the element(s) those are only in file1 and at the same copy I want to copy these elements in a newly generated xml. I can delete the elements but I am not able to copy them in another xml file.
Here is the code:
for (Map.Entry<String, Element> entry : Map1.entrySet()) {
String key = entry.getKey();
if (!Map2.containsKey(key)) {
Map1.remove(key);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dbf.newDocumentBuilder();
Document doc= builder.newDocument();
Element rootElement =
doc.createElementNS("", "missing");
doc.appendChild(rootElement);
//here i want to copy the deleted element in new xml file.
//rootElement.appendChild(Map1.get(key));
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(doc);
StreamResult newXml = new StreamResult(new File("C:/user/desktop/Output.xml"));
transformer.transform(source, newXml);
}
}
Shift the part where Map1.remove(key); to the end of the code. Your rootElement.appendChild(Map1.get(key)) would not work because key is no longer in Map1 after you removed it.

Create namespace in dom element issue

Im trying to create XML document with DOM APi's and when i use the following code I got the
expect result
Element rootTreeNode = document.createElementNS("http://schemas.microsoft.com/ado/2007","ex" + ":Ex")
this is the output with tags in output console
ex:Ex Version="1.0" xmlns:ex="http://schemas.microsoft.com/ado/2007"/
Now I want to add to this element the following
**xmlns:gp**="http://www.pst.com/Protocols/Data/Generic"
and I dont succeed with the xmlns:gp i have tried to use
the like the following
rootTreeNode.setAttributeNS("xmlns" ,"gp","http://www.pst.com/Protocols/Data/Generic")
and i have got it like the folloing
**xmlns:ns0="xmlns"** **ns0:gp**="http://www.pst.com/Protocols/Data/Generic"
and if put null in the first parameter
rootTreeNode.setAttributeNS(null ,"gp","http://www.pst.com/Protocols/Data/Generic")
I get just gp with the URL without the xmlns .
what am i doing wrong here ?
Thanks!!!
Complete test:
DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
Document doc = docBuilder.newDocument();
Element root = doc.createElementNS("http://schemas.microsoft.com/ado/2007","ex" + ":Ex");
root.setAttributeNS("http://www.w3.org/2000/xmlns/" ,"xmlns:gp","http://www.pst.com/Protocols/Data/Generic");
doc.appendChild(root);
TransformerFactory transfac = TransformerFactory.newInstance();
Transformer trans = transfac.newTransformer();
trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
trans.setOutputProperty(OutputKeys.INDENT, "yes");
StringWriter sw = new StringWriter();
StreamResult result = new StreamResult(sw);
DOMSource source = new DOMSource(doc);
trans.transform(source, result);
String xmlString = sw.toString();
System.out.println("Xml:\n\n" + xmlString);

How to remove standalone attribute declaration in xml document?

Im am currently creating an xml using Java and then I transform it into a String. The xml declaration is as follows:
DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
Document doc = docBuilder.newDocument();
doc.setXmlVersion("1.0");
For transforming the document into String, I include the following declaration:
TransformerFactory transfac = TransformerFactory.newInstance();
Transformer trans = transfac.newTransformer();
trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
trans.setOutputProperty(OutputKeys.VERSION, "1.0");
trans.setOutputProperty(OutputKeys.ENCODING,"UTF-8");
trans.setOutputProperty(OutputKeys.INDENT, "yes");
And then I do the transformation:
StringWriter sw = new StringWriter();
StreamResult result = new StreamResult(sw);
DOMSource source = new DOMSource(doc);
trans.transform(source, result);
String xmlString = sw.toString();
The problem is that in the XML Declaration attributes, the standalone attribute is included and I don't want that, but I want the version and encoding attributes to appear:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
Is there any property where that could be specified?
From what I've read you can do this by calling the below method on Document before creating the DOMSource:
doc.setXmlStandalone(true); //before creating the DOMSource
If you set it false you cannot control it to appear or not. So setXmlStandalone(true) on Document. In transformer if you want an output use OutputKeys with whatever "yes" or "no" you need. If you setXmlStandalone(false) on Document your output will be always standalone="no" no matter what you set (if you set) in Transformer.
Read the thread in this forum

how to append tags in xml in android? and how save that xml file?

i would like to append a new tag with some attributes with those values in to xml file and save that xml file through my application.i have written a method for append a new tag as child to xml file which is available in sdcard of android emulator.the following method for append a new tag as follows
public void appendTag(){
try{
DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document doc = docBuilder.parse (new File("/sdcard/sample.xml"));
Node node = doc.getElementsByTagName("earth").item(0);
//append a new node to earth
Element newelmnt = doc.createElement("new");
newelmnt.appendChild(doc.createTextNode("this is a text"));
node.appendChild(newelmnt);
}
catch (Exception e) {
e.printStackTrace();
}
}
after execution of this method i can't able to find a new tag in xml file.
could please any one help on how to append new tag as child in xml file and how save the modification?
if i uses TransformerFactory i am getting error as
ERROR/AndroidRuntime(13479): java.lang.VerifyError: com.sample.xmlapp.DOMClass
i have used as follows
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File("/sdcard/sample.xml"));
transformer.transform(source, result);
Your in memory document will be changed, but you will need to write it to a file again.
Try adding this for writing the document to the file again:
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File("/sdcard/sample.xml"));
transformer.transform(source, result);

Categories