Home > Software engineering >  Add Soap Envelope with XSL transformation
Add Soap Envelope with XSL transformation

Time:12-17

This is my source XML:

<?xml version="1.0" encoding="UTF-8" ?>
<SSC>
    <ErrorContext>
        <CompatibilityMode>1</CompatibilityMode>
        <ErrorOutput>1</ErrorOutput>
        <ErrorThreshold>1</ErrorThreshold>
    </ErrorContext>
    <User>
        <Name>LIF</Name>
    </User>
    <SunSystemsContext>
        <BusinessUnit>SHA</BusinessUnit>
    </SunSystemsContext>
    <MethodContext>
        <Transaction>
            <TransactionType>IFA</TransactionType>
        </Transaction>
    </MethodContext>
    <Payload>
            <SalesInvoice>
            <AcknowledgementAddress>4113611600</AcknowledgementAddress>
            <CompletionDate>28112022</CompletionDate>
            <CustomerCode>4113611600</CustomerCode>
            <EntryDate>28112022</EntryDate>
            <InvoiceAddressCode>4113611600</InvoiceAddressCode>
            <InvoicePeriod>0112022</InvoicePeriod>
            <MiscellaneousDescription1>Ministry of Public Order</MiscellaneousDescription1>
            <SalesDefinitionCode>IFA</SalesDefinitionCode>
            <SalesInvoiceId>13</SalesInvoiceId>
            <Status>3</Status>
            <TransactionDate>28112022</TransactionDate>
            <Line>
                <CreditStatus>0</CreditStatus>
                <CurrencyCode>LEK</CurrencyCode>
                <DeliveryAddressCode>4113611600</DeliveryAddressCode>
                <DemandQuantity>100.00000</DemandQuantity>
                <DispatchStatus>99</DispatchStatus>
                <UserLineNumber>1</UserLineNumber>
            </Line>
        </SalesInvoice>
    </Payload>
</SSC>

I need to transform it to this XML:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:doc="urn:bp:xi:dwn:rm:pf:merchant:sales:100">
    <soapenv:Header/>
    <soapenv:Body>
        <InvoiceTransmission>
            <InvoiceTransmission xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="IATAFuelInvoiceStandardv2.0.2.xsd" />
            <InvoiceTransmissionHeader>
                <InvoiceCreationDate>2022-12-16</InvoiceCreationDate>
                <Version>2.0.2</Version>
            </InvoiceTransmissionHeader>
            <Invoice>
                <InvoiceHeader>
                    <CustomerEntityID>3611600</CustomerEntityID>
                    <IssuingEntityID>-</IssuingEntityID>
                    <IssuingEntityName>Air BP Albania</IssuingEntityName>
                    <InvoiceNumber />
                </InvoiceHeader>
                <InvoiceSummary>
                    <InvoiceLineCount />
                    <TotalInvoiceLineAmount>0</TotalInvoiceLineAmount>
                    <TotalInvoiceTaxAmount>000.00</TotalInvoiceTaxAmount>
                </InvoiceSummary>
            </Invoice>
            <InvoiceTransmissionSummary>
                <InvoiceMessageCount>1</InvoiceMessageCount>
            </InvoiceTransmissionSummary>
        </InvoiceTransmission>
    </soapenv:Body>
</soapenv:Envelope>

And this is my XSL:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"   
    exclude-result-prefixes="xs xsi soapenv" version="2.0">

    <xsl:output method="xml" encoding="UTF-8" standalone="no"/>
    <xsl:strip-space elements="*" />

    <xsl:template match="/">
        <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:doc="urn:bp:xi:dwn:rm:pf:merchant:sales:100">
            <soapenv:Header/>
            <soapenv:Body>
                <InvoiceTransmission> 
                    <xsl:element name="InvoiceTransmission"> 
                        <xsl:namespace name="xsi" select="'http://www.w3.org/2001/XMLSchema-instance'" />           
                        <xsl:attribute name="xsi:noNamespaceSchemaLocation">IATAFuelInvoiceStandardv2.0.2.xsd</xsl:attribute>
                    </xsl:element>
                    <xsl:apply-templates select="SSC"/>
                </InvoiceTransmission>
            </soapenv:Body>
        </soapenv:Envelope>
    </xsl:template>

    <xsl:template match="User | SunSystemsContext | MethodContext | ErrorContext"/>

    <xsl:template match="Payload">
        <InvoiceTransmissionHeader>
            <InvoiceCreationDate>
                <xsl:value-of select="format-date(current-date(), '[Y0001]-[M01]-[D01]')" />
            </InvoiceCreationDate>
            <Version>2.0.2</Version>
        </InvoiceTransmissionHeader>

        <xsl:for-each select ="SalesInvoice">
            <Invoice>
                <InvoiceHeader>
                    <CustomerEntityID>
                        <xsl:value-of select="substring(CustomerCode, 4)" />            
                    </CustomerEntityID>  
                    <IssuingEntityID>-</IssuingEntityID>
                    <IssuingEntityName>Air BP Albania</IssuingEntityName>
                    <InvoiceNumber>
                        <xsl:value-of select="distinct-values(Line/SalesInvoiceTransactionReference)" />    
                    </InvoiceNumber>
                </InvoiceHeader>
                <InvoiceSummary>
                    <InvoiceLineCount>
                        <xsl:value-of select="max(Line/SalesInvoiceLineNumber)" />
                    </InvoiceLineCount>
                    <TotalInvoiceLineAmount>
                        <xsl:value-of select="sum(Line/VLAB18/Trans/VSilVlabEntry_Val)" />
                    </TotalInvoiceLineAmount>
                    <TotalInvoiceTaxAmount>000.00</TotalInvoiceTaxAmount>
                </InvoiceSummary>
            </Invoice>              
        </xsl:for-each>
        <InvoiceTransmissionSummary>
            <InvoiceMessageCount>1</InvoiceMessageCount>
        </InvoiceTransmissionSummary>                   
    </xsl:template> 
</xsl:stylesheet> 

Everything works fine except soapenv:Envelope element. It's copies attributes to each element, and I need them only in this one. So my final XML now looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:doc="urn:bp:xi:dwn:rm:pf:merchant:sales:100"
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Header xmlns:doc="urn:bp:xi:dwn:rm:pf:merchant:sales:100"
        xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" />
    <soapenv:Body xmlns:doc="urn:bp:xi:dwn:rm:pf:merchant:sales:100"
        xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
        <InvoiceTransmission xmlns:doc="urn:bp:xi:dwn:rm:pf:merchant:sales:100"
            xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
            <InvoiceTransmission xmlns:doc="urn:bp:xi:dwn:rm:pf:merchant:sales:100"
                xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="IATAFuelInvoiceStandardv2.0.2.xsd" />
            <InvoiceTransmissionHeader xmlns:doc="urn:bp:xi:dwn:rm:pf:merchant:sales:100"
                xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
                <InvoiceCreationDate xmlns:doc="urn:bp:xi:dwn:rm:pf:merchant:sales:100"
                    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">2022-12-16</InvoiceCreationDate>
                <Version xmlns:doc="urn:bp:xi:dwn:rm:pf:merchant:sales:100"
                    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">2.0.2</Version>
            </InvoiceTransmissionHeader>
            <Invoice xmlns:doc="urn:bp:xi:dwn:rm:pf:merchant:sales:100"
                xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
                <InvoiceHeader xmlns:doc="urn:bp:xi:dwn:rm:pf:merchant:sales:100"
                    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
                    <CustomerEntityID xmlns:doc="urn:bp:xi:dwn:rm:pf:merchant:sales:100"
                        xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">3611600</CustomerEntityID>
                    <IssuingEntityID xmlns:doc="urn:bp:xi:dwn:rm:pf:merchant:sales:100"
                        xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">-</IssuingEntityID>
                    <IssuingEntityName xmlns:doc="urn:bp:xi:dwn:rm:pf:merchant:sales:100"
                        xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">Air BP Albania</IssuingEntityName>
                    <InvoiceNumber xmlns:doc="urn:bp:xi:dwn:rm:pf:merchant:sales:100"
                        xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" />
                </InvoiceHeader>
                <InvoiceSummary xmlns:doc="urn:bp:xi:dwn:rm:pf:merchant:sales:100"
                    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
                    <InvoiceLineCount xmlns:doc="urn:bp:xi:dwn:rm:pf:merchant:sales:100"
                        xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" />
                    <TotalInvoiceLineAmount xmlns:doc="urn:bp:xi:dwn:rm:pf:merchant:sales:100"
                        xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">0</TotalInvoiceLineAmount>
                    <TotalInvoiceTaxAmount xmlns:doc="urn:bp:xi:dwn:rm:pf:merchant:sales:100"
                        xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">000.00</TotalInvoiceTaxAmount>
                </InvoiceSummary>
            </Invoice>
            <InvoiceTransmissionSummary xmlns:doc="urn:bp:xi:dwn:rm:pf:merchant:sales:100"
                xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
                <InvoiceMessageCount xmlns:doc="urn:bp:xi:dwn:rm:pf:merchant:sales:100"
                    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">1</InvoiceMessageCount>
            </InvoiceTransmissionSummary>
        </InvoiceTransmission>
    </soapenv:Body>
</soapenv:Envelope>

Please what should I change to get my desired result? For transformation I have .NET program written using Saxon 10.8.

.NET main function:

using System;
using Saxon.Api;
using System.IO;
using System.Xml;
using System.Text;
using java.nio.file;

namespace TestingXsl
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string data = "";
            string req = "";
            string file = "pokus_so.xml";
            string fileSAP = "out.xml";
           
            XsltTransformator trans = new XsltTransformator("transform_so.xsl");

            data=File.ReadAllText(file, Encoding.UTF8); //where file is input XML path
            req=trans.TransformString(data);

            File.WriteAllText(fileSAP, req, Encoding.UTF8); //where fileSAP is output XML path
        }
    }
}

.NET XsltTransformator class

using Saxon.Api;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace TestingXsl
{
    public class XsltTransformator
    {
        XsltTransformer saxon;

        public XsltTransformator(string xsltTemplate)
        {
            Processor saxProc = new Processor();
            XsltCompiler saxComp = saxProc.NewXsltCompiler();

            XmlReader xr = XmlReader.Create(xsltTemplate);
            XsltExecutable saxExec = saxComp.Compile(xr);

            saxon = saxExec.Load();
        }

        public void TransformFile(string inFile, string outFile)
        {
            Stream sr = new FileStream(inFile, FileMode.Open);
            saxon.SetInputStream(sr, new Uri("http://testing.com"));

            XmlWriter xmw = XmlWriter.Create(outFile);
            TextWriterDestination twd = new TextWriterDestination(xmw);

            saxon.Run(twd);
            twd.close();
            xmw.Close();
        }

        public string TransformString(string inData)
        {
            Stream sr = new MemoryStream();
            StreamWriter sw = new StreamWriter(sr);
            sw.Write(inData);
            sw.Flush();
            sr.Position = 0;

            saxon.SetInputStream(sr, new Uri("http://testing.com"));

            StringBuilder sb = new StringBuilder();
            XmlWriterSettings xws = new XmlWriterSettings();
            xws.OmitXmlDeclaration = true;
            XmlWriter xmw = XmlWriter.Create(sb, xws);
            //XmlWriter xmw = XmlWriter.Create(sb, new XmlWriterSettings { Encoding=Encoding.UTF8});            
            TextWriterDestination twd = new TextWriterDestination(xmw);

            saxon.Run(twd);
            twd.close();
            xmw.Close();

            string xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n"   sb.ToString();

            return xml;
        }

    }

}

CodePudding user response:

This is a known bug in Saxon 10 for .NET

https://saxonica.plan.io/issues/5565

Sorry about it. We are planning to produce another maintenance release which will fix this, but the task hasn't made it to the top of our list.

  • Related