I just had to write the following stupid class to avoid going insane:
import java.io.OutputStream;
import org.w3c.dom.Document;
import org.w3c.dom.bootstrap.DOMImplementationRegistry;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSOutput;
import org.w3c.dom.ls.LSSerializer;
public final class XMLSerializer {
public static final void writeDocument(Document input, OutputStream output) {
try {
DOMImplementationLS ls =
(DOMImplementationLS) DOMImplementationRegistry
.newInstance().getDOMImplementation("LS");
LSSerializer ser = ls.createLSSerializer();
LSOutput out = ls.createLSOutput();
out.setByteStream(output);
ser.write(input, out);
} catch (Exception e) { // DIAF Java
throw new RuntimeException(e);
}
}
}
Does this convenience method already exist in Java or a common library? It seems ridiculously long-winded, and that's even the version where all exceptions are collapsed under a "catch (Exception e)".
Try this:
DOMSource domSource = new DOMSource(input);
StreamResult resultStream = new StreamResult(output);
TransformerFactory transformFactory = TransformerFactory.newInstance();
try {
serializer.transform(domSource, resultStream);
} catch (javax.xml.transform.TransformerException e) {
}
Try dom4j. It is an excellent XML library.
Related
I'm new to XML so bear with me. I need to transform an xml file to another xml file. It needs xslt 2.0. I am using saxon's s9api. Using their documentation this what I have so far:
import java.io.File;
import javax.xml.transform.stream.StreamSource;
import net.sf.saxon.s9api.DocumentBuilder;
import net.sf.saxon.s9api.Processor;
import net.sf.saxon.s9api.SaxonApiException;
import net.sf.saxon.s9api.XsltCompiler;
import net.sf.saxon.s9api.XsltExecutable;
import net.sf.saxon.s9api.XsltTransformer;
class Main{
public static void main(String args[]){
Processor processor = new Processor(false);
XsltCompiler compiler = processor.newXsltCompiler();
DocumentBuilder builder = processor.newDocumentBuilder();
try {
builder.build(new File("C:\\XMLFILE.xml"));
} catch (SaxonApiException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
XsltExecutable xsl = compiler.compile(new StreamSource(new File("C:\\XSLFILE.xsl")));
XsltTransformer trans = xsl.load();
trans.transform();
} catch (SaxonApiException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Is this the right direction? If it is and this is actually performing the transformation how do I specify the output xml.
You can set a destination on the transformer, for example an output File.
Serializer out = new Serializer();
out.setOutputProperty(Serializer.Property.METHOD, "html");
out.setOutputProperty(Serializer.Property.INDENT, "yes");
out.setOutputFile(new File("<filelocation>"));
Then set on the transformer
transformer.setDestination(out);
Before you make the call to transform().
trans.transform();
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");
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 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);
}
How can a Rational Functional Tester script figure out under which version of RFT it executes/was built with?
I digged through the documentation, and the closest I found was
com.rational.test.ft.script.ScriptUtilities.getOperatingSystemVersion()
which returns OS version info, which might be close, but still not what Daddy is looking for ;O
I didn't find anything in the APIs or in the Windows registry.
The only way I can think of is to create a custom method and include it in you helper class.
You can find the versione in the file C:\IBM\SDP\FunctionalTester\properties\version\IBM_Rational_Functional_Tester.*.*.swtag, change the path to match your installation.
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
private final static String RFTVersionFolder = "C:\\IBM\\SDP\\FunctionalTester\\properties\\version";
public static String getRFTVersionWithXML() {
File versionFolder = new File(RFTVersionFolder);
File[] versionFile = versionFolder.listFiles( new FilenameFilter() {
public boolean accept(File dir, String name) {
return (name.endsWith(".swtag"));
} } );
Document versionDocument = null;
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder = factory.newDocumentBuilder();
versionDocument = builder.parse(new FileInputStream(versionFile[0]));
} catch (SAXParseException spe) {
spe.printStackTrace();
} catch (SAXException sxe) {
sxe.printStackTrace();
} catch (ParserConfigurationException pce) {
pce.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
}
Node versionNode = versionDocument.getElementsByTagName("ProductVersion").item(0);
return versionNode.getTextContent();
}
This is a quite expensive method, because it istantiates a DocumentBuilder for XML parsing.
As an alternative, load the file content as a String and parse it with a RegExp,
use this matching pattern: [0-9]\.[0-9]\.[0-9]
public static String getRFTVersionWithRegexp() {
File versionFolder = new File(RFTVersionFolder);
File[] versionFile = versionFolder.listFiles( new FilenameFilter() {
public boolean accept(File dir, String name) {
return (name.endsWith(".swtag"));
} } );
byte[] buffer = null;
FileInputStream fin;
try {
fin = new FileInputStream(versionFile[0]);
buffer = new byte[(int) versionFile[0].length()];
new DataInputStream(fin).readFully(buffer);
fin.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException ioe) {
ioe.printStackTrace();
}
String versionFileContent = new String(buffer);
String version = null;
Regex r = new Regex("[0-9]\\.[0-9]\\.[0-9]", Regex.MATCH_NORMAL);
if (r.matches(versionFileContent))
version = r.getMatch();
return version;
}
1) Go to Help> About RFT, it shows the version.