XML Transformation from Java Code - java

I am doing transformation of an XML File using XSL through Java code. I used this tutorial for the same. Now the problem is that the output file is created but it has no contents in it. I am also adding the code snippet. Kindly check it and tell me what am I missing :
TransformerFactory factory = TransformerFactory.newInstance();
System.out.println("In transform");
File temp = new File(xslFile);
if(temp.exists()){
System.out.println("File found");
}
StreamSource xsl = new StreamSource(temp);
Transformer transformer = factory.newTransformer(xsl);
temp = new File(xmlFile);
if(temp.exists()){
System.out.println("Found Again!!");
}
StreamSource xml = new StreamSource(temp);
temp = new File(outputFile);
if(temp.createNewFile()){
System.out.println("New File Created");
}
StreamResult output = new StreamResult(temp);
transformer.transform(xml, output);
Here, the xslFile, xmlFile and outputFile are string and passed as parameters to the method.

Try to declare three different variables, one for each file. Code will look clearer and you most likely will avoid some unexpected behaviour, as you don't know how is Transformer using those three references.

Related

How do I write a DOM Document to File?

How do I write this document to the local filesystem?
public void docToFile(org.w3c.dom.Document document, URI path) throws Exception {
File file = new File(path);
}
I need to iterate the document, or might there be a "to xml/html/string" method? I was looking at:
document.getXmlEncoding();
Not quite what I'm after -- but something like that. Looking for the String representation and then to write that to file like:
Path file = ...;
byte[] buf = ...;
Files.write(file, buf);
https://docs.oracle.com/javase/tutorial/essential/io/file.html
I would use a transformer class to convert the DOM content to an xml file, something like below:
Document doc =...
// write the content into xml file
DOMSource source = new DOMSource(doc);
FileWriter writer = new FileWriter(new File("/tmp/output.xml"));
StreamResult result = new StreamResult(writer);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(source, result);
I hope this ends up working for you!

How do I get the URI of a JavaFileObject in annotation testing?

I'm using XSLT to generate Java Code with the javax.annotation.processing API.
It works well as long as I don't want to test it, which I of course do :)
While running the processor, the JavaFileObject.toUri() gives me a "file:/"-URI,
which I can use for creating a StreamResult for the Transformer.
This is not the case when testing the class
I get, for example /CLASS_OUTPUT/com/example.MyClass.class
JavaFileObject jfo = filer.createSourceFile(className);
String uri = jfo.toUri().toASCIIString();
if (!uri.startsWith("file:/")) { // is test!
messager.printMessage(Diagnostic.Kind.NOTE, "Not a file URI, we're testing!");
return;
}
StreamResult result = new StreamResult(uri);
DOMSource src = new DOMSource(modelDoc);
DOMSource xslSource = new DOMSource(loadDocument(xslUri));
TransformerFactory tf = new net.sf.saxon.TransformerFactoryImpl();
Transformer transformer = tf.newTransformer(xslSource);
transformer.transform(src, result);
I have the following questions:
Does the test create a real source file?
If yes, what is its actual location?
Thanks!

Replace text in XML before XSLT

I need to replace a certain text in a XML file before giving it to the XSL-Transformer.
It's the DTD-URL in the DOCTYPE tag. It points to a webserver, but I want it to be usable offline, so I want to change it to a URL pointing to a local file.
However I mustn't edit the original XML directly. I thought of reading the file into a string, use String.replaceAll() on the text and save it into another file, which I pass to the Transformer. I already tried it, but it's really slow; the file I'm using has a size of ca. 500kiB.
Is there any better (=faster) way to accomplish this?
EDIT: The code used for the transformation:
public String getPlaylist(String playlist) {
Source source = new StreamSource(library);
StreamSource xsl = new StreamSource(getClass().getResourceAsStream("M3Utransformation.xml"));
StringWriter w = new StringWriter();
Result result = new StreamResult(w);
try {
Transformer transformer = TransformerFactory.newInstance().newTransformer(xsl);
transformer.setParameter("playlist", playlist);
transformer.transform(source, result);
return w.getBuffer().toString();
} catch (Throwable t) {
t.printStackTrace();
return null;
}
}
You can create an entity resolver, and make use of it.
The following example uses the JAXP DocumentBuilder, and a CatalogResolver
public static void main(String[] args) throws ParserConfigurationException,
SAXException, IOException, TransformerConfigurationException, TransformerException {
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
db.setEntityResolver(new CatalogResolver());
File src = new File("src/article.xml");
Document doc = db.parse(src);
// Here, we execute the transformation
// Use a Transformer for output
File stylesheet = new File("src/aticle.xsl");
TransformerFactory tFactory = TransformerFactory.newInstance();
StreamSource stylesource = new StreamSource(stylesheet);
Transformer transformer = tFactory.newTransformer(stylesource);
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(System.out);
transformer.transform(source, result);
}
create a catalog properties file, and place it on your classpath
CatalogManager.properties has to be the name, see CatalogManager API documentation
define a catalog XML file, point your properties file, above to it. From
http://www.xml.com/pub/a/2004/03/03/catalogs.html you can find a very simple catalog XML file :
<?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<public publicId="-//OYRM/foo" uri="src/bar.dtd"/>
</catalog>
With the above catalog.xml and CatalogManager.properties, you'll end up resolving references to the publicId "-//OYRM/foo" to the uri src/bar.dtd
xml-commons contains the resolver :
http://xerces.apache.org/mirrors.cgi#binary
for a more complete treatment of the topic of Resolvers read Tom White's article from XML.com
The transformer application was cribbed from the Java trail for Extensible StyleSheet Language Transformations > Transforming Data with XSLT

What to do with generated SOAP calls from a WSDL file in Netbeans

I'm just starting out with Java, but my boss is pushing for this. I've taken the WSDL file we had, and generated a web service and a web client in Netbeans. Also, I've dragged the new service into my client and made sure, that the code works. But now I have a question. How do work with the result? The code in my JSP looks like this:
try {
Soap.PDFSignatureServiceService service = new Soap.PDFSignatureServiceService();
javax.xml.namespace.QName portQName = new javax.xml.namespace.QName("http://external.ltc.com/", "PDFSignatureServicePort");
String req = "<getTimestamp xmlns=\"http://external.ltc.com/\"><msisdn>ENTER VALUE</msisdn></getTimestamp>";
javax.xml.ws.Dispatch<javax.xml.transform.Source> sourceDispatch = null;
sourceDispatch = service.createDispatch(portQName, javax.xml.transform.Source.class, javax.xml.ws.Service.Mode.PAYLOAD);
javax.xml.transform.Source result = sourceDispatch.invoke(new javax.xml.transform.stream.StreamSource(new java.io.StringReader(req)));
out.print(result.toString());
} catch (Exception ex) {
out.print(ex.getMessage());
}
The code works, but what it is printing out is: com.sun.xml.ws.util.xml.StAXSource#90fe8e. What in the world do I do with this? I was expecting either a SOAP message, or an integer of some sorts. How do I get to somewhere from here?
Thanks!
What you are doing here is creating a dynamic client and actually you are working on the payload level and not on the SOAP message level.
For the SOAP level you would have to do:
Dispatch<SOAPMessage> dispatch
The result in your case is the XML payload of the response.
You can for example convert it to String and see it:
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
StringWriter writer = new StringWriter();
Result stringOut = new StreamResult(writer);
transformer.transform(result, stringOut);
writer.close();
System.out.println(writer.toString());
Or convert it to XML node:
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
DOMResult domResult = new DOMResult();
transformer.transform(result, domResult);
rootNode = domResult.getNode();
Disclaimer:Did not even attempt to compile the code
If you look at the Dispatch.invoke specs in javadocs, it is :
http://docs.oracle.com/javase/6/docs/api/javax/xml/ws/Dispatch.html#invoke(T).
And if you change your code to :
**javax.xml.transform.stream.StreamSource** result = sourceDispatch.invoke(new javax.xml.transform.stream.StreamSource(new java.io.StringReader(req)));
The StreamSource has methods to get the Reader and eventually some meaningful result can b obtained.

How to 'transform' a String object (containing XML) to an element on an existing JSP page

Currently, I have a String object that contains XML elements:
String carsInGarage = garage.getCars();
I now want to pass this String as an input/stream source (or some kind of source), but am unsure which one to choose and how to implement it.
Most of the solutions I have looked at import the package: javax.xml.transform and accept a XML file (stylerXML.xml) and output to a HTML file (outputFile.html) (See code below).
try
{
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer(new StreamSource("styler.xsl"));
transformer.transform(new StreamSource("stylerXML.xml"), new StreamResult(new FileOutputStream("outputFile.html")));
}
catch (Exception e)
{
e.printStackTrace();
}
I want to accept a String object and output (using XSL) to a element within an existing JSP page. I just don't know how to implement this, even having looked at the code above.
Can someone please advise/assist. I have searched high and low for a solution, but I just can't pull anything out.
Use a StringReader and a StringWriter:
try {
StringReader reader = new StringReader("<xml>blabla</xml>");
StringWriter writer = new StringWriter();
TransformerFactory tFactory = TransformerFactory.newInstance();
Transformer transformer = tFactory.newTransformer(
new javax.xml.transform.stream.StreamSource("styler.xsl"));
transformer.transform(
new javax.xml.transform.stream.StreamSource(reader),
new javax.xml.transform.stream.StreamResult(writer));
String result = writer.toString();
} catch (Exception e) {
e.printStackTrace();
}
If at some point you want the source to contain more than just a single string, or you don't want to generate the XML wrapper element manually, create a DOM document that contains your source and pass it to the transformer using a DOMSource.
This worked for me.
String str = "<my>xml</my>"
StreamSource src = new StreamSource(new StringReader(str));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Result res = new StreamResult(baos);
transformer.transform(src, res);

Categories