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.