I am generating XML dynamically using JAXB.
Now, I want to convert it to HTML using XSL. How can i include
<?xml-stylesheet type="text/xsl" href="">
in the dynamically generated XML?
I am generating XML dynamically using JAXB.
Now, I want to convert it to HTML using XSL. How can i include
<?xml-stylesheet type="text/xsl" href="">
in the dynamically generated XML?
All the solutions here are pretty ugly and verbose. Simply set the line inside the Mashaller
object specifying the additional header.
Marshaller jaxbMarshaller = ...
jaxbMarshaller.setProperty("com.sun.xml.bind.xmlHeaders",
"<?xml-stylesheet type='text/xsl' href='nameoffile.xsl' ?>");
This example will output an XML object to a file using a stylesheet and format the elements nicely for humans to read. The object myXmlObject
is of class MyXmlClass
, and will be written to file
, formatted by a stylesheet given by xslUrl
:
JAXBContext context = JAXBContext.newInstance(MyXmlClass.class);
Marshaller marshaller = context.createMarshaller();
//Need to use a Writer to marshal with the XSL
FileWriter fw = new FileWriter(file);
//Do this or else the XML is all one line and not human friendly...
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.setProperty("com.sun.xml.bind.xmlHeaders",
"<?xml-stylesheet type='text/xsl' href=\"" +
xslUrl +
"\" ?>");
marshaller.marshal(myXmlObject, fw);
Update
In recent version of JAXB we need to use property key as com.sun.xml.internal.bind.xmlHeaders
like below.
Marshaller jaxbMarshaller = ...
jaxbMarshaller.setProperty("com.sun.xml.internal.bind.xmlHeaders",
"<?xml-stylesheet type='text/xsl' href='nameoffile.xsl' ?>");
You could use a StringWriter to first write the stylesheet information into it, and then marshal the object into it:
StringWriter writer = new StringWriter();
//add processing instructions "by hand" with escaped quotation marks
//or single marks
writer.println("<?xml version='1.0'?>");
writer.println("<?xml-stylesheet type=\"text/xsl\" href=\"\">");
//create and configure marshaller to leave out processing instructions
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
//marshal to the StringWriter
marshaller.marshal(someObject,writer);
//get the string representation
String str = writer.toString();
Of course you can also directly print to every other output stream you want, e.g. files or Sytstem.out.
See how it's done in rexsl-core, part of ReXSL XSL/JAXB/JAX-RS framework: XslResolver:
final String header = String.format(
"\n<?xml-stylesheet type='text/xsl' href='%s'?>",
StringEscapeUtils.escapeXml("my-stylesheet.xsl")
);
marshaller.setProperty("com.sun.xml.bind.xmlHeaders", header);
JAXBContext jaxbContext;
try {
jaxbContext = JAXBContext.newInstance(new Class[] {SomeObject.class});
StringWriter writer = new StringWriter();
writer.write("<?xml version='1.0'?>");
writer.write("\n");
writer.write("<?xml-stylesheet type=\"text/xsl\" href=\"\">");
writer.write("\n");
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.marshal(someobject, writer);
}