I am trying to explore and learn XSLT mapping with a pretty basic requirement though I am not sure on how to proceed.
Basically I have multiple payloads.
Payload 1
<?xml version="1.0" encoding="UTF-8" ?>
<root>
<header>
<quoteType>YQT</quoteType>
<salesOrg>5010</salesOrg>
<distributionChannel>00</distributionChannel>
<division>00</division>
<deliveryDateHeader>2022-09-29T00:00Z</deliveryDateHeader>
<shippingCondition>01</shippingCondition>
</header>
<partner>
<partnerNumber>100193</partnerNumber>
<partnerFunction>SP</partnerFunction>
</partner>
<partner>
<partnerNumber>100193</partnerNumber>
<partnerFunction>WE</partnerFunction>
</partner>
<partner>
<partnerNumber>100193</partnerNumber>
<partnerFunction>RE</partnerFunction>
</partner>
<materialsAvailibility>
<itemNumber>110</itemNumber>
<materialNumber>188521</materialNumber>
</materialsAvailibility>
</root>
Payload 2
<?xml version="1.0" encoding="UTF-8" ?>
<root>
<header>
<quoteType>YQT</quoteType>
<salesOrg>5010</salesOrg>
<distributionChannel>00</distributionChannel>
<division>00</division>
<deliveryDateHeader>2022-09-29T00:00Z</deliveryDateHeader>
<shippingCondition>01</shippingCondition>
</header>
<partner>
<partnerNumber>100193</partnerNumber>
<partnerFunction>SP</partnerFunction>
</partner>
<partner>
<partnerNumber>100193</partnerNumber>
<partnerFunction>WE</partnerFunction>
</partner>
<partner>
<partnerNumber>100193</partnerNumber>
<partnerFunction>RE</partnerFunction>
</partner>
<materialsAvailibility>
<itemNumber>10</itemNumber>
<materialNumber>115517</materialNumber>
</materialsAvailibility>
</root>
Expected Output
<?xml version="1.0" encoding="UTF-8" ?>
<root>
<header>
<quoteType>YQT</quoteType>
<salesOrg>5010</salesOrg>
<distributionChannel>00</distributionChannel>
<division>00</division>
<deliveryDateHeader>2022-09-29T00:00Z</deliveryDateHeader>
<shippingCondition>01</shippingCondition>
</header>
<partner>
<partnerNumber>100193</partnerNumber>
<partnerFunction>SP</partnerFunction>
</partner>
<partner>
<partnerNumber>100193</partnerNumber>
<partnerFunction>WE</partnerFunction>
</partner>
<partner>
<partnerNumber>100193</partnerNumber>
<partnerFunction>RE</partnerFunction>
</partner>
<materialsAvailibility>
<itemNumber>110</itemNumber>
<materialNumber>188521</materialNumber>
</materialsAvailibility>
<materialsAvailibility>
<itemNumber>10</itemNumber>
<materialNumber>115517</materialNumber>
</materialsAvailibility>
</root>
The header and partner nodes are always identical and I just need to collate the materialAvailibility together. Can someone help provide a working XSLT mapping for this and I will try to study what does the specific lines do. Thanks in advance.
CodePudding user response:
Try following powershell script. Code works without the root node.
using assembly System.Collections
using assembly System.Xml
using assembly System.Xml.Linq
$inputFilename1 = "C:\temp\test.xml"
$inputFilename2 = "C:\temp\test1.xml"
$outputFilename = "C:\temp\test2.xml"
$rSettings = New-Object System.Xml.XmlReaderSettings
$rSettings.ConformanceLevel = [System.Xml.ConformanceLevel]::Fragment
$reader1 = [System.Xml.XmlReader]::Create($inputFilename1,$rSettings)
$nodes1 = New-Object System.Collections.Generic.List[System.Xml.Linq.XElement]
while($reader1.EOF -eq $False)
{
if($reader1.IsStartElement() -eq $False) {$reader2.MoveToContent()}
$nodes1.Add([System.Xml.Linq.XElement]::ReadFrom($reader1));
}
$reader2 = [System.Xml.XmlReader]::Create($inputFilename2,$rSettings)
$nodes2 = New-Object System.Collections.Generic.List[System.Xml.Linq.XElement]
while($reader2.EOF -eq $False)
{
if($reader2.IsStartElement() -eq $False) {$reader2.MoveToContent()}
$nodes2.Add([System.Xml.Linq.XElement]::ReadFrom($reader2));
}
$materialsAvailibility2 = [System.Linq.Enumerable]::Where($nodes2, [Func[object,bool]]{ param($x) $x.Name.LocalName -eq "materialsAvailibility"})
$materialsAvailibility2 = [System.Linq.Enumerable]::First($materialsAvailibility2)
$materialsAvailibility2 = [System.Xml.Linq.XElement]$materialsAvailibility2
#Write-Host $materialsAvailibility2
$nodes1.Add($materialsAvailibility2)
$sWriter = New-Object System.IO.StreamWriter($outputFilename)
$sWriter.WriteLine("<?xml version=""1.0"" encoding=""UTF-8"" ?>");
$wSettings = New-Object System.Xml.XmlWriterSettings
$wSettings.ConformanceLevel = [System.Xml.ConformanceLevel]::Fragment
$wSettings.Indent = $True;
$xWriter = [System.Xml.XmlWriter]::Create($sWriter,$wSettings);
foreach ($node1 in $nodes1)
{
#Write-Host $node1
$node1.WriteTo($xWriter);
#Write-Host "end"
}
$xWriter.Flush();
$xWriter.Close();
CodePudding user response:
The simplest is probably
<xsl:template match="/*">
<xsl:copy>
<xsl:copy-of select="*, doc('payload2.xml')//materialsAvailability"/>
</xsl:copy>
</xsl:template>