phax / ph-ubl

Java library for reading and writing UBL 2.0, 2.1, 2.2, 2.3 and 2.4 (CS01) documents

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Question: Namespaces in DianExtension

r-vasquez opened this issue · comments

Hi Phillip,

I'm using ph-ubl21 and ph-ubl-dian @6.5.0 to generate an invoice like the one in CreateInvoiceFromScratchFuncTest.java

To add the DianExtension I followed the advice from #30 (comment) like:

       ....

        // https://github.com/phax/ph-ubl/issues/30 -> convert to DOM element Dian UBL Extension
        final JAXBContext jc = JAXBContext.newInstance(DianExtensionsType.class);

        // Creating the Document object to wrap DianExtension element
        final DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
        final Document dianDocument = dbf.newDocumentBuilder().newDocument();
        final Marshaller marshaller = jc.createMarshaller();

        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        marshaller.marshal(new JAXBElement<>(new QName("dian:gov:co:facturaelectronica:Structures-2-1", "DianExtensions", "sts"), DianExtensionsType.class, dianExtension), dianDocument);

        final UBLExtensionsType ublExtensions = new UBLExtensionsType();
        final UBLExtensionType ublExtension = new UBLExtensionType();
        final ExtensionContentType extensionContent = new ExtensionContentType();

        extensionContent.setAny(dianDocument.getDocumentElement());
 
       ...

        final UBL21WriterBuilder<InvoiceType> aBuilder = UBL21Writer.invoice();
        final MapBasedNamespaceContext aNsCtx = UBL21NamespaceContext.getInstance().getClone();
        aNsCtx.addDefaultNamespaceURI("urn:oasis:names:specification:ubl:schema:xsd:Invoice-2");
        aNsCtx.removeMapping("cec");
        aNsCtx.addMapping("ext", "urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2");
        aBuilder.setNamespaceContext(aNsCtx);

        // Write to disk (We can use a DianUBLWriter that checks the content)
        final ESuccess eSuccess = aBuilder.write(aInvoice, new File("somefilepath.xml"));

This generates:

<?xml version="1.0" encoding="UTF-8"?>
<Invoice xmlns:cac="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
         xmlns:ext="urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2"
         xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
         xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
    <ext:UBLExtensions>
        <ext:UBLExtension>
            <ext:ExtensionContent>
                <DianExtensions xmlns:ns3="urn:oasis:names:specification:ubl:schema:xsd:CommonAggregateComponents-2"
                                xmlns:ns2="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
                                xmlns="dian:gov:co:facturaelectronica:Structures-2-1">
                    <InvoiceControl>
                        <InvoiceAuthorization>18760000001</InvoiceAuthorization>
                        <AuthorizationPeriod>
                            <ns2:StartDate>2019-01-19Z</ns2:StartDate>
                            <ns2:EndDate>2030-01-19Z</ns2:EndDate>
                        </AuthorizationPeriod>
                        ...
                        ...

My question is:

  • Is it ok to generate a new Namespace (ns2 & ns3) in the DianExtension even if the namespace is already defined in the root (cbc & cac) ? Do you know how can I modify/fix this?

  • I understand that defining the defaultNamespace in DianExtension will not have any difference from defining it from the root, is that right ?

Thanks a lot for your time and work with this library, it has helped me a lot.

Hi Rogger,
from an XML perspective it doesn't matter if the prefix is called "ns2", "dian" or "hugo".
As long as this prefix is mapped to the same URL (e.g. urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2) the XML is considered semantically equal.
But I heard, that DIAN enforces some specific requirements on the namespace prefix if I am not mistaken - I don't know the details. Sorry.

Search through the closed issues for resolutions on how to change the namespaces.

Thanks for the response,

if you see I changed the namespace of cec to ext for this reason using the closed issues examples:

        aNsCtx.addDefaultNamespaceURI("urn:oasis:names:specification:ubl:schema:xsd:Invoice-2");
        aNsCtx.removeMapping("cec");
        aNsCtx.addMapping("ext", "urn:oasis:names:specification:ubl:schema:xsd:CommonExtensionComponents-2");
        aBuilder.setNamespaceContext(aNsCtx);

But since I created a DianExtensionsType instance, marshal it to a DOM Element and then pass the Element to setAny, I cannot control the namespace of this DOM Element from the NamespaceContext from UBL21NamespaceContext instance.

Is there another way to pass the Dian UBLExtension to setAny without having to marshal it to a DOM instance?

I get what you mean, and I found no way to marshal the "xs:any" element with the correct namespace URI.

I found the problem - the namespace maper was manually overriding the Dian namespace with the default prefix. This will be fixed in 6.6.1