根据输出xml修改xslt

时间:2018-05-22 06:07:46

标签: c# xml xslt

我正在尝试修改我的XSLT以获得所需的输出。列出所需的输入XML,输出XML和XSLT文件。

这是我的输入XML

<NewDataSet>
    <Header>
        <BankName>SAMA</BankName>
        <CashCenterName>SAMA Riyadh</CashCenterName>
    </Header>
    <DepositorList>
        <ReferenceNumber>1</ReferenceNumber>
        <DepositList_Id>0</DepositList_Id>
        <PreparedBy>FZE</PreparedBy>
        <TotalContainerCount>2</TotalContainerCount>
        <ExpectedDate>2018-04-19T09:13:10-05:00</ExpectedDate>
        <DeclaredAmount>150000</DeclaredAmount>
    </DepositorList>
    <Carrier>
        <CarrierName>tns1:Commercial CIT</CarrierName>
        <CarrierNumber>10001</CarrierNumber>
        <CarrierLocationName>tns1:Riyadh</CarrierLocationName>
        <CarrierLocationNumber>100011</CarrierLocationNumber>
        <CarrierLocationRouteName>tns1:R1</CarrierLocationRouteName>
        <CarrierLocationRouteNumber>R1</CarrierLocationRouteNumber>
        <DepositList_Id>0</DepositList_Id>
    </Carrier>
    <Customer>
        <AccountNumber>ISB</AccountNumber>
        <LocationNumber>10065100</LocationNumber>
        <DepositList_Id>0</DepositList_Id>
    </Customer>
    <ContainerList>
        <ContainerNumber>903000033102</ContainerNumber>
        <ContainerList_Id>0</ContainerList_Id>
        <DeclaredAmount>50000</DeclaredAmount>
        <DepositList_Id>0</DepositList_Id>
    </ContainerList>
    <ContainerList>
        <ContainerNumber>903000033103</ContainerNumber>
        <ContainerList_Id>1</ContainerList_Id>
        <DeclaredAmount>100000</DeclaredAmount>
        <DepositList_Id>0</DepositList_Id>
    </ContainerList>
    <ContainerContentList>
        <ContainerContentList_Id>0</ContainerContentList_Id>
        <TotalRecordCount>1</TotalRecordCount>
        <ContainerList_Id>0</ContainerList_Id>
    </ContainerContentList>
    <ContainerContentList>
        <ContainerContentList_Id>1</ContainerContentList_Id>
        <TotalRecordCount>1</TotalRecordCount>
        <ContainerList_Id>1</ContainerList_Id>
    </ContainerContentList>
    <ContentCategory>
        <ISOCurrencyCode>SAR</ISOCurrencyCode>
        <InventoryType>Fit Currency</InventoryType>
        <InventorySubType>Fit</InventorySubType>
        <ContainerContentList_Id>0</ContainerContentList_Id>
    </ContentCategory>
    <ContentCategory>
        <ISOCurrencyCode>SAR</ISOCurrencyCode>
        <InventoryType>Fit Currency</InventoryType>
        <InventorySubType>Fit</InventorySubType>
        <ContainerContentList_Id>1</ContainerContentList_Id>
    </ContentCategory>
    <ContentCategoryItemList>
        <ItemFaceValue>5</ItemFaceValue>
        <ItemCount>10000</ItemCount>
        <DeclaredAmount>50000</DeclaredAmount>
        <ContentCategoryItemList_Id>0</ContentCategoryItemList_Id>
        <ContainerContentList_Id>0</ContainerContentList_Id>
    </ContentCategoryItemList>
    <ContentCategoryItemList>
        <ItemFaceValue>10</ItemFaceValue>
        <ItemCount>10000</ItemCount>
        <DeclaredAmount>100000</DeclaredAmount>
        <ContentCategoryItemList_Id>1</ContentCategoryItemList_Id>
        <ContainerContentList_Id>1</ContainerContentList_Id>
    </ContentCategoryItemList>
    <CategoryItemUnitList>
        <InventoryUnitName>Bundle</InventoryUnitName>
        <UnitQuantity>10</UnitQuantity>
        <UnitAmount>5000</UnitAmount>
        <UnitWeight />
        <MeasurementUnit />
        <BeginSerialNumber />
        <Series />
        <EndSerialNumber />
        <ContentCategoryItemList_Id>0</ContentCategoryItemList_Id>
    </CategoryItemUnitList>
    <CategoryItemUnitList>
        <InventoryUnitName>Bundle</InventoryUnitName>
        <UnitQuantity>10</UnitQuantity>
        <UnitAmount>10000</UnitAmount>
        <UnitWeight />
        <MeasurementUnit />
        <BeginSerialNumber />
        <Series />
        <EndSerialNumber />
        <ContentCategoryItemList_Id>1</ContentCategoryItemList_Id>
    </CategoryItemUnitList>
</NewDataSet>

我正在寻找的输出是

<?xml version="1.0" encoding="UTF-8"?>
<tns:DepositNotificationFile xsi:schemaLocation="http://www.gide.com/vmsng/integration/dn/schema/message DepositNotification.messages.xsd " xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tns1="http://www.gide.com/vmsng/integration/dn/schema/type" xmlns:tns="http://www.gide.com/vmsng/integration/dn/schema/message">
 <tns:Header>
     <tns1:BankName>SAMA</tns1:BankName>
     <tns1:CashCenterName>SAMA Riyadh</tns1:CashCenterName>
 </tns:Header>
 <tns:DepositList>
      <tns1:ReferenceNumber>00000001</tns1:ReferenceNumber>
 <tns1:Carrier>
      <tns1:CarrierName>tns1:Commercial CIT</tns1:CarrierName>
      <tns1:CarrierNumber>10001</tns1:CarrierNumber>
      <tns1:CarrierLocationName>tns1:Riyadh</tns1:CarrierLocationName>
      <tns1:CarrierLocationNumber>100011</tns1:CarrierLocationNumber>
      <tns1:CarrierLocationRouteName>tns1:R1</tns1:CarrierLocationRouteName>
      <tns1:CarrierLocationRouteNumber>R1</tns1:CarrierLocationRouteNumber>
 </tns1:Carrier>
 <tns1:Customer>
      <tns1:AccountNumber>ISB</tns1:AccountNumber>
      <tns1:LocationNumber>10065100</tns1:LocationNumber>
 </tns1:Customer>
 <tns1:ContainerList>
      <tns1:ContainerNumber>903000033102</tns1:ContainerNumber>
      <tns1:ContainerContentList>
           <tns1:ContentCategory>
                <tns1:ISOCurrencyCode>SAR</tns1:ISOCurrencyCode>
                <tns1:InventoryType>Fit Currency</tns1:InventoryType>
                <tns1:InventorySubType>Fit</tns1:InventorySubType>
           </tns1:ContentCategory>
           <tns1:ContentCategoryItemList>
                <tns1:ItemFaceValue>5.0000</tns1:ItemFaceValue>
                <tns1:ItemCount>10000</tns1:ItemCount>
                <tns1:DeclaredAmount>50000.00</tns1:DeclaredAmount>
                <tns1:CategoryItemUnitList>
                     <tns1:InventoryUnitName>Bundle</tns1:InventoryUnitName>
                     <tns1:UnitQuantity>10</tns1:UnitQuantity>
                     <tns1:UnitAmount>5000.0</tns1:UnitAmount>
                     <tns1:UnitWeight/>
                     <tns1:MeasurementUnit/>
                     <tns1:BeginSerialNumber/>
                     <tns1:Series/>
                     <tns1:EndSerialNumber/>
               </tns1:CategoryItemUnitList>
          </tns1:ContentCategoryItemList>
          <tns1:TotalRecordCount>1</tns1:TotalRecordCount>
     </tns1:ContainerContentList>
     <tns1:DeclaredAmount>50000.00</tns1:DeclaredAmount>
  </tns1:ContainerList>
  <tns1:ContainerList>
       <tns1:ContainerNumber>903000033103</tns1:ContainerNumber>
       <tns1:ContainerContentList>
            <tns1:ContentCategory>
                 <tns1:ISOCurrencyCode>SAR</tns1:ISOCurrencyCode>
                 <tns1:InventoryType>Fit Currency</tns1:InventoryType>
                 <tns1:InventorySubType>Fit</tns1:InventorySubType>
            </tns1:ContentCategory>
            <tns1:ContentCategoryItemList>
                 <tns1:ItemFaceValue>10.0000</tns1:ItemFaceValue>
                 <tns1:ItemCount>10000</tns1:ItemCount>
                 <tns1:DeclaredAmount>100000.00</tns1:DeclaredAmount>
                 <tns1:CategoryItemUnitList>
                              <tns1:InventoryUnitName>Bundle</tns1:InventoryUnitName>
                      <tns1:UnitQuantity>10</tns1:UnitQuantity>
                      <tns1:UnitAmount>10000.0</tns1:UnitAmount>
                      <tns1:UnitWeight/>
                      <tns1:MeasurementUnit/>
                      <tns1:BeginSerialNumber/>
                      <tns1:Series/>
                      <tns1:EndSerialNumber/>
                 </tns1:CategoryItemUnitList>
           </tns1:ContentCategoryItemList>
           <tns1:TotalRecordCount>1</tns1:TotalRecordCount>
     </tns1:ContainerContentList>
     <tns1:DeclaredAmount>100000.00</tns1:DeclaredAmount>
  </tns1:ContainerList>
  <tns1:PreparedBy>FZE</tns1:PreparedBy>
  <tns1:TotalContainerCount>2</tns1:TotalContainerCount>
  <tns1:ExpectedDate>2018-04-19T09:13:10-05:00</tns1:ExpectedDate>
  <tns1:DeclaredAmount>150000.00</tns1:DeclaredAmount>
 </tns:DepositList>
</tns:DepositNotificationFile>

请建议正确的XSLT以获得正确的结果:

到目前为止我目前的XSLT

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="/NewDataSet">
        <NewDataSet>
            <xsl:copy-of select="Header"/>
            <xsl:for-each select="DepositorList">
                <DepositorList>
                    <xsl:variable name="DepositList_Id">
                        <xsl:value-of select="DepositList_Id"/>
                    </xsl:variable>
                    <xsl:variable name="ContainerList_Id">
                        <xsl:value-of select="../ContainerList[DepositList_Id=$DepositList_Id]/ContainerList_Id"/>
                    </xsl:variable>
                    <xsl:variable name="ContainerContentList_Id">
                        <xsl:value-of select="../ContainerContentList[ContainerList_Id=$DepositList_Id]/ContainerList_Id/ContainerContentList_Id"/>
                    </xsl:variable>
                    <xsl:copy-of select="*"/>
                    <xsl:copy-of select="../ContainerList[DepositList_Id=$DepositList_Id]"/>                                           
                    <xsl:copy-of select="../ContainerContentList[ContainerList_Id=$ContainerList_Id]"/>             
                </DepositorList>
            </xsl:for-each>
        </NewDataSet>
    </xsl:template>
</xsl:stylesheet>

1 个答案:

答案 0 :(得分:1)

以下解决方案使用嵌套的<xsl:for-each>循环,通过匹配不同的*_Id元素值来过滤数据。由于使用嵌套的for-each循环,它可能不是获得所需输出的最佳解决方案。

请注意,已共享的输出中的元素属于不同的名称空间,这些名称空间在XSLT中未被考虑,因为输入中不存在名称空间。如果输出中需要名称空间而输入中不存在名称空间,则必须修改XSLT以分别处理每个元素。

此外,输出中的某些元素(尤其是数字)已在输出中格式化为金额(#.00#.0)或不同的数字格式,这导致使用{{在这种情况下,1}}元素明智。

XSLT解决方案

copy-of

输出

<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>