Altering the XML header produced by the JAXB marshaller - java

I am currently using the following code to marshal an object into an xml string
JAXBContext context;
try {
context = JAXBContext.newInstance(heartbeat.getClass());
StringWriter writer = new StringWriter();
Marshaller marshaller = context.createMarshaller();
heartbeat.setHeader(header);
heartbeat.setHeartbeatEvent(event);
marshaller.marshal(heartbeat, writer);
String stringXML = writer.toString();
return stringXML;
} catch (JAXBException e) {
throw new RuntimeException("Problems generating XML in specified "
+ "encoding, underlying problem is " + e.getMessage(),
e);
}
Which produces the following header
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
My desired output is the following
<?xml version=\"1.0\"?>
By adding this to the marshaller
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.FALSE);
marshaller.setProperty("com.sun.xml.bind.xmlHeaders", "<?xml version=\"1.0\"?>");
I receive
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><?xml version="1.0"?>
and changing the JAXB_FRAGMENT property to TRUE removes the header entirely. I have been following the JAXB - Remove 'standalone="yes"' from generated XML thread attempting to solve the problem but I have had no luck so far. Can someone please give me some insight on how to get my desired header from the JAXB marshaller?

When marshalling to an OutputStream using a combination of the following produces the expected output.
marshaller.setProperty("com.sun.xml.bind.xmlHeaders", "<?xml version=\"1.0\"?>");
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
The problem you are seeing occurs when you marshal to a Writer, which appears to be a bug in the JAXB reference implementation. You can raise an issue at the link below:
https://java.net/jira/browse/JAXB/
You could always do:
JAXBContext context;
try {
context = JAXBContext.newInstance(heartbeat.getClass());
StringWriter writer = new StringWriter();
writer.append("<?xml version=\"1.0\"?>");
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
heartbeat.setHeader(header);
heartbeat.setHeartbeatEvent(event);
marshaller.marshal(heartbeat, writer);
String stringXML = writer.toString();
return stringXML;
} catch (JAXBException e) {
throw new RuntimeException("Problems generating XML in specified "
+ "encoding, underlying problem is " + e.getMessage(),
e);
}
EclipseLink JAXB (MOXy) also supports the com.sun.xml.bind.xmlHeaders and it works correctly when marshalling to a Writer (I'm the MOXy lead)
http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html

This worked for me
marshaller.setProperty("com.sun.xml.internal.bind.xmlHeaders",
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>");

In JAXB 3.0.1 the above mentioned constants cause a PropertyException:
jakarta.xml.bind.PropertyException: name: com.sun.xml.bind.xmlDeclaration value: false
In this case, the XML preamble can be configured with these marshaller constants:
marshaller.setProperty("org.glassfish.jaxb.xmlHeaders", "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
https://eclipse-ee4j.github.io/jaxb-ri/3.0.0/docs/ch05.html

Related

Incorrect output with log object to xml

I need to log XML message.
I use this code:
//From object to xml
public String createMarshalerDealInfoType(DealInfoType dealInfoType) {
StringWriter contactStr = null;
try {
JAXBContext jaxbContext = JAXBContext.newInstance(DealInfoType.class);
Marshaller jaxbUnmarshaller = jaxbContext.createMarshaller();
contactStr = new StringWriter();
jaxbUnmarshaller.marshal(dealInfoType, contactStr);
} catch (JAXBException e) {
log.error(e.getMessage());
}
return contactStr.toString();
}
In test class:
ResponseType ResponseType = woNspDealWS.createRequestWS(DealRequestType);
String DealResponce = updateDealEsb.createMarshalerDealInfoType(ResponseType.getDealInfo());
log.debug("Response: \n " + DealResponce);
Problem: in log output I see only first line of responce, not whole message
18:01:42,975 DEBUG updateDeal_Test:73 - Response: <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
How do I make to print all response in XML?
SOLVED:
resolved problem with use annotation #XmlRootElement for test class.
The object which you have passed in test class might be empty
ResponseType.getDealInfo()
For solving this problem need use annotation #XmlRootElement in test class

Timestamp tag empty in XML - Java Marshaller

I am not very familiar with Marshaller but I gave a try in a project and the XML was generated fine. But when I apply the XML validation (with the .xsd file) it shows an Error saying that <Timestamp> is empty. I debugged the application and I see that inside my Bean the Timestamp is not empty but when the Marshaller generates the XML it is really empty. In the other hand, other attributes which uses XMLGregorianCalendar are present in the XML. I don't know what is happening.
This is the XML generator function:
public void generateXMLReportFile(String fileOutputDirectory,
String xmlOutputFileName,
CRSOECD crsOECD)
throws JAXBException, FileNotFoundException, IOException
{
String encoding = "UTF-8";
// Schema location to write to generated XML file.
String schemaLocation = "urn:oecd:ties:crs:v1 CrsXML_v1.0.xsd";
// Generate The Report:
JAXBContext context = JAXBContext.newInstance(CRSOECD.class);
StringWriter xml = new StringWriter();
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_ENCODING, encoding);
marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, schemaLocation);
marshaller.marshal(crsOECD, xml);
try (OutputStream out = new FileOutputStream(fileOutputDirectory + xmlOutputFileName)) {
byte[] bytes = xml.toString().getBytes(encoding);
out.write(bytes, 0, bytes.length);
log.info("XML generated.");
}
}
If I debug, I see that the element which is empty in the XML is not empty in the Bean crsOECD.
Guys I just found the answer. The problem was that my element was tagged like this:
#XmlElement(name = "Timestamp", required = true)
#XmlSchemaType(name = "dateTime")
And I was passing only a Date with no Time.

Apache CXF/JAXB unmarshaller converting Japanese characters to ? marks java

Apache CXF/JAXB is not unmarshaling Japanese characters. If we are printing the xml using System.out.println output is coming properly like below.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<employee id="1470">
<designation>Eng</designation>
<name>マデュ</name>
<salary>20000.0</salary>
</employee>
If we are passing the same XML to CXF layer it is converting like below.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<employee id="1470">
<designation>Eng</designation>
<name>???</name>
<salary>20000.0</salary>
</employee>
How to solve this issue. Thanks in advance.
Can you try use PrintWriter on top of StringWriter?
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
Can you try with XMLEventWriter to System.out?
XMLEventFactory events = XMLEventFactory.newInstance();
QName bar = new QName("urn:bar", "bar");
XMLOutputFactory factory = XMLOutputFactory.newInstance();
factory.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, true);
XMLEventWriter writer = factory.createXMLEventWriter(System.out);
JAXBContext pContext = JAXBContext.newInstance(target);
Marshaller marshaller = pContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(pObject, writer);
writer.add(events.createStartDocument());
writer.setDefaultNamespace("urn:bar");
writer.add(events.createStartElement(bar, null, null));
writer.add(events.createEndDocument());
writer.flush();

Remove standalone from xml [duplicate]

I am currently using the following code to marshal an object into an xml string
JAXBContext context;
try {
context = JAXBContext.newInstance(heartbeat.getClass());
StringWriter writer = new StringWriter();
Marshaller marshaller = context.createMarshaller();
heartbeat.setHeader(header);
heartbeat.setHeartbeatEvent(event);
marshaller.marshal(heartbeat, writer);
String stringXML = writer.toString();
return stringXML;
} catch (JAXBException e) {
throw new RuntimeException("Problems generating XML in specified "
+ "encoding, underlying problem is " + e.getMessage(),
e);
}
Which produces the following header
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
My desired output is the following
<?xml version=\"1.0\"?>
By adding this to the marshaller
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.FALSE);
marshaller.setProperty("com.sun.xml.bind.xmlHeaders", "<?xml version=\"1.0\"?>");
I receive
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><?xml version="1.0"?>
and changing the JAXB_FRAGMENT property to TRUE removes the header entirely. I have been following the JAXB - Remove 'standalone="yes"' from generated XML thread attempting to solve the problem but I have had no luck so far. Can someone please give me some insight on how to get my desired header from the JAXB marshaller?
When marshalling to an OutputStream using a combination of the following produces the expected output.
marshaller.setProperty("com.sun.xml.bind.xmlHeaders", "<?xml version=\"1.0\"?>");
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
The problem you are seeing occurs when you marshal to a Writer, which appears to be a bug in the JAXB reference implementation. You can raise an issue at the link below:
https://java.net/jira/browse/JAXB/
You could always do:
JAXBContext context;
try {
context = JAXBContext.newInstance(heartbeat.getClass());
StringWriter writer = new StringWriter();
writer.append("<?xml version=\"1.0\"?>");
Marshaller marshaller = context.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
heartbeat.setHeader(header);
heartbeat.setHeartbeatEvent(event);
marshaller.marshal(heartbeat, writer);
String stringXML = writer.toString();
return stringXML;
} catch (JAXBException e) {
throw new RuntimeException("Problems generating XML in specified "
+ "encoding, underlying problem is " + e.getMessage(),
e);
}
EclipseLink JAXB (MOXy) also supports the com.sun.xml.bind.xmlHeaders and it works correctly when marshalling to a Writer (I'm the MOXy lead)
http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html
This worked for me
marshaller.setProperty("com.sun.xml.internal.bind.xmlHeaders",
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
In JAXB 3.0.1 the above mentioned constants cause a PropertyException:
jakarta.xml.bind.PropertyException: name: com.sun.xml.bind.xmlDeclaration value: false
In this case, the XML preamble can be configured with these marshaller constants:
marshaller.setProperty("org.glassfish.jaxb.xmlHeaders", "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
https://eclipse-ee4j.github.io/jaxb-ri/3.0.0/docs/ch05.html

Java JAXB - link output to XSLT document

I am producing a XML file by the help of JAXB.
public String getPrices() {
StringWriter writer = new StringWriter();
JAXBContext context;
try {
context = JAXBContext.newInstance(AllMerchandises.class);
Marshaller m = context.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
m.marshal(this.allMerchandises, writer);
} catch (JAXBException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return writer.toString();
}
the resulting XML String looks like this.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<ns2:merchandises xmlns:ns2="example/test/workspace">
<merchandise id="1">
<name>Cat</name>
<price>50</price>
</merchandise>
<merchandise id="2">
<name>Dog</name>
<price>100</price>
</merchandise>
<merchandise id="3">
<name>Ape</name>
<price>150</price>
</merchandise>
<merchandise id="4">
<name>Gorilla</name>
<price>200</price>
</merchandise>
<merchandise id="5">
<name>Elephant</name>
<price>250</price>
</merchandise>
</ns2:merchandises>
It is my task that the document could be showed a little bit designed in a browser by using XSLT. Therefor I need to include the .xsl in my XML file. Is there a maybe a way to tell the JAXB marshaller to make a inclusion? What could I do otherwise?
I need to include sth like this as 2nd line:
<?xml-stylesheet type="text/xsl" href="myfile.xsl"?>
thanks for every good idea
Finally I ended up using the same solution as described in this thread.
Making JAXB generate an XML processing instruction

Categories