XML Output in Java -- what's with DOMImplementationLS? - java

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

How to do XSLT 2.0 transform using saxon s9api? XML file to XML file

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();

Can't make Java created XML work with XSL

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");

Modifying XML element in java

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>

Java error saving xml

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 do I get the RFT version number?

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.

Categories

Resources