I'm creating an XML using DOM, I open the XML with explorer and it seems fine.
After that I created an XSL for it, add the reference to it programatically to the XML and boom, it works no longer.
I inspect the code in the browser and save the file as XML.
I open the XML with notepad++ and noticed the npp shows the XML file is encoded in "UCS-2 LE BOM" even though the XML header sais it's in "UTF-8", I don't know if this has to do with being saved from the browser or it's because of Java transformer.File encoding according to npp
Anyway, I change the file encoding in npp to "UTF-8", open it again and it works flawlessly.
I've tried changing the transformer's encoding property transformer.setOutputProperty("encoding", "ISO-8859-1") to different values but it will just change the XML header.
I googled around but I haven't found anything that's worked so far.
This is the code where the XML is created
package modelo;
import java.awt.Desktop;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
public class DAOXML {
private static final String rutaUno = ".\\VerLibro.xml";
private static final String rutaListado = ".\\listado.xml";
public static boolean toXML(ArrayList<Libro> libros2) {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
final String rutaActual = libros2.size()>1?rutaListado:rutaUno;
try {
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.newDocument();
doc.setDocumentURI(rutaActual);
doc.setXmlStandalone(true);
Element libros = doc.createElement("libros");
for(Libro l : libros2) {
Element libro = doc.createElement("libro");
Element isbn = doc.createElement("isbn");
isbn.setTextContent(l.getISBN());
libro.appendChild(isbn);
Element editorial = doc.createElement("editorial_apellidos");
editorial.setTextContent(l.getEditorial_apellidos());
libro.appendChild(editorial);
Element autor = doc.createElement("autor");
autor.setTextContent(l.getAutor());
libro.appendChild(autor);
Element categoria = doc.createElement("categoria");
categoria.setTextContent(l.getCategoria());
libro.appendChild(categoria);
Element titulo = doc.createElement("titulo");
titulo.setTextContent(l.getTitulo());
libro.appendChild(titulo);
Element ubicacion = doc.createElement("ubicacion");
ubicacion.setTextContent(l.getUbiacion());
libro.appendChild(ubicacion);
libros.appendChild(libro);
}
doc.appendChild(libros);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
// transformer.setOutputProperty("encoding", "ISO-8859-1");
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File(rutaActual));
//result.setWriter(new PrintWriter(new File(rutaActual), "UTF-8"));
transformer.transform(source, result);
if(rutaActual == rutaUno) {
Node pi = doc.createProcessingInstruction("xml-stylesheet", "type=\"text/xsl\" href=\"VerLibro.xsl\"");
doc.insertBefore(pi, libros);
}
else {
Node pi = doc.createProcessingInstruction("xml-stylesheet", "type=\"text/xsl\" href=\"listado.xsl\"");
doc.insertBefore(pi, libros);
}
Desktop.getDesktop().open(new File(rutaActual));
return true;
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (TransformerConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
}
Thanks in advance.
Try adding this line before you call transform():
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
Related
I am trying to edit a specific key inside an XML file. The problem is that after the file is saved, the '<' and '>' characters are transformed in coded characters (respectively: "& lt;" and "& gt;").
XML File:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
</configSections>
<system.web>
<httpRuntime targetFramework="X.X"/>
</system.web>
<connectionStrings>
<add connectionString="Data Source=XXXX;user Id=YYYYY;password=ZZZZZ;" name="Entities" providerName="Oracle.ManagedDataAccess.Client"/>
</connectionStrings>
</configuration>
I'm updating the value of the entire connectionStrings key:
package br.com.sedna.bitbucket.plugin.enviromentsetup.utils;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.StringReader;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.xml.sax.InputSource;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class ModifyXmlFile {
private File _inputFile;
private String _filePath;
private DocumentBuilderFactory _docFactory;
private DocumentBuilder _docBuilder;
private Document _doc;
private Node _xmlObject;
private String CONNECTION_STRINGS = "<add connectionString=\"Data Source=XXXX;user Id=%s;password=ZZZZZ;\" name=\"Entities\" providerName=\"Oracle.ManagedDataAccess.Client\"/>";
public ModifyXmlFile(String xmlPath){
try {
this._filePath = xmlPath;
this._inputFile = new File(this._filePath);
this._docFactory = DocumentBuilderFactory.newInstance();
this._docBuilder = _docFactory.newDocumentBuilder();
this._doc = _docBuilder.parse(_inputFile);
this._xmlObject = _doc.getFirstChild();
} 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();
}
}
public ModifyXmlFile setNodeValue(String nodeName, String nodeValue){
Node nodeNameObject = this._doc.getElementsByTagName(nodeName).item(0);
try {
// updating the value of connectionStrings key
nodeNameObject.setTextContent(String.format(CONNECTION_STRINGS, nodeValue));
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer;
transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.ENCODING, "utf-8");
DOMSource source = new DOMSource(this._doc);
StreamResult consoleResult = new StreamResult(new File(this._filePath));
transformer.transform(source, consoleResult);
System.out.println("Done");
} catch (TransformerConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return this;
}
}
Running this class:
ModifyXmlFile xmlHelper = new ModifyXmlFile("C:\\Web.config");
xmlHelper.setNodeValue("connectionStrings", "NEWVALUE");
The result:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
</configSections>
<system.web>
<httpRuntime targetFramework="X.X"/>
</system.web>
<connectionStrings><add connectionString="Data Source=XXXX;user Id=NEWVALUE;password=ZZZZZ;" name="Entities" providerName="Oracle.ManagedDataAccess.Client"/></connectionStrings>
</connectionStrings>
</configuration>
I have tried changing the encode type without success.
I have modified the setNodeValue method. The relevant part follows:
public ModifyXmlFile setElementAttributeValue(String nodeXPath, String attributeName, String newAttributeValue) throws XPathExpressionException{
try {
XPath xPath = XPathFactory.newInstance().newXPath();
Node node = (Node)xPath.evaluate(nodeXPath, _doc, XPathConstants.NODE);
node.getAttributes().getNamedItem(attributeName).setNodeValue(String.format(CONNECTION_STRINGS, newAttributeValue));
Calling this via
setElementAttributeValue("/configuration/connectionStrings/add", "connectionString", "NEWVALUE" );
changes the value of the attribute connectionString on the element add.
There are several problems in the original code:
the consoleResult is named confusingly - the StreamResult points to a file
the parameter nodeName actually stands for parent node of the element to be edited and this is indeed what is retrieved per this._doc.getElementsByTagName(nodeName).item(0) - at least when setNodeValue is called with "connectionStrings" for nodeName.
the name of the attribute to be edited is hard-wired into the code.
as T.J. Crowder mentioned, the setTextContent method the original code is calling is used to set text content, i.e. the text between >< of some element. It is neccessary to distinguish between elements, attributes and text content and be aware of the fact that these are not interchangeable. It is not possible to add new element by adding text content which looks like (is formatted like) an element.
Please note that the new code is not production ready as at the very least the handling of potential null values would need to be added, e.g. on the result of getNamedItem(attributeName).
I am looking for an element "storage.hostname" and modifying that element.
Here is my piece of code,
import java.io.File;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
public class testXML {
public static void main(String argv[]) throws TransformerException {
String filepath = "C:\\qautilsServer\\target\\";
String hostname = "psvrhc9";
update(filepath,hostname);
}
public static void update(String destDirectory, String hostname) throws TransformerException{
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
File rexsterFile = new File(destDirectory + "\\titan-rexster-server-2.5.0\\config\\rexster.xml");
DocumentBuilder docBuilder = null;
try
{
docBuilder = docFactory.newDocumentBuilder();
}
catch (ParserConfigurationException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
Document doc = null;
try
{
doc = docBuilder.parse(rexsterFile);
}
catch (SAXException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
Node nodes1 = doc.getElementsByTagName("storage.hostname").item(0);
nodes1.setTextContent(hostname);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(destDirectory + "\\config.xml");
transformer.transform(source, result);
}
}
I get the same error when i do the following
nodes1.getTextContent();
My XML looks like this:
<graph>
<graph-name>graph</graph-name>
<graph-type>com.thinkaurelius.titan.tinkerpop.rexster.TitanGraphConfiguration</graph-type>
<graph-read-only>true</graph-read-only>
<properties>
<storage.backend>hbase</storage.backend>
<ids.num-partitions>1</ids.num-partitions>
<storage.hbase.region-count>8</storage.hbase.region-count>
<cluster.max-partitions>32</cluster.max-partitions>
<storage.hostname>psvrhc1</storage.hostname>
<storage.hbase.table>ldmns:titan_db</storage.hbase.table>
<storage.hbase.skip-schema-check>false</storage.hbase.skip-schema-check>
<query.force-index>false</query.force-index>
</properties>
<extensions>
<allows>
<allow>tp:gremlin</allow>
</allows>
</extensions>
</graph>
I am getting following issue and i have no clue why is this error coming:
Exception in thread "main" java.lang.AbstractMethodError: org.apache.xerces.dom.DeferredAttrImpl.setTextContent(Ljava/lang/String;)V
Note: I am running in jre7 and not jre8. The code seems to be working fine with jre8. Since, my project only supports jre7, i can't upgrade to jre8.
I even tried nodes1.setNodeValue(hostname);
but it didnt work.
Any help will be highly appreciated.
I notice you are having an AbstractMethodError.
Reference says:
Thrown when an application tries to call an abstract method. Normally, this error is caught by the compiler; this error can only occur at run time if the definition of some class has incompatibly changed since the currently executing method was last compiled.
I fear you might have issues with your Apache Xerces library. Maybe your runtime is using an older version which does not implement Node#setTextContent(String) (since DOM level 3).
Previously I modified your code to create a minimal reproducible case. But in fact it worked fine. Also works when i read from filesystem your full XML in my Eclipse Java EE 4.5 fresh setup. Probably the code is irrelevant, but I keep it on display just in case.
import java.io.ByteArrayInputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
public class TestXML {
public static void main(String argv[]) throws TransformerException {
try {
String xml = "<graph>" + "<storage.hostname>psvrhc1</storage.hostname>" + "</graph>";
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(new ByteArrayInputStream(xml.getBytes()));
Node nodes1 = doc.getElementsByTagName("storage.hostname").item(0);
nodes1.setTextContent("blah");
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(System.out);
transformer.transform(source, result);
} catch (Throwable e) {
e.printStackTrace();
}
}
}
Outputs:
<?xml version="1.0" encoding="UTF-8" standalone="no"?><graph><storage.hostname>blah</storage.hostname></graph>
I want to store sql query in tree format in xml file.I wrote a code which split the code into different tokens and store it in xml file.I am storing keywords like "select",from,where etc as xmlelements and the values of these keywords as textnodes inside corresponding elements.When the query contains single single statement it works as i need.but when nested query occurs i want to store the nested query inside "where" element.In that case the code didn't works properly.I am hereby attaching the code.
Can anyone point out logical mistakes in my code????
Second problem is that when i try to store the xmldata in "CreateFiles.xml" file ,the file is not displaying in the corresponding folder.what is the reason for that?
CreateXml.java
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package Work;
import java.io.File;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
/**
*
* #author user
*/
public class Createxmls {
public void CreateXML() throws ParserConfigurationException, TransformerConfigurationException, TransformerException {
DocumentBuilderFactory documentFactory = DocumentBuilderFactory
.newInstance();
DocumentBuilder documentBuilder = documentFactory
.newDocumentBuilder();
Document document = documentBuilder.newDocument();
Element rootElement = document.createElement("SQLStatement");
document.appendChild(rootElement);
Element stmt = document.createElement("SQLStatement");
rootElement.appendChild(stmt);
Element Element = document.createElement("null");
String tokens[] = {"select", "max(id)", "from", "facedictionary", "where", "id = (",
"select", "id", "from", "facedetails", "where", "id like 34 group by id)"};
for (int i = 0; i < tokens.length; i++) {
System.out.println("tok:" + tokens[i]);
if (tokens[i].equalsIgnoreCase("select") || tokens[i].equalsIgnoreCase("from") || tokens[i].equalsIgnoreCase("where")) {
Element = document.createElement(tokens[i]);
stmt.appendChild(Element);
} else {
Element.appendChild(document.createTextNode(tokens[i]));
stmt.appendChild(Element);
}
}
String xmlstring = "";
TransformerFactory transformerFactory = TransformerFactory
.newInstance();
Transformer transformer = transformerFactory.newTransformer();
StreamResult streamResult = new StreamResult(new File(
"createFile.xml"));
StringWriter sw = new StringWriter();
Transformer serializer = TransformerFactory.newInstance().newTransformer();
serializer.transform(new DOMSource(document), new StreamResult(sw));
xmlstring = sw.toString();
System.out.println(xmlstring);
DOMSource domSource = new DOMSource(stmt);
transformer.transform(domSource, streamResult);
System.out.println("File saved to specified path!");
}
public static void main(String arg[]) {
try {
Createxmls xml = new Createxmls();
xml.CreateXML();
} catch (ParserConfigurationException ex) {
Logger.getLogger(Createxmls.class.getName()).log(Level.SEVERE, null, ex);
} catch (TransformerConfigurationException ex) {
Logger.getLogger(Createxmls.class.getName()).log(Level.SEVERE, null, ex);
} catch (TransformerException ex) {
Logger.getLogger(Createxmls.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
When i displayed the contents of xml file for the query:
"select max(id) from facedictionary where id = (select id from facedetails where id like 34 group by id))
The result i got
<?xml version="1.0" encoding="UTF-8"?>
-<SQLStatement>
<select>max(id)</select>
<from>facedictionary</from>
<where>id = (</where>
<select>id</select>
<from>facedetails</from>
<where>id like 34 group by id)</where>
</SQLStatement>
The result i need:
<?xml version="1.0" encoding="UTF-8"?>
-<SQLStatement>
<select>max(id)</select>
<from>facedictionary</from>
<where>id = (
<select>id</select>
<from>facedetails</from>
<where>id like 34 group by id)</where>
</where>
</SQLStatement>
Hi all and thanks for your time and help.
Im trying to parse a xml file in the "res/raw" folder and passing the result to other class to work with it.
I'm stuck and cannot find any solution, Im trying to learn programming, so, the whole code may be wrong and I failed catastrophically from the beginning.
this is the parser, it get a document from the raw folder and return the parsed document.
import java.io.IOException;
import java.io.InputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.xml.sax.SAXException;
import android.app.Activity;
public class Pars extends Activity{
public Document doc(){
InputStream is = getResources().openRawResource(R.raw.talechap01);
Document docout = null;
DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = null;
try {
builder = domFactory.newDocumentBuilder();
docout = builder.parse(is);
} catch (ParserConfigurationException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return docout;
}
}
this class get the parsed document and find some content using xpath and pass it in a return.
I can not pass the parsed document "docout" from the class "Pars"
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
public class Commanders {
public static String getStory(String spage) {
XPathExpression expr;
XPath xpath = XPathFactory.newInstance().newXPath();
Object result = null;
String num = spage;
String par = null;
Document doc = //Here I need the document parsed from the "Pars" class
try {
expr = xpath.compile("//decision"+num+"/p//text()");
result = expr.evaluate(doc, XPathConstants.NODESET);
}
catch (XPathExpressionException e) {
e.printStackTrace();
}
NodeList nodes = (NodeList) result;
for (int i = 0; i < nodes.getLength(); i++) {
par = nodes.item(i).getNodeValue();
// System.out.println(par);
}
return par;
}
}
Here is an example from the xml.
I'm trying to get the content of "" depending of the "decisionXXX" number.
<talechap01>
<Start></Start>
<decision000 id="000">
<p> part 1 text</p>
<p> second row text</p>
<pick chs= "001" name= "go to decision001"/>
<pick chs= "002" name= "go to decision002"/>
</decision000>
<decision001 id="001">
<p>parte 2</p>
<pick chs = "002" name= "go to decision002"/>
<pick chs = "003" name= "go to decision003"/>
</decision001>
I'm doing something/all wrong?
Is there even possible to do?
Maybe I don't understand something, but it seems like attribute "id" is a decision number,
i mean next
decision000 id=000
If it's true then you can first find nodes which start with and then select by id
I can't check it now, but it should work, try next expression:
//*[starts-with(local-name(), 'decision')][#id='your_num_value']
You need to adjust the function signature of Commanders#getStory(java.lang.String) so it takes your extra doc argument. You can then execute your code like...
Pars pars = new Pars();
Document doc = pars.doc();
Commanders.getStory(doc, spage)
I have a Document object in java and I want to save it, so I have this code:
TransformerFactory fabTransformador = TransformerFactory.newInstance();
Transformer transformador = fabTransformador.newTransformer();
Source origin = new DOMSource(documentoXML);
Result destino = new StreamResult(new java.io.File(nombrearchivo));
transformador.transform(origin, destino);
where "nombrearchivo" is the file name (file.xml) and documentoXMLis the Document object.
When I execute the code, I receive as output: ERROR: ''
I don't receive any exception, just the message ERROR: ''
The document is about 1,3 GB, I don't know it it is the problem, and in that case, is there another way to save the file?
I use the next imports:
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.Node;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.*;
import javax.xml.transform.stream.*;
Your code looks fine, but for reference there's an alternative approach you can use for saving a DOM document:
import org.w3c.dom.ls.*;
import java.io.FileOutputStream;
DOMImplementationLS ls = (DOMImplementationLS)documentoXML.getImplementation();
LSSerializer ser = ls.createLSSerializer();
LSOutput out = ls.createLSOutput();
out.setEncoding("UTF-8");
FileOutputStream output = new FileOutputStream("output.xml");
try {
out.setByteStream(output);
ser.write(documentoXML, out);
} finally {
output.close();
}
Use following to determine exact reason:
try {
secure.generaTextoXML();
} catch (Trowable thr) {
thr.printStackTrace();
}
... or try Level.ERROR instead of Level.SEVERE for your logger:
try {
secure.generaTextoXML();
} catch (TransformerConfigurationException ex) {
Logger.getLogger(GUI.class.getName()).log(Level.ERROR, null, ex);
} catch (TransformerException ex) {
Logger.getLogger(GUI.class.getName()).log(Level.ERROR, null, ex);
}