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 "" 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.
Related
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
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.
I need help understanding why the XML String does not convert into a CSV file. Why is the CSV Resut always empty?
Here is an example of a Java Code
public class transformCSV_1 {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
try {
String xmlData = new String(
"<?xml version=\"1.0\"?><PurchaseOrder xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"http://localhost:8080/source/schemas/poSource/xsd/purchaseOrder.xsd\"><Reference>SBELL-2002100912333601PDT</Reference><Actions><Action><User>SVOLLMAN</User></Action></Actions><Requestor>Sarah J. Bell</Requestor><User>SBELL</User><CostCenter>S30</CostCenter><ShippingInstructions><name>Sarah J. Bell</name><address>400 Oracle Parkway Redwood Shores CA 94065 USA</address><telephone>650 506 7400</telephone></ShippingInstructions><SpecialInstructions>Air Mail</SpecialInstructions><LineItems><LineItem ItemNumber=\"1\"><Description>A Night to Remember</Description><Part Id=\"715515009058\" UnitPrice=\"39.95\" Quantity=\"2\"/></LineItem><LineItem ItemNumber=\"2\"><Description>The Unbearable Lightness Of Being</Description><Part Id=\"37429140222\" UnitPrice=\"29.95\" Quantity=\"2\"/></LineItem><LineItem ItemNumber=\"3\"><Description>Sisters</Description><Part Id=\"715515011020\" UnitPrice=\"29.95\" Quantity=\"4\"/></LineItem></LineItems></PurchaseOrder>");
String stylesheet = new String(
"<?xml version=\"1.0\" encoding=\"utf-8\"?><xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\"><xsl:output method=\"text\" /><xsl:variable name=\"delimiter\" select=\"','\" /><!-- define an array containing the fields we are interested in --><xsl:variable name=\"fieldArray\"><field>Reference</field><field>User</field><field>Reject</field><field>Requestor</field></xsl:variable><xsl:param name=\"fields\" select=\"document('')/*/xsl:variable[#name='fieldArray']/*\" /><xsl:template match=\"/\"><!-- output the header row --><xsl:for-each select=\"$fields\"><xsl:if test=\"position() != 1\"><xsl:value-of select=\"$delimiter\"/></xsl:if><xsl:value-of select=\".\" /></xsl:for-each><!-- output newline --><xsl:text>
</xsl:text><xsl:apply-templates select=\"PurchaseOrder\"/></xsl:template><xsl:template match=\"PurchaseOrder\"><xsl:variable name=\"currNode\" select=\".\" /><!-- output the data row --><!-- loop over the field names and find the value of each one in the xml --><xsl:for-each select=\"$fields\"><xsl:if test=\"position() != 1\"><xsl:value-of select=\"$delimiter\"/></xsl:if><xsl:value-of select=\"$currNode/*[name() = current()]\" /></xsl:for-each><!-- output newline --><xsl:text>
</xsl:text></xsl:template></xsl:stylesheet>");
InputStream xmlSource = new ByteArrayInputStream(
xmlData.getBytes("UTF-8"));
InputStream styleSource = new ByteArrayInputStream(
stylesheet.getBytes("UTF-8"));
DocumentBuilderFactory factory = DocumentBuilderFactory
.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(xmlSource);
StreamSource stylesource = new StreamSource(styleSource);
Transformer transformer = TransformerFactory.newInstance()
.newTransformer(stylesource);
Source source = new DOMSource(document);
Result outputTarget = new StreamResult(new File("src/resultI.csv"));
transformer.transform(source, outputTarget);
} catch (TransformerConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ParserConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerFactoryConfigurationError e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Best way is to use XSLT to "transform" the XML to CSV --> Can someone give me hint?
Consider to load the XSLT code from a file or URI (instead of from a string) as otherwise your approach of doing <xsl:param name="fields" select="document('')/*/xsl:variable[#name='fieldArray']/*" /> where document('') tries to pull in the XSLT code again is likely to fail, unless you set up a special resolver.
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.
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.