XSLT 1.0 复制并删除节点

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

我必须复制一个节点(Set_Item/ForwarderReferenceNumber)以防倍增,然后删除我们从中获取值的节点“Set_Item”。

要查找相同的 Set_Item(但不同的 ForwarderReferenceNumer),我们必须使用“Set_Item/GTIN”)。 -> 因此,在我的示例中,我们可以看到“LineNum”2 和 7 的“GTIN”相同 (555),现在我们必须将第 7 行的“Set_Item/ForwarderReferenceNumber”复制到该行的“Set_Item/ForwarderReferenceNumber”下方2 然后用“LineNum”删除“Set_Item”的完整节点 7.

XML 示例:

<OSTRPT>
  <LineInformation>  
    <Set_Item>
      <LineNum>2</LineNum>
      <GTIN>555</GTIN>      
      <Quantity>1.00</Quantity>
      <MeasureUnit>PCE</MeasureUnit>
      <DeliveryDate>2024-03-13</DeliveryDate>
      <Status>24</Status>     
      <ForwarderReferenceNumber>666</ForwarderReferenceNumber>  
      <Date>2</Date>          
    </Set_Item>
    <Set_Item>
      <LineNum>7</LineNum>
      <GTIN>555</GTIN>     
      <Quantity>1.00</Quantity>
      <MeasureUnit>PCE</MeasureUnit>
      <DeliveryDate>2024-03-13</DeliveryDate>
      <Status>24</Status>      
      <ForwarderReferenceNumber>777</ForwarderReferenceNumber> 
      <Date>3</Date>          
    </Set_Item>
  </LineInformation>
</OSTRPT>

这应该是正确的输出:

<OSTRPT>
  <LineInformation>  
    <Set_Item>
      <LineNum>2</LineNum>
      <GTIN>555</GTIN>      
      <Quantity>1.00</Quantity>
      <MeasureUnit>PCE</MeasureUnit>
      <DeliveryDate>2024-03-13</DeliveryDate>
      <Status>24</Status>     
      <ForwarderReferenceNumber>666</ForwarderReferenceNumber>
      <ForwarderReferenceNumber>777</ForwarderReferenceNumber> 
      <Date>2</Date>      
    </Set_Item>
  </LineInformation>
</OSTRPT>

这是我当前的 xslt。 (但这种情况没有解决方案)

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:exsl="http://exslt.org/common" extension-element-prefixes="exsl">

 <xsl:output method="xml" indent="yes" encoding="UTF-8"/>
 
  <xsl:strip-space elements="*" />

    <xsl:template match="/">   
        <xsl:choose>
            <xsl:when test="//LineInformation[not(Item)] and //LineInformation[not(Set_Item)]"></xsl:when>
            <xsl:when test="not(//Set_Item) and not(//Item)"></xsl:when>
                <xsl:otherwise> <xsl:apply-templates select="@* | node()"/></xsl:otherwise>
        </xsl:choose>
    </xsl:template>

  <xsl:key name="header_text" match="HeaderText" use="Text"/>
  <xsl:key name="line_text" match="LineText" use="concat(../LineNum, '|', Text)"/>
  <xsl:key name="allowance_charge_header" match="AllowanceOrCharge_Header" use="concat(Code, '|', Amount)"/>
  <xsl:key name="allowance_charge_line" match="AllowanceOrCharge_Line" use="concat(../LineNum, '|', Code, '|', Amount)"/>
  <xsl:key name="packing_slip" match="ItemDeliveryInformation" use="concat(../LineNum, '|', PackingSlipId, '|', DeliveryDate, '|', DeliveredQuantity)"/>
  <xsl:key name="item" match="Item" use="concat(LineNum, '|', GTIN, '|', SupplierArticleNumber, '|', Quantity)"/>
  <xsl:key name="set_item" match="Set_Item" use="concat(LineNum, '|', GTIN, '|', SupplierArticleNumber, '|', ForwarderReferenceNumber)"/>
  <xsl:key name="WeightAndVolume" match="WeightAndVolume" use="Weight_RecId"/>
  <xsl:key name="ContainerInformation" match="ContainerInformation" use="SSCC_RecId"/>
  <xsl:key name="ContainerInformation_Set_Item" match="ContainerInformation_Set_Item" use="SSCC"/>

  <!-- Identity-Template für die nicht explizit benannten Elemente -->
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

    <xsl:template match="//Forwarder/Code[//Forwarder/Country = 'DE' and //Forwarder/Name[contains(., 'GLS')]]">
        <Code>5</Code>       
    </xsl:template>
  
  <!-- Entfernt alles nach und inkl. "_" -->
  <xsl:template match="GLN[contains(., '_')]">
    <GLN><xsl:value-of select="substring-before(., '_')"/></GLN>
  </xsl:template>
  
  <!-- Entfernt alles nach und inkl. "_" -->
  <xsl:template match="Recipient[contains(., '_')]">
    <Recipient><xsl:value-of select="substring-before(., '_')"/></Recipient>
  </xsl:template>
  
      <xsl:template match="ItemDeliveryInformation_Set_Item">        
        <xsl:element name="ItemDeliveryInformation">       
    <!--copy all other nodes-->
    <xsl:apply-templates select="@* | node()"/>
        </xsl:element>
    </xsl:template>

  <xsl:template match="Set_Item">        
     <xsl:element name="Item">
    <!--copy all other nodes-->
    <xsl:apply-templates select="@* | node()"/>
        </xsl:element>
    </xsl:template>

  <xsl:template match="RFF_Line_Set_Item">        
     <xsl:element name="RFF_Line">
    <!--copy all other nodes-->
    <xsl:apply-templates select="@* | node()"/>
        </xsl:element>
    </xsl:template>
    
      <xsl:template match="ContainerInformation_Set_Item">        
     <xsl:element name="ContainerInformation">
    <!--copy all other nodes-->
    <xsl:apply-templates select="@* | node()"/>
        </xsl:element>
    </xsl:template>

  <!-- Differenz zwischen bestellter und gelieferter Menge -->
  <xsl:template match="Item/ItemDeliveryInformation[. != '']">
    <xsl:copy>
    <!--copy all other nodes-->
      <xsl:apply-templates select="@* | node()"/>
    <QtyDifference>
        <xsl:value-of select="format-number((./DeliveredQuantity - ../Ordered), '#0.00')"/>
    </QtyDifference>  
    </xsl:copy>
  </xsl:template> 

  <!-- das aufzurufende Template: OrderResponseReference Teil 1-->
<xsl:template name="last-substring-after">
  <xsl:param name="search"/>
  <xsl:param name="string"/>
  <xsl:variable name="result" select="substring-after($string, $search)"/>
    <xsl:choose>
        <xsl:when test="contains($result, $search)">
            <xsl:call-template name="last-substring-after">
            <xsl:with-param name="search" select="$search"/>
            <xsl:with-param name="string" select="$result"/>
      </xsl:call-template>
        </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$result"/>
            </xsl:otherwise>
    </xsl:choose>
</xsl:template>

<!-- das aufzurufende Template: OrderResponseReference Teil 2-->
  <xsl:template match="OrderResponseReference[contains (., '/')]">
    <OrderResponseReference>    
        <xsl:call-template name="last-substring-after">
        <xsl:with-param name="search" select="'/'"/>
        <xsl:with-param name="string" select="."/>
    </xsl:call-template>
    </OrderResponseReference>
  </xsl:template>
  
  <xsl:template match="OrderResponseReference[not(contains (., '/'))]">
    <OrderResponseReference><xsl:value-of select="." /></OrderResponseReference>    
  </xsl:template>    

  <xsl:template match="HeaderText[generate-id() != generate-id(key('header_text', Text)[1])]" />
  <xsl:template match="LineText[generate-id() != generate-id(key('line_text', concat(../LineNum, '|', Text))[1])]" />
  <xsl:template match="AllowanceOrCharge_Header[generate-id() != generate-id(key('allowance_charge_header', concat(Code, '|', Amount))[1])]" />
  <xsl:template match="AllowanceOrCharge_Line[generate-id() != generate-id(key('allowance_charge_line', concat(../LineNum, '|', Code, '|', Amount))[1])]" />
  <xsl:template match="ItemDeliveryInformation[generate-id() != generate-id(key('packing_slip', concat(../LineNum, '|', PackingSlipId, '|', DeliveryDate, '|', DeliveredQuantity))[1])]" />
  <xsl:template match="Item[generate-id() != generate-id(key('item', concat(LineNum, '|', GTIN, '|', SupplierArticleNumber, '|', Quantity))[1])]" />
  <xsl:template match="Set_Item[generate-id() != generate-id(key('set_item', concat(LineNum, '|', GTIN, '|', SupplierArticleNumber, '|', ForwarderReferenceNumber))[1])]" />
  <xsl:template match="WeightAndVolume[generate-id() != generate-id(key('WeightAndVolume', Weight_RecId)[1])]" />
  <xsl:template match="ContainerInformation[generate-id() != generate-id(key('ContainerInformation', SSCC_RecId)[1])]" />
  <xsl:template match="ContainerInformation_Set_Item[generate-id() != generate-id(key('ContainerInformation_Set_Item', SSCC)[1])]" />

  <!-- Delete 0 at PackagingQty -->
  <xsl:template match="PackagingUnit[PackagingQty = '0.00' or AllowanceOrChargeAmount = '0']"/>

  <!-- Delete 0 at ContainerInformation/SSCC_RecId -->
  <xsl:template match="ContainerInformation/SSCC_RecId"/>
  
    <!-- Delete 0 at ContainerInformation/SSCC_RecId -->
  <xsl:template match="ContainerInformation_Set_Item/SSCC_RecId"/>

  <!-- Delete 0 at WeightAndVolume/Weight_RecId -->
  <xsl:template match="WeightAndVolume/Weight_RecId"/>
  
<!-- delete empty nodes -->
 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>

 <xsl:template match="*[not(@*|*|comment()|processing-instruction()) and normalize-space()='']"/>

</xsl:stylesheet>

谢谢!

致以最诚挚的问候 朱利安

xml xslt xslt-1.0
1个回答
0
投票

使用密钥并处理由该密钥形成的“组”中的所有 ForwarderReferenceNumber:

const xslt = `<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:key name="group" match="Set_Item" use="GTIN"/>

<xsl:template match="Set_Item[not(generate-id() = generate-id(key('group', GTIN)[1]))]"/>

<xsl:template match="ForwarderReferenceNumber">
  <xsl:copy-of select=". | key('group', ../GTIN)/ForwarderReferenceNumber"/>
</xsl:template>

<xsl:template match="@* | node()">
  <xsl:copy>
    <xsl:apply-templates select="@* | node()"/>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>`;

var domParser = new DOMParser();

var xsltProcessor = new XSLTProcessor();

xsltProcessor.importStylesheet(domParser.parseFromString(xslt, 'application/xml'));

var resultDoc = xsltProcessor.transformToDocument(domParser.parseFromString(document.getElementById('xml').text, 'application/xml'));

console.log(resultDoc);

console.log(new XMLSerializer().serializeToString(resultDoc));
<script id="xml" type="application/xml">
<OSTRPT>
  <LineInformation>  
    <Set_Item>
      <LineNum>2</LineNum>
      <GTIN>555</GTIN>      
      <Quantity>1.00</Quantity>
      <MeasureUnit>PCE</MeasureUnit>
      <DeliveryDate>2024-03-13</DeliveryDate>
      <Status>24</Status>     
      <ForwarderReferenceNumber>666</ForwarderReferenceNumber>  
      <Date>2</Date>          
    </Set_Item>
    <Set_Item>
      <LineNum>7</LineNum>
      <GTIN>555</GTIN>     
      <Quantity>1.00</Quantity>
      <MeasureUnit>PCE</MeasureUnit>
      <DeliveryDate>2024-03-13</DeliveryDate>
      <Status>24</Status>      
      <ForwarderReferenceNumber>777</ForwarderReferenceNumber> 
      <Date>3</Date>          
    </Set_Item>
  </LineInformation>
</OSTRPT>
</script>

© www.soinside.com 2019 - 2024. All rights reserved.