Stop escaping special characters when saving to XML with DOM - java

Is there any way to prevent Java from escaping the special characters when writing to XML using DOM? I can’t change the format of the XML so I can’t save them in CDATA tags.
I’m trying to save HTML inside a XML file using DOM. Currently it is escaping the special characters so <p> is being saved as <p>.
public void updateXML(Document doc) throws XPathExpressionException{
Node aNode = getXMLNode("//PRECISSCHE.HTM/html/body", doc);
removeChilds(aNode);
aNode.setTextContent(saved_precis_Scheme);
}
It's outputting as:
<PRECISSCHE.HTM>
<html>
<body><p>schemeName</p></body>
</html>
</PRECISSCHE>
but I need:
<PRECISSCHE.HTM>
<html>
<body><p>schemeName</p></body>
</html>
</PRECISSCHE>
Here is my code to create the doc object:
//pull data and write to XML
public void updateXML(String path) throws XPathExpressionException{
try {
String filepath = path;
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
docFactory.setIgnoringElementContentWhitespace(true);
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(filepath);
Tab_Client.updateClientXML(doc);
if(!polType.equals("Household")){
Tab_Vehicle.updateVehicleXML(doc);
Tab_PCClaimsConv.updateXML(doc);
Tab_precis.updateXML(doc);
}
if(polType.equals("Household")){
Tab_PropertyDetails.updatePropertyDetailsXML(doc);
Tab_HCsumInsured.updateXML(doc);
Tab_Contents.updateXML(doc);
Tab_HCClaims.updateXML(doc);
}
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 (ParserConfigurationException pce) {
pce.printStackTrace();
} catch (TransformerException tfe) {
tfe.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
} catch (SAXException sae) {
sae.printStackTrace();
}
}

You can that do
stringString.replaceAll("<","<").replaceAll(">",">")
before you output the data

Related

Premature end of file error. How to resolve? XML

I've been reading over this SAXParseException error for a while and trying to resolve it but to no success.
[Fatal Error] schedule.xml:1:1: Premature end of file.
org.xml.sax.SAXParseException; systemId: file:/U:/schedule.xml; lineNumber: 1; columnNumber: 1; Premature end of file.
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(Unknown Source)
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(Unknown Source)
at javax.xml.parsers.DocumentBuilder.parse(Unknown Source)
at package.DOMclass.importDocument(DOMclass.java:681) //<---.parse(new File(fileToImport));
...
I've read how it could be the stream being used is empty (or xml file being read is empty), as well as it can't be reused? Also, the problem of reading and writing back to the same file. Here's a link that explains it but I still don't understand.
Also, another possibility could be that my xml is malformed/not correct but I've looked over it and it's fine, the tags are good and I've encoded it in UTF-8 (without BOM) in Notepad++ since some posts have said there might be hidden whitespace before the xml declaration but again, no success.
This is my reading in code
public TestClass(){
Node root = DOMclass.importDocument("U:\\schedule.xml");
... read nodes, attribute values, etc..
}
public static Document importDocument(String fileToImport)
{
Document document = null;
try
{
document = DocumentBuilderFactory.newInstance().newDocumentBuilder()
.parse(new File(fileToImport)); //<--- where the error is at
//Do I need a Reader here? to close?
}
catch(SAXException saxe)
{
saxe.printStackTrace();
}
catch(IOException ioe)
{
ioe.printStackTrace();
}
catch(ParserConfigurationException pce)
{
pce.printStackTrace();
}
return document;
}
This is my writing out.
public static void addNode(String name, String lastName,...){
String filepath = "U;\\schedule.xml";
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder;
try {
docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(filepath);
...
... make/traverse xml nodes, elements, appending
...
}
DOMUtils.exportDocument(doc, filepath);
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void exportDocument(Document documentToExport, String fileName)
{
Transformer transformer = null;
DOMSource domSource = null;
StreamResult streamResult = null;
try
{
BufferedWriter out = new BufferedWriter(new FileWriter(fileName));
transformer = TransformerFactory.newInstance().newTransformer();
domSource = new DOMSource(documentToExport);
streamResult = new StreamResult(out);
System.out.println("\nStream Result: " + streamResult);
transformer.transform(domSource, streamResult);
out.close();
}
catch (IOException e)
{
e.printStackTrace();
}
catch(TransformerException e)
{
e.printStackTrace();
}
finally
{
transformer = null;
domSource = null;
streamResult = null;
}
}
}
Any thoughts? Thank you.

Xml Document Object returns null, but not always

I have been recently trying to read from a xml file. I believe I am parsing correctly but it returns null,however not always.I received the input that I want 1 out of 100 executions, with no drastic changes on code.This is the code that receives the file path of xml file(also file in code)
public Document getXmlDoc(String filePath) {
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
Document doc = null;
try {
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
doc = dBuilder.parse(new File(filePath));
doc.getDocumentElement().normalize();
System.out.println(doc.getDocumentElement().getNodeValue());//null
System.out.println(doc.getDocumentElement().getChildNodes().item(1));//null
System.out.println(doc.getDocumentElement().getLastChild().getAttributes().getNamedItem("id"));//not null and correct
System.out.println(doc.getDocumentElement().getElementsByTagName("entry").item(1));//null
} catch (ParserConfigurationException e) {
e.printStackTrace();//pipe these
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return doc;
}
Also I call my method here and turn my node to string
NodeList nList = getXmlDoc(newFilePath).getElementsByTagName("entry");
System.out.println(nodeToString(nList.item(i)));
Where nList is a node list and nodeToString method is like this:
private String nodeToString(Node node){
StringWriter sw = new StringWriter();
try{
Transformer t = TransformerFactory.newInstance().newTransformer();
t.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION,"yes");
t.transform(new DOMSource(node),new StreamResult(sw));
} catch (TransformerException e) {
e.printStackTrace();
}
return sw.toString();
}

Java produce version "1.1" in XML header with transformer

I want to produce xml files with 1.1 as version in the header, since i get SaxparserExceptions when parsing my xml-files with version 1.0:
"Character reference "&#3" is an invalid XML character".
When I manually change the header, i don't get any errors. Changing the version via outputkeys doesn't seem to work. The file has still the wrong header:
"<?xml version="1.0" encoding="UTF-8" standalone="no"?>"
example code:
try {
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.newDocument();
TransformerFactory transformerFactory = TransformerFactory
.newInstance();
Transformer transformer = transformerFactory
.newTransformer();
transformer.setOutputProperty(
OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperty(OutputKeys.VERSION, "1.1");
transformer
.setOutputProperty(
"{http://xml.apache.org/xslt}indent-amount",
"2");
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(
"processed_.xml");
transformer.transform(source, result);
} catch (TransformerConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Xalan probably doesn't support XML 1.1. Try Saxon instead.
doc.setXmlVersion("1.1"); works for me.

XML output Print in Browser using JAVA

Here I try to access two third party API.
I got two xml response, I merge them in one single file and store it in local system.
If i print the output in console I got the output in xml format, but I want to print it in the browser.
My solution won't work please help me.
Here's my code:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/xml");
PrintWriter out=response.getWriter();
String btn1=request.getParameter("btn1");
String btn2=request.getParameter("btn2");
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
domFactory.setIgnoringComments(true);
DocumentBuilder builder = null;
try {
builder = domFactory.newDocumentBuilder();
} catch (ParserConfigurationException e2) {
e2.printStackTrace();
}
Document doc = null;
try {
doc = builder.parse(new URL("valid url in my program").openStream());
response.setContentType("text/xml");
Object con=doc.getDoctype();
} catch (SAXException e2) {
e2.printStackTrace();
}
Document doc1 = null;
try {
doc1 = builder.parse(new URL(valid url).openStream());
} catch (SAXException e2) {
e2.printStackTrace();
}
NodeList nodes = doc.getElementsByTagName("events");
NodeList node1=doc.getElementsByTagName("events");
Element root=doc.getDocumentElement();
Element root1 = doc.createElement("ObjectId");
doc.getDocumentElement().appendChild(root1);
root.getElementsByTagName("ObjectId").item(0).setTextContent("1");
node1.item(0).getParentNode().insertBefore(root1,node1.item(0));
NodeList nodes1 = doc1.getElementsByTagName("events");
NodeList node2=doc1.getElementsByTagName("event");
Element root2=doc1.getDocumentElement();
Element root3= doc1.createElement("ObjectId");
doc1.getDocumentElement().appendChild(root3);
root2.getElementsByTagName("ObjectId").item(0).setTextContent("2");
node2.item(0).getParentNode().insertBefore(root3,node2.item(0));
for(int i=0;i<nodes1.getLength();i=i+1){
Node n= (Node) doc.importNode(nodes1.item(i), true);
nodes.item(i).getParentNode().appendChild(n);
}
Transformer transformer = null;
try {
transformer = TransformerFactory.newInstance().newTransformer();
} catch (TransformerConfigurationException e1) {
e1.printStackTrace();
} catch (TransformerFactoryConfigurationError e1) {
e1.printStackTrace();
}
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
StreamResult result = new StreamResult(new StringWriter());
DOMSource source = new DOMSource(doc);
try {
transformer.transform(source,result);
} catch (TransformerException e) {
e.printStackTrace();
}
Writer output = null;
output = new BufferedWriter(new FileWriter("merge.xml"));
String xmlout = result.getWriter().toString();
output.write(xmlout);
response.setContentType("text/xml");
out.write(xmlout);
//out.println(xmlout);
//System.out.println(xmlout);
//I tried many ways but
//it will not print to the browser in xml the format
}
A point of note; you're setting the ContentType three times. It only needs setting once?
You don't appear to be returning the response, but I presume some other part of your program is handling that.
EDITED: the other answer that was here disappeared.
Going to need more information to work out what is going wrong. Please bear in mind that System.out.println() calls will not show up in the browser as they're console-specific.

Android data store in XML files

In my android application I am using an xml file to store some history information within the application.
Following is the code I use to enter a new record to the file.
String filename = "file.xml";
File xmlFilePath = new File("/data/data/com.testproject/files/" + filename);
private void addNewRecordToFile(History history)
{
try
{
DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
Document doc = docBuilder.parse(xmlFilePath);
Element rootEle = doc.getDocumentElement();
Element historyElement = doc.createElement("History");
rootEle.appendChild(historyElement);
Element customerEle = doc.createElement("customer");
customerEle.appendChild(doc.createTextNode(history.getCustomer()));
historyElement.appendChild(customerEle);
Element productEle = doc.createElement("product");
productEle.appendChild(doc.createTextNode(history.getProduct()));
historyElement.appendChild(productEle);
//-------->
DOMSource source = new DOMSource(doc);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
StreamResult result = new StreamResult(xmlFilePath);
transformer.transform(source, result);
}
catch (ParserConfigurationException e)
{
Log.v("State", "ParserConfigurationException" + e.getMessage());
}
catch (SAXException e)
{
Log.v("State", "SAXException" + e.getMessage());
}
catch (IOException e)
{
Log.v("State", "IOException" + e.getMessage());
}
catch (TransformerConfigurationException e) {
e.printStackTrace();
}
catch (TransformerFactoryConfigurationError e) {
e.printStackTrace();
}
catch (TransformerException e) {
e.printStackTrace();
}
}
XML file format
<?xml version="1.0" encoding="UTF-8"?>
<HistoryList>
<History>
<customer>Gordon Brown Ltd</customer>
<product>Imac</product>
</History>
<History>
<customer>GG Martin and Sons</customer>
<product>Sony Vaio</product>
</History>
<History>
<customer>PR Thomas Ltd</customer>
<product>Acer Laptop</product>
</History>
</HistoryList>
So using this code I can successfully add a new rocord to the file. But My minimum target version in android shoud be API level 4. This code works well with API Level 8 and above.
DOMSource, TransformerFactory classes are not available in android API levels under 8. So All the things before the comment //--------> works in APIs below 8.
Does anyone know any way that I can write to the xml file without using Transformer APIs. Thanks in advance...
EDITS.....
In my case I have to use a xml file to store information. That's why I don't look for sharedpreferences or Sqlite DB to store data. Thanks.
Maybe you should store this information is SharedPreferences instead? If you have a specific reason why you are trying to write this to XML, that is fine.
Otherwise, I would suggest using a different method of persistence in Android - as there are a few built in ways to do this that are easier that working with XML.

Categories