使用 XSLT 对 XML 文件进行排序

问题描述 投票:0回答:1

我有这个 XML 文件(这只是其中的一小部分)

<?xml version="1.0" encoding="utf-8"?>   
   <InterfaceHeader Version="1" originationsystem="xxx" systemdate="2024-02-22T14:27:11"  username="xxx" testindicator="Y">
     <Warehouses>
       <Warehouse>
         <WarehouseName>WH1</WarehouseName>
         <Permits>
           <Permit>
             <LicenseNumber>R501155DK</LicenseNumber>
             <GoodsOwners>
               <GoodsOwnersIds>
                 <GoodsOwnerId>000000001</GoodsOwnerId>
                 <Items>
                   <Item>
                     <VariantSKU>5707644839038</VariantSKU>
                    <Quantity>0</Quantity>
                  </Item>
                 </Items>
               </GoodsOwnersIds>
             </GoodsOwners>
           </Permit>
         </Permits>
       </Warehouse>
       <Warehouse>
         <WarehouseName>WH2</WarehouseName>
         <Permits>
           <Permit>
             <LicenseNumber>C470413DK</LicenseNumber>
             <GoodsOwners>
               <GoodsOwnersIds>
                 <GoodsOwnerId>213456789</GoodsOwnerId>
                 <Items>
                   <Item>
                     <VariantSKU>5707644839038</VariantSKU>
                     <Quantity>93</Quantity>
                   </Item>
                 </Items>
               </GoodsOwnersIds>
             </GoodsOwners>
           </Permit>
         </Permits>
       </Warehouse>
     </Warehouses>
   </InterfaceHeader>
   <InterfaceHeader Version="1" originationsystem="xxx" systemdate="2024-02-22T14:27:34" username="xxx" testindicator="Y">
     <Warehouses>
       <Warehouse>
         <WarehouseName>WH2</WarehouseName>
         <Permits>
           <Permit>
             <LicenseNumber>R501155DK</LicenseNumber>
             <GoodsOwners>
               <GoodsOwnersIds>
                 <GoodsOwnerId>000000001</GoodsOwnerId>
                 <Items>
                  <Item>
                    <VariantSKU>5707644839076</VariantSKU>
                     <Quantity>300</Quantity>
                   </Item>
                 </Items>
               </GoodsOwnersIds>
             </GoodsOwners>
          </Permit>
        </Permits>
       </Warehouse>
       <Warehouse>
         <WarehouseName>WH2</WarehouseName>
         <Permits>
           <Permit>
             <LicenseNumber>C470413DK</LicenseNumber>
             <GoodsOwners>
               <GoodsOwnersIds>
                 <GoodsOwnerId>213456789</GoodsOwnerId>
                 <Items>
                   <Item>
                     <VariantSKU>5707644839076</VariantSKU>
                     <Quantity>2803</Quantity>
                   </Item>
                 </Items>
               </GoodsOwnersIds>
             </GoodsOwners>
           </Permit>
         </Permits>
       </Warehouse>
     </Warehouses>
   </InterfaceHeader>
   <InterfaceHeader Version="1" originationsystem"xxx" systemdate="2024-02-22T14:27:44" username="xxx" testindicator="Y">
     <Warehouses>
       <Warehouse>
         <WarehouseName>WH1</WarehouseName>
         <Permits>
           <Permit>
             <LicenseNumber>R501155DK</LicenseNumber>
             <GoodsOwners>
               <GoodsOwnersIds>
                 <GoodsOwnerId>000000001</GoodsOwnerId>
                 <Items>
                   <Item>
                     <VariantSKU>5707644727472</VariantSKU>
                     <Quantity>468</Quantity>
                   </Item>
                 </Items>
               </GoodsOwnersIds>
             </GoodsOwners>
           </Permit>
         </Permits>
       </Warehouse>
       <Warehouse>
         <WarehouseName>WH2</WarehouseName>
         <Permits>
           <Permit>
             <LicenseNumber>C470413DK</LicenseNumber>
             <GoodsOwners>
               <GoodsOwnersIds>
                 <GoodsOwnerId>213456789</GoodsOwnerId>
                 <Items>
                   <Item>
                     <VariantSKU>5707644727472</VariantSKU>
                     <Quantity>4860</Quantity>
                   </Item>
                 </Items>
               </GoodsOwnersIds>
             </GoodsOwners>
           </Permit>
         </Permits>
       </Warehouse>
     </Warehouses>
   </InterfaceHeader>

我怎样才能

  1. 删除
    InterfaceHeader
    ,这样它就只存在一次
  2. 对 XML 文件进行排序,因此
    WH1
    中的所有项目都排在前面,然后是
    WH2
    中的项目(每个仓库的许可证和所有者 ID 都相同)?

这是我正在寻找的示例:

 <InterfaceHeader Version="1" originationsystem="xxx" systemdate="2024-02-22T14:27:11" username="xxx" testindicator="Y">
   <Warehouses>
       <Warehouse>
         <WarehouseName>WH1</WarehouseName>
         <Permits>
           <Permit>
             <LicenseNumber>R501155DK</LicenseNumber>
             <GoodsOwners>
               <GoodsOwnersIds>
                 <GoodsOwnerId>000000001</GoodsOwnerId>
                 <Items>
                   <Item>
                     <VariantSKU>5707644839038</VariantSKU>
                     <Quantity>0</Quantity>
                   </Item>
                   <Item>
                     <VariantSKU>5707644839076</VariantSKU>
                     <Quantity>300</Quantity>
                   </Item>
                 </Items>
               </GoodsOwnersIds>
             </GoodsOwners>
          </Permit>
        </Permits>
       </Warehouse>
       <Warehouse>
         <WarehouseName>WH2</WarehouseName>
         <Permits>
           <Permit>
             <LicenseNumber>C470413DK</LicenseNumber>
             <GoodsOwners>
               <GoodsOwnersIds>
                 <GoodsOwnerId>213456789</GoodsOwnerId>
                 <Items>
                   <Item>
                     <VariantSKU>5707644839038</VariantSKU>
                     <Quantity>93</Quantity>
                   </Item>
                   <Item>
                     <VariantSKU>5707644839076</VariantSKU>
                     <Quantity>2803</Quantity>
                   </Item>
                 </Items>
               </GoodsOwnersIds>
             </GoodsOwners>
           </Permit>
         </Permits>
       </Warehouse>
     </Warehouses>
   </InterfaceHeader>

我试过这个:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:key name="WarehouseKey" match="InterfaceHeader" use="concat(Warehouses/Warehouse/WarehouseName, '|', @originationsystem)"/>

    <xsl:template match="/">
        <xsl:for-each select="InterfaceHeader[generate-id() = generate-id(key('WarehouseKey', concat(Warehouses/Warehouse/WarehouseName, '|', @originationsystem))[1])]">
            <xsl:sort select="Warehouses/Warehouse/WarehouseName"/>
            <xsl:copy-of select="."/>
        </xsl:for-each>
    </xsl:template>

</xsl:stylesheet>

但结果是这样的:

<?xml version="1.0" encoding="utf-8"?>
xml xslt
1个回答
0
投票

您可以使用 Powershell 脚本

using assembly System.Xml.Linq 

$inputFilename = 'c:\temp\test.xml'
$outputFilename = 'c:\temp\test1.xml'

$settings = [System.Xml.XmlReaderSettings]::New();

$settings.ConformanceLevel = [System.Xml.ConformanceLevel]::Fragment;
$reader = [System.Xml.XmlReader]::Create($inputFilename,$settings);

$whareHouses = [System.Collections.ArrayList]::new()
$count = 0;

$doc = [System.Xml.Linq.XDocument]::new()

while ($reader.EOF -eq $False)
{
   if ($reader.Name -ne 'InterfaceHeader')
   {
      $reader.ReadToFollowing('InterfaceHeader') | out-null;;
   }
   if($reader.EOF -eq $False)
   {
      $interfaceHeader = [System.Xml.Linq.XElement][System.Xml.Linq.XElement]::ReadFrom($reader);
      if($count -eq 0)
      {
         $doc.Add($interfaceHeader);
      } 
      else 
      {
         $whareHouse = $interfaceHeader.Descendants("Warehouse")[0];
         $whareHouses.Add($whareHouse) | out-null
      }
   }
   $count++;
}

$wharehouse = $doc.Descendants("Warehouses")[0];
$wharehouse.Add($wharehouses);
$doc.Save($outputFilename);
© www.soinside.com 2019 - 2024. All rights reserved.