В приведенном ниже решении используются вложенные циклы <xsl:for-each>
, фильтрующие данные путем сопоставления различных значений элемента *_Id
.Возможно, это не самое оптимальное решение для получения желаемого результата из-за использования вложенных циклов for-each
.
Обратите внимание, что элементы в выводе, к которому был предоставлен общий доступ, принадлежат разным пространствам имен, которые не были учтены в XSLT, поскольку пространства имен отсутствуют во входных данных.Если пространства имен требуются в выходных данных и не присутствуют во входных данных, тогда XSLT придется модифицировать для обработки каждого элемента отдельно.
Кроме того, некоторые элементы в выходных данных, особенно числа, были отформатированы в выходных данных.либо для сумм (#.00
или #.0
), либо для другого числового формата, что привело к использованию copy-of
поэлементно в таких сценариях.
XSLT Solution
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" />
<xsl:strip-space elements="*" />
<xsl:template match="NewDataSet">
<DepositNotificationFile>
<xsl:copy-of select="Header" />
<xsl:apply-templates />
</DepositNotificationFile>
</xsl:template>
<xsl:template match="DepositorList">
<DepositList>
<xsl:variable name="depLstId" select="DepositList_Id" />
<!-- format reference number -->
<ReferenceNumber><xsl:value-of select="format-number(ReferenceNumber, '000000000')" /></ReferenceNumber>
<!-- create <Carrier> element and copy all children except <DepositList_Id> -->
<Carrier>
<xsl:copy-of select="../Carrier[DepositList_Id = $depLstId]/*[not(self::DepositList_Id)]" />
</Carrier>
<!-- create <Customer> element and copy all children except <DepositList_Id> -->
<Customer>
<xsl:copy-of select="../Customer[DepositList_Id = $depLstId]/*[not(self::DepositList_Id)]" />
</Customer>
<!-- loop for <ContainerList> matching <DepositList_Id> -->
<xsl:for-each select="../ContainerList[DepositList_Id = $depLstId]">
<ContainerList>
<xsl:variable name="contLstId" select="ContainerList_Id" />
<xsl:copy-of select="ContainerNumber" />
<!-- create <ContainerContentList> -->
<ContainerContentList>
<!-- loop for <ContainerContentList> matching <ContainerList_Id> -->
<xsl:for-each select="../ContainerContentList[ContainerList_Id = $contLstId]">
<xsl:variable name="contentLstId" select="ContainerContentList_Id" />
<!-- create <ContentCategory> and copy all children except <ContainerContentList_Id> -->
<ContentCategory>
<xsl:copy-of select="../ContentCategory[ContainerContentList_Id = $contentLstId]/*[not(self::ContainerContentList_Id)]" />
</ContentCategory>
<!-- create <ContentCategoryItemList> and copy, format children -->
<ContentCategoryItemList>
<ItemFaceValue><xsl:value-of select="format-number(../ContentCategoryItemList[ContainerContentList_Id = $contentLstId]/ItemFaceValue, '#.0000')" /></ItemFaceValue>
<xsl:copy-of select="../ContentCategoryItemList[ContainerContentList_Id = $contentLstId]/ItemCount" />
<DeclaredAmount><xsl:value-of select="format-number(../ContentCategoryItemList[ContainerContentList_Id = $contentLstId]/DeclaredAmount, '#.00')" /></DeclaredAmount>
<xsl:variable name="ctgyItemLstId" select="../ContentCategoryItemList[ContainerContentList_Id = $contentLstId]/ContentCategoryItemList_Id" />
<!-- create <CategoryItemUnitList> -->
<CategoryItemUnitList>
<!-- loop for <CategoryItemUnitList> matching <ContentCategoryItemList_Id> -->
<xsl:for-each select="../CategoryItemUnitList[ContentCategoryItemList_Id = $ctgyItemLstId]">
<xsl:copy-of select="InventoryUnitName | UnitQuantity" />
<UnitAmount><xsl:value-of select="format-number(UnitAmount, '#.0')" /></UnitAmount>
<xsl:copy-of select="UnitWeight | MeasurementUnit | BeginSerialNumber | Series | EndSerialNumber" />
</xsl:for-each>
</CategoryItemUnitList>
</ContentCategoryItemList>
</xsl:for-each>
</ContainerContentList>
<DeclaredAmount><xsl:value-of select="format-number(DeclaredAmount,'#.00')" /></DeclaredAmount>
</ContainerList>
</xsl:for-each>
<xsl:copy-of select="PreparedBy | TotalContainerCount | ExpectedDate" />
<DeclaredAmount><xsl:value-of select="format-number(DeclaredAmount, '#.00')" /></DeclaredAmount>
</DepositList>
</xsl:template>
<xsl:template match="text()"/>
</xsl:stylesheet>
Вывод
<DepositNotificationFile>
<Header>
<BankName>SAMA</BankName>
<CashCenterName>SAMA Riyadh</CashCenterName>
</Header>
<DepositList>
<ReferenceNumber>000000001</ReferenceNumber>
<Carrier>
<CarrierName>tns1:Commercial CIT</CarrierName>
<CarrierNumber>10001</CarrierNumber>
<CarrierLocationName>tns1:Riyadh</CarrierLocationName>
<CarrierLocationNumber>100011</CarrierLocationNumber>
<CarrierLocationRouteName>tns1:R1</CarrierLocationRouteName>
<CarrierLocationRouteNumber>R1</CarrierLocationRouteNumber>
</Carrier>
<Customer>
<AccountNumber>ISB</AccountNumber>
<LocationNumber>10065100</LocationNumber>
</Customer>
<ContainerList>
<ContainerNumber>903000033102</ContainerNumber>
<ContainerContentList>
<ContentCategory>
<ISOCurrencyCode>SAR</ISOCurrencyCode>
<InventoryType>Fit Currency</InventoryType>
<InventorySubType>Fit</InventorySubType>
</ContentCategory>
<ContentCategoryItemList>
<ItemFaceValue>5.0000</ItemFaceValue>
<ItemCount>10000</ItemCount>
<DeclaredAmount>50000.00</DeclaredAmount>
<CategoryItemUnitList>
<InventoryUnitName>Bundle</InventoryUnitName>
<UnitQuantity>10</UnitQuantity>
<UnitAmount>5000.0</UnitAmount>
<UnitWeight />
<MeasurementUnit />
<BeginSerialNumber />
<Series />
<EndSerialNumber />
</CategoryItemUnitList>
</ContentCategoryItemList>
</ContainerContentList>
<DeclaredAmount>50000.00</DeclaredAmount>
</ContainerList>
<ContainerList>
<ContainerNumber>903000033103</ContainerNumber>
<ContainerContentList>
<ContentCategory>
<ISOCurrencyCode>SAR</ISOCurrencyCode>
<InventoryType>Fit Currency</InventoryType>
<InventorySubType>Fit</InventorySubType>
</ContentCategory>
<ContentCategoryItemList>
<ItemFaceValue>10.0000</ItemFaceValue>
<ItemCount>10000</ItemCount>
<DeclaredAmount>100000.00</DeclaredAmount>
<CategoryItemUnitList>
<InventoryUnitName>Bundle</InventoryUnitName>
<UnitQuantity>10</UnitQuantity>
<UnitAmount>10000.0</UnitAmount>
<UnitWeight />
<MeasurementUnit />
<BeginSerialNumber />
<Series />
<EndSerialNumber />
</CategoryItemUnitList>
</ContentCategoryItemList>
</ContainerContentList>
<DeclaredAmount>100000.00</DeclaredAmount>
</ContainerList>
<PreparedBy>FZE</PreparedBy>
<TotalContainerCount>2</TotalContainerCount>
<ExpectedDate>2018-04-19T09:13:10-05:00</ExpectedDate>
<DeclaredAmount>150000.00</DeclaredAmount>
</DepositList>
</DepositNotificationFile>