Header Tag in XML using JAXB - java

Right now I am getting this as an XML output from my JAXB Marshaller
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><create></create>
But I want my root element as:
<create xmlns="http://ws.abc.com" xmlns:doc="http://ws.abc.com">
Do I need to modify this using parsers, Or is there any annotation available.

You can set the following property on the Marshaller to remove the header:
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
For More Information
http://blog.bdoughan.com/2011/08/jaxb-and-java-io-files-streams-readers.html

I've used a Transformer in the past. You'd want something like the following sample code:
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
StreamResult transformedDoc = new StreamResult(new StringWriter());
DOMSource source = new DOMSource(content); // Where content is a org.w3c.dom.Document object.
transformer.transform(source, transformedDoc);
So maybe do your marshalling and then process. Not sure if this is the best approach but it would work.

Related

Disable Indent in JAXP when transform XML

I am using JAXP to convert DOM tree to XML. I do not want any intends in my result XML.
This is my code:
root.normalize();
DOMSource domSource = new DOMSource(root);
StreamResult result = new StreamResult(outputStream);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperty(OutputKeys.ENCODING, encoding);
transformer.setOutputProperty(OutputKeys.INDENT, "no");
transformer.transform(domSource, result);
It works nice if source is not intended and result is also not intended,
If the source XML file is pretty formatted, then "INDENT = no" takes no effect.
The transformed XML file is still indented but I do not want that.
This input generate correct output with no intends.:
<InitMessage xmlns="http://www.test.com/"><operation>while</operation><part1>6</part1><part2>2</part2><part3>5</part3><part4>1</part4></InitMessage>
But this one no and I still got pretty printed intended xml in my output (one line).
<InitMessage xmlns="http://www.test.com/">
<operation>while</operation>
<part1>6</part1>
<part2>2</part2>
<part3>5</part3>
<part4>1</part4>
</InitMessage>
Setting INDENT to no only indicates that the processor is not allowed to add
additional whitespace, not that it will strip existing whitespace.

JAVA 8 xml pretty output not working properly

I try to save Document to the XML in pretty output. But problem is every new element start from line of pervious element end tag.
Example:
<?xml version="1.0" encoding="UTF-8"?><report>
<jiraentry category="SERVICE & ASSET" component="DOCMAN" priority="10" summary="Bug Generated By, UNCHECKED_ACCESS">Tool:UNCHECKED_ACCESS Date:2015-11-12
</jiraentry>
You can see that and text in print in pervious line.Here is the below my Java code which i used to save xml by using transformer.
//normalize the xml file
root.getDocumentElement().normalize();
//remove standalone no
root.setXmlStandalone(true);
// write the content into xml file
TransformerFactory transformerFactory = TransformerFactory.newInstance();
transformerFactory.setAttribute("indent-number", new Integer(0));//add intend to the new line
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(root);
StreamResult result = new StreamResult(new OutputStreamWriter(new FileOutputStream(this.outpath), "UTF-8"));//save the file
transformer.transform(source, result);
Any one can suggest me to make this more pretty and clear.
You need to set the indent amount for the transformer as shown in the snippet below:
t.setOutputProperty(OutputKeys.INDENT, "yes");
t.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
Useful Reference: Similar Question

Java XML dom: prevent collapsing empty element

I use the javax.xml.parsers.DocumentBuilder, and want to write a org.w3c.dom.Document to a file.
If there is an empty element, the default output is a collapsed:
<element/>
Can I change this behavior so that is doesn't collapse the element? I.e.:
<element></element>
Thanks for your help.
This actualy depends on the way how you're writing a document to a file and has nothing to do with DOM itself. The following example uses popular Transformer-based approach:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
Document document = factory.newDocumentBuilder().newDocument();
Element element = document.createElement("tag");
document.appendChild(element);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.METHOD, "html");
DOMSource source = new DOMSource(document);
StreamResult result = new StreamResult(System.out);
transformer.transform(source, result);
It outputs <tag></tag> as you're expecting. Please note, that changing the output method has other side effects, like missing XML declaration.

Java XML Transformer : Empty elements in long notation instead of short

I have created a conversion tool to add some information to an existing xml file.
This is done by using DOM and the Transformer class.
The output file will be processed by third party software.
This TPS needs the empty tags from the input and outputfile in Long Notation.
Unfortunately, transformer class always change them to short notation.
Is there a way to prevent this from happenning?
I have been searching various sites, but haven't found a solution that really fits my needs.
Please help,
Thanks,
Kind regards,
Maarten
You can transform the DOM to StAXResult.
For instance,
XMLOutputFactory factory=XMLOutputFactory.newFactory();
XMLStreamWriter writer=factory.createXMLStreamWriter(System.out);
StAXResult result=new StAXResult(writer);
trans.transform(new DOMSource(doc),result);
XMLOutputFactory factory = XMLOutputFactory.newFactory();
XMLStreamWriter writer = factory.createXMLStreamWriter(System.out);
StAXResult result = new StAXResult(writer);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(new DOMSource(doc), result);

Add XML comments into marshaled file

I'm marshaling objects into an XML file. How can I add comments into that XML file?
You can add comments right after the preamble with the proprietary Marshaller property com.sun.xml.bind.xmlHeaders (see XML Preamble Control)
In the included JAXB-implementation jdk1.6.0_29 the property is called "com.sun.xml.internal.bind.xmlHeaders"
See also question: How to add DOCTYPE and xml processing instructions when marshalling with JAXB?
So to get this XML with the test-comment after the preamble:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- Test Comment -->
<player>
<name>Daniel</name>
<birthday>1982-06-09T00:00:00+02:00</birthday>
</player>
You can use this Java-Code:
JAXBContext context = JAXBContext.newInstance(Player.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.setProperty("com.sun.xml.internal.bind.xmlHeaders", "\n<!-- Test Comment -->");
m.marshal(player, System.out);
I do not see a way to do it with JAXB alone. However, I think you can leverage DOM to get the desired effect:
final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
final DocumentBuilder builder = factory.newDocumentBuilder();
final Document doc = builder.getDOMImplementation().createDocument(null, null, null);
final Binder<Node> binder = jaxbContext.createBinder();
binder.marshal(jaxbObject, doc);
final Comment comment = doc.createComment("This is a comment");
doc.appendChild(comment);
final DOMSource domSource = new DOMSource(doc);
// use System.out for testing
final StreamResult streamResult = new StreamResult(System.out);
final TransformerFactory tf = TransformerFactory.newInstance();
final Transformer serializer = tf.newTransformer();
serializer.transform(domSource, streamResult);
Where jaxbContext is the JAXBContext object you are working with and jaxbObject is the object to be marshalled. This sample just appends the comment to the end of the document. For a different location, you would have to traverse the DOM through the doc object or use XPath to find the exact element you want the comment added to and use appendChild on it.
If anyone comes to this now, like I just did, it is worth pointing out that the property to do this is now com.sun.xml.bind.xmlHeaders (no longer internal it seems), so you can solve the problem like this (I have only tried it with EclipseLink MOXY):
JAXBContext context = JAXBContext.newInstance(Player.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.setProperty("com.sun.xml.bind.xmlHeaders", "\n<!-- Test Comment -->");
m.marshal(player, System.out);
The following information originally comes from Marshaller Properties in the JAXB RI Extensions documentation on jaxb.java.net:
XML Preamble Control
This property allows you to specify an XML preamble (
declaration) and any additional PIs, comments, DOCTYPE declaration
that follows it. This property takes effect only when you are
marshalling to OutputStream, Writer, or StreamResult. Note that this
property interacts with the Marshaller.JAXB_FRAGMENT property. If that
property is untouched or set to false, then JAXB would always write
its XML preamble, so this property can be only used to write PIs,
comments, DOCTYPE, etc. On the other hand, if it is set to true, then
JAXB will not write its own XML preamble, so this property may contain
custom XML preamble.

Categories