Reputation: 1499
I have to build an XML file from a java object in a java maven project. I have a class named CrossIndustryInvoice with XML annotations.
@Data
@Builder
@AllArgsConstructor @NoArgsConstructor
@XmlRootElement(name="CrossIndustryInvoice", namespace = NamespaceMapper.RSM_URI)
@XmlAccessorType(XmlAccessType.FIELD)
public
class CrossIndustryInvoice {
@XmlElement(name = "ExchangedDocumentContext", namespace = NamespaceMapper.RSM_URI)
private ExchangedDocumentContext exchangedDocumentContext;
@XmlElement(name = "ExchangedDocument", namespace = NamespaceMapper.RSM_URI)
private ExchangedDocument exchangedDocument;
@XmlElement(name = "SupplyChainTradeTransaction", namespace = NamespaceMapper.RSM_URI)
private SupplyChainTradeTransaction supplyChainTradeTransaction;
}
I also created a class named NamespaceMapper where i define the different namespaces used in my XML
public class NamespaceMapper extends NamespacePrefixMapper {
public static final String QDT_PREFIX = "qdt"; // DEFAULT NAMESPACE
public static final String QDT_URI = "urn:un:unece:uncefact:data:standard:QualifiedDataType:100";
public static final String RAM_PREFIX = "ram"; // DEFAULT NAMESPACE
public static final String RAM_URI = "urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100";
public static final String RSM_PREFIX = "rsm"; // DEFAULT NAMESPACE
public static final String RSM_URI = "urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100";
public static final String UDT_PREFIX = "udt"; // DEFAULT NAMESPACE
public static final String UDT_URI = "urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100";
public static final String XSI_PREFIX = "xsi"; // DEFAULT NAMESPACE
public static final String XSI_URI = "http://www.w3.org/2001/XMLSchema-instance";
@Override
public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) {
if(QDT_PREFIX.equals(namespaceUri)) {
return QDT_PREFIX;
}
if(RAM_PREFIX.equals(namespaceUri)) {
return RAM_PREFIX;
}
if(RSM_PREFIX.equals(namespaceUri)) {
return RSM_PREFIX;
}
if(UDT_PREFIX.equals(namespaceUri)) {
return UDT_PREFIX;
}
if(XSI_PREFIX.equals(namespaceUri)) {
return XSI_PREFIX;
}
return suggestion;
}
@Override
public String[] getPreDeclaredNamespaceUris() {
return new String[] { QDT_URI, RAM_URI, RSM_URI, UDT_URI, XSI_URI };
}
}
I also created a package-info.java file
@XmlSchema(
elementFormDefault= XmlNsForm.QUALIFIED,
namespace="http://www.example.com/FOO",
xmlns={
@XmlNs(
prefix="ns1",
namespaceURI="http://www.example.com/FOO"),
@XmlNs(
prefix="qdt",
namespaceURI="urn:un:unece:uncefact:data:standard:QualifiedDataType:100"),
@XmlNs(
prefix="ram",
namespaceURI="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"),
@XmlNs(
prefix="rsm",
namespaceURI="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"),
@XmlNs(
prefix="udt",
namespaceURI="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100"),
@XmlNs(
prefix="xsi",
namespaceURI="http://www.w3.org/2001/XMLSchema-instance"),
}
)
package fr.dsidiff.app.ui.model.request.metadata;
import javax.xml.bind.annotation.XmlNs;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
In my application, I do have a method that converts Java Object to XML String.
private String payloadToXml(CrossIndustryInvoice invoice) throws JAXBException {
//Create JAXB Context
JAXBContext ctx = null;
try {
ctx = JAXBContext.newInstance(CrossIndustryInvoice.class);
Marshaller jaxbMarshaller = ctx.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
StringWriter sw = new StringWriter();
jaxbMarshaller.marshal(invoice, sw);
return sw.toString();
} catch (JAXBException e) {
e.printStackTrace();
throw new JAXBException("Oops something went wrong");
}
}
My problem is that the XML i generate is invalid and namespaces are not matching.
here is a sample of XML I obtain :
<ns2:CrossIndustryInvoice xmlns="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100" xmlns:ns2="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100" xmlns:ns4="urn:un:unece:uncefact:data:standard:QualifiedDataType:100" xmlns:ns3="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100">
<ns2:ExchangedDocumentContext>
<BusinessProcessSpecifiedDocumentContextParameter>
<ID>A1</ID>
</BusinessProcessSpecifiedDocumentContextParameter>
<GuidelineSpecifiedDocumentContextParameter>
<ID>urn:factur-x.eu:1p0:basicwl</ID>
</GuidelineSpecifiedDocumentContextParameter>
</ns2:ExchangedDocumentContext>
While i should get something different:
<?xml version='1.0' encoding='UTF-8'?>
<rsm:CrossIndustryInvoice xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:100"
xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100"
xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100"
xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<rsm:ExchangedDocumentContext>
<ram:BusinessProcessSpecifiedDocumentContextParameter>
<ram:ID>A1</ram:ID>
</ram:BusinessProcessSpecifiedDocumentContextParameter>
<ram:GuidelineSpecifiedDocumentContextParameter>
<ram:ID>urn:factur-x.eu:1p0:basicwl</ram:ID>
</ram:GuidelineSpecifiedDocumentContextParameter>
</rsm:ExchangedDocumentContext>
Upvotes: 0
Views: 794
Reputation: 1499
I didn't pay attention to the import. In my pom.xml I added the following dependency:
<!-- https://mvnrepository.com/artifact/com.sun.xml.bind/jaxb-impl -->
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>2.0.1</version>
</dependency>
In my NamespaceMapper class I was using the following import
import com.sun.xml.bind.marshaller.NamespacePrefixMapper;
I replaced it with :
import com.sun.xml.internal.bind.marshaller.NamespacePrefixMapper;
Upvotes: 1