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!
Related
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!
In this article (https://www.ahoi-it.de/ahoi/news/java-xslt-memory-leak/4830) it is explained that Javax xml transformer caches XML contents to its internal HashMap for later use.
This is my issue: I am reading XML messages from activemq and if something fails, I retry to convert them again using Javax XML transformer and send them to certain endpoint. The problem is that eventually my Docker container restarts because it runs out of memory.
What I would like to do is disable caching, unfortunately, after 3 hours of research I still have no idea how to do so.
I have a utils class with static methods and this is how my Javax XML Transformer looks like:
public static String getTransformedXml(Object input, String transformerFileName)
throws IOException, TransformerException {
ClassPathResource classPathResource = new ClassPathResource(transformerFileName);
InputStream xsltStream = classPathResource.getInputStream();
TransformerFactory factory = TransformerFactory.newInstance();
Source xslt = new StreamSource(xsltStream);
Transformer transformer = factory.newTransformer(xslt);
transformer.setErrorListener(new XsltTransformerErrorListener(transformerFileName));
Source text = new StreamSource(new StringReader(XmlUtils.encode(input, input.getClass())));
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
transformer.transform(text, result);
return result.getWriter().toString();
}
Try to change the TransformerFactoryImpl :
TransformerFactory tFactory = TransformerFactory.newInstance("org.apache.xalan.processor.TransformerFactoryImpl",null);
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.
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.
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);