我必须复制一个节点(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>
谢谢!
致以最诚挚的问候 朱利安
使用密钥并处理由该密钥形成的“组”中的所有 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>