Search code examples
xmlabap-st

Wrong namespace binding during ST transformation serialization


I have a Simple Transformation to create an XML file like this:

<?xml version="1.0" encoding="utf-16"?>
<ORDEREXPORT xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
    xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
    xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <cbc:EXPORTDATE>2020-07-21</cbc:EXPORTDATE>
  <cbc:EXPORTTIME>10:10:46</cbc:EXPORTTIME>
  <xs:EXPORTUSER>STACKY</xs:EXPORTUSER>
</ORDEREXPORT>

But my transformation generates a file like this:

<?xml version="1.0" encoding="utf-16"?>
<ORDEREXPORT xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
    <cbc:EXPORTDATE xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">2020-07-21</cbc:EXPORTDATE>
    <cbc:EXPORTTIME xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2">10:10:46</cbc:EXPORTTIME>
    <xs:EXPORTUSER xmlns:xs="http://www.w3.org/2001/XMLSchema">STACKY</xs:EXPORTUSER>
</ORDEREXPORT>

I want all namespaces to be located in the <ORDEREXPORT> element.

How can I make this happen?

My transformation:

<?sap.transform simple?>
<tt:transform xmlns:tt="http://www.sap.com/transformation-templates"
    xmlns:ddic="http://www.sap.com/abapxml/types/dictionary"
    xmlns:def="http://www.sap.com/abapxml/types/defined">
  <tt:root name="ORDEREXPORT" type="ddic:ZORDEREXPORT_TYPE"/>
  <tt:template match="NewDataSet">
    <ORDEREXPORT xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2" >
      <cbc:EXPORTDATE tt:value-ref=".ORDEREXPORT.EXPORTDATE"/>
      <cbc:EXPORTTIME tt:value-ref=".ORDEREXPORT.EXPORTTIME"/>
      <xs:EXPORTUSER tt:value-ref=".ORDEREXPORT.EXPORTUSER"/>
    </ORDEREXPORT>
  </tt:template>
</tt:transform>

Solution

  • Both XML files are syntactically equivalent (and correct).

    SAP don't explain the logic how the XML namespaces are assigned, but it's somewhat not important because the syntax is correct in the end.

    Eventually one possibility is to define false attributes cbc:dummy="" xs:dummy="" in the tag <ORDEREXPORT>, that forces the namespace to be defined at this element, and remove cbc:dummy="" xs:dummy="" via ABAP after the transformation.

    Transformation with the dummy attributes:

    <?sap.transform simple?>
    <tt:transform xmlns:tt="http://www.sap.com/transformation-templates"
        xmlns:ddic="http://www.sap.com/abapxml/types/dictionary"
        xmlns:def="http://www.sap.com/abapxml/types/defined">
      <tt:root name="ORDEREXPORT" type="ddic:ZORDEREXPORT_TYPE"/>
      <tt:template match="NewDataSet">
        <ORDEREXPORT xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
            xmlns:xs="http://www.w3.org/2001/XMLSchema"
            xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
            xs:dummy="" cbc:dummy="" >
          <cbc:EXPORTDATE tt:value-ref=".ORDEREXPORT.EXPORTDATE"/>
          <cbc:EXPORTTIME tt:value-ref=".ORDEREXPORT.EXPORTTIME"/>
          <xs:EXPORTUSER tt:value-ref=".ORDEREXPORT.EXPORTUSER"/>
        </ORDEREXPORT>
      </tt:template>
    </tt:transform>
    

    Obtained file right after transformation (in ABAP 7.52), including the dummy attributes:

    <?xml version="1.0" encoding="utf-16"?>
    <ORDEREXPORT xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2"
        xmlns:cbc="urn:oasis:names:specification:ubl:schema:xsd:CommonBasicComponents-2"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xs:dummy="" cbc:dummy="">
      <cbc:EXPORTDATE>2020-07-21</cbc:EXPORTDATE>
      <cbc:EXPORTTIME>10:10:46</cbc:EXPORTTIME>
      <xs:EXPORTUSER>STACKY</xs:EXPORTUSER>
    </ORDEREXPORT>
    

    ABAP code to call the transformation and remove the dummy attributes:

    DATA(ls_orderexport) = VALUE zorderexport_type( 
        exportdate = '20200721' exporttime = '101046' exportuser = 'STACKY' ).
    
    DATA string TYPE string.
    CALL TRANSFORMATION z_transfo_name 
        SOURCE orderexport = ls_orderexport
        RESULT XML string.
    
    REPLACE 'xs:dummy="" cbc:dummy=""' IN string WITH ``.