計算分割點鑑於以下XML輸入:XSLT/XML:如何動態地從一個輸入值
<shipment>
<goodsLines>FP-1|HP-0|QP-3|MQP-2</goodsLines>
<Barcodes>Code1|Code2|Code3|Code4|Code5|Code6</Barcodes>
</shipment>
和所需的輸出:
<Consignment>
<GoodsItemSet>
<GoodsItem goodsItemId="1">
<NumberOfPackages unitCode="PCE">1</NumberOfPackages>
<PackageTypeCode>FP</PackageTypeCode>
</GoodsItem>
<Package packageId="Code1"/>
</GoodsItemSet>
<GoodsItemSet>
<GoodsItem goodsItemId="2">
<NumberOfPackages unitCode="PCE">3</NumberOfPackages>
<PackageTypeCode>QP</PackageTypeCode>
</GoodsItem>
<Package packageId="Code2"/>
<Package packageId="Code3"/>
<Package packageId="Code4"/>
</GoodsItemSet>
<GoodsItemSet>
<GoodsItem goodsItemId="3">
<NumberOfPackages unitCode="PCE">2</NumberOfPackages>
<PackageTypeCode>MQP</PackageTypeCode>
</GoodsItem>
<Package packageId="Code5"/>
<Package packageId="Code6"/>
</GoodsItemSet>
</Consignment>
的想法是遞歸分割管道,然後爲每個由管道分隔的GoodsLines值創建一個GoodsItemSet,其中包數=' - '之後的值。當值爲0時,我們不做任何事情。GoodsItemSet將具有1 .. *子包依賴於所述數字,並且ID將被順序提取:1. FP-1 => 1條碼,從1開始爲1. 2.QP-3 => 3條碼,從2到5等。條碼讀數的起始點將從'sum until now'開始+1。
如何在下面修改我的xslt,動態更改起點並將正確的條形碼與正確的GoodsItemSet配對?該解決方案將運行在Biztalk 2013R2(xslt1.0) 非常感謝。
我至今XSLT:
<xsl:template match="GoodsLines" name="GenerateGoodsItemSet">
<xsl:param name="packagingCodes" select="."/>
<xsl:param name="unitsAccum" select="0"/>
<xsl:variable name="separator" select="'|'" />
<xsl:variable name="headpackagingCode">
<xsl:choose>
<xsl:when test="contains($packagingCodes, $separator)">
<xsl:value-of select="substring-before($packagingCodes, $separator)"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$packagingCodes"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:variable name="tailpackagingCodes" select="substring-after($packagingCodes, $separator)" />
<xsl:if test="number(substring-after($headpackagingCode, '-')) >0">
<xsl:element name="GoodsItemSet">
<xsl:element name="GoodsItem">
<xsl:attribute name="goodsItemId">
<xsl:number/>
</xsl:attribute>
<xsl:element name="NumberOfPackages">
<xsl:attribute name="unitCode">
<xsl:text>PCE</xsl:text>
</xsl:attribute>
<xsl:value-of select="substring-after($headpackagingCode, '-')"/>
</xsl:element>
<xsl:element name="PackageTypeCode">
<xsl:value-of select="substring-before($headpackagingCode, '-')" />
</xsl:element>
</xsl:element>
<!-- extract packageIds -->
<xsl:variable name="totalPackagesSoFar" select="substring-after($headpackagingCode, '-')"/> <!--Here I need a logic for the total processed so far, to use it as a starting point.-->
<xsl:choose>
<xsl:when test="position()=1">
<xsl:apply-templates select="../Barcodes">
<xsl:with-param name="start">1</xsl:with-param>
<xsl:with-param name="stop" select="number($unitsAccum + number(substring-after($headpackagingCode,'-')))"/>
</xsl:apply-templates>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="../Barcodes">
<xsl:with-param name="start" select="number($unitsAccum + $totalPackagesSoFar) +1"/>
<xsl:with-param name="stop" select="$unitsAccum + $totalPackagesSoFar + number(substring-after($headpackagingCode,'-'))"/>
</xsl:apply-templates>
</xsl:otherwise>
</xsl:choose>
</xsl:element>
</xsl:if>
<xsl:if test="$tailpackagingCodes">
<xsl:call-template name="GenerateGoodsItemSet">
<xsl:with-param name="packagingCodes" select="$tailpackagingCodes" />
</xsl:call-template>
</xsl:if>
</xsl:template>
<!--Tokenizer template-->
<xsl:template name="tokenize" match="Barcodes">
<xsl:param name="text" select="."/>
<xsl:param name="separator" select="'|'"/>
<xsl:param name="pos" select="1"/>
<xsl:param name="start"/>
<xsl:param name="stop"/>
<xsl:choose>
<xsl:when test="not(contains($text, $separator))">
<xsl:if test="$pos >= $start and $pos <= $stop">
<xsl:element name="Package">
<xsl:attribute name="packageId">
<xsl:value-of select="normalize-space($text)"/>
</xsl:attribute>
</xsl:element>
</xsl:if>
</xsl:when>
<xsl:otherwise>
<xsl:if test="$pos >= $start and $pos <= $stop">
<xsl:element name="Package">
<xsl:attribute name="packageId">
<xsl:value-of select="normalize-space(substring-before($text, $separator))"/>
</xsl:attribute>
</xsl:element>
</xsl:if>
<xsl:call-template name="tokenize">
<xsl:with-param name="text" select="substring-after($text, $separator)"/>
<xsl:with-param name="pos" select="$pos + 1"/>
<xsl:with-param name="start" select="$start"/>
<xsl:with-param name="stop" select="$stop"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
這是一個可怕的很多工作。你在使用哪種XSLT處理器?你真的可以使用擴展函數的一些幫助。 –
而不是從頭開始爲每個項目集選擇條形碼,而是將條形碼列表的相應尾部作爲模板參數傳遞,與您已經處理包裝代碼的方式類似。您可以使用單獨的遞歸模板來生成所需的尾部。 –