0

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>

1 Answer 1

1

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;

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.