2
一位同事和我已被給予新的要求。請查看以下內容。限制輸出(XSLT 2.0臨時樹)
我們需要轉換XML源文檔,同時對結果文檔中的某些項目執行數字限制。以下是源文檔,XSLT樣式表和結果文檔。然而,這個結果文檔沒有反映出所需的數值限制,因爲這個樣式表沒有任何限制地轉換源文檔。
最後,我們的問題是:如何在樣式表中強制實現所需的數值限制?
源文件:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<T:Message xmlns="http://www.noname.com/Platform" xmlns:T="http://www.noname.com/Transportation">
<T:ShipmentListMessage>
<Shipment>
<ShipmentNumber>ABC</ShipmentNumber>
<PickupCommodityCode>Hazmat</PickupCommodityCode>
<DeliveryCommodityCode>Hazmat</DeliveryCommodityCode>
<ShipmentLine>
<ShipmentLineNumber>ABC-1</ShipmentLineNumber>
<OrderLineItemNumber>1</OrderLineItemNumber>
</ShipmentLine>
<ShipmentLine>
<ShipmentLineNumber>ABC-2</ShipmentLineNumber>
<OrderLineItemNumber>2</OrderLineItemNumber>
</ShipmentLine>
<ShipmentLine>
<ShipmentLineNumber>ABC-3</ShipmentLineNumber>
<OrderLineItemNumber>3</OrderLineItemNumber>
</ShipmentLine>
</Shipment>
<Shipment>
<ShipmentNumber>DEF</ShipmentNumber>
<PickupCommodityCode>Hazmat</PickupCommodityCode>
<DeliveryCommodityCode>Hazmat</DeliveryCommodityCode>
<ShipmentLine>
<ShipmentLineNumber>DEF-1</ShipmentLineNumber>
<OrderLineItemNumber>1</OrderLineItemNumber>
</ShipmentLine>
<ShipmentLine>
<ShipmentLineNumber>DEF-2</ShipmentLineNumber>
<OrderLineItemNumber>2</OrderLineItemNumber>
</ShipmentLine>
</Shipment>
<Shipment>
<ShipmentNumber>GHI</ShipmentNumber>
<PickupCommodityCode>Hazmat</PickupCommodityCode>
<DeliveryCommodityCode>Hazmat</DeliveryCommodityCode>
<ShipmentLine>
<ShipmentLineNumber>GHI-1</ShipmentLineNumber>
<OrderLineItemNumber>1</OrderLineItemNumber>
</ShipmentLine>
<ShipmentLine>
<ShipmentLineNumber>GHI-2</ShipmentLineNumber>
<OrderLineItemNumber>2</OrderLineItemNumber>
</ShipmentLine>
<ShipmentLine>
<ShipmentLineNumber>GHI-3</ShipmentLineNumber>
<OrderLineItemNumber>3</OrderLineItemNumber>
</ShipmentLine>
<ShipmentLine>
<ShipmentLineNumber>GHI-4</ShipmentLineNumber>
<OrderLineItemNumber>4</OrderLineItemNumber>
</ShipmentLine>
</Shipment>
</T:ShipmentListMessage>
<T:MovementListMessage>
<Movement>
<MovementStop>
<StopSequenceNumber>0</StopSequenceNumber>
<MovementStopLine>
<OperationType>Pickup</OperationType>
<ShipmentNumber>ABC</ShipmentNumber>
</MovementStopLine>
<MovementStopLine>
<OperationType>Pickup</OperationType>
<ShipmentNumber>DEF</ShipmentNumber>
</MovementStopLine>
<MovementStopLine>
<OperationType>Pickup</OperationType>
<ShipmentNumber>GHI</ShipmentNumber>
</MovementStopLine>
</MovementStop>
<MovementStop>
<StopSequenceNumber>1</StopSequenceNumber>
<MovementStopLine>
<OperationType>Deliver</OperationType>
<ShipmentNumber>ABC</ShipmentNumber>
</MovementStopLine>
</MovementStop>
<MovementStop>
<StopSequenceNumber>2</StopSequenceNumber>
<MovementStopLine>
<OperationType>Deliver</OperationType>
<ShipmentNumber>DEF</ShipmentNumber>
</MovementStopLine>
<MovementStopLine>
<OperationType>Deliver</OperationType>
<ShipmentNumber>GHI</ShipmentNumber>
</MovementStopLine>
</MovementStop>
</Movement>
</T:MovementListMessage>
</T:Message>
XSLT樣式表:
<?xml version="1.0"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:t="http://www.noname.com/Transportation" xmlns:vc="http://www.noname.com/Platform">
<xsl:output method="text" indent="no"/>
<xsl:template match="t:Message">
<xsl:variable name="shipmentPath" select="t:ShipmentListMessage/vc:Shipment"/>
<xsl:variable name="movementPath" select="t:MovementListMessage/vc:Movement"/>
<xsl:variable name="numDeliverLocations" select="count($movementPath/vc:MovementStop/vc:MovementStopLine[vc:OperationType = 'Deliver'])"/>
<xsl:variable name="numOffers" select="count($shipmentPath)"/>
<xsl:for-each select="$movementPath/vc:MovementStop">
<xsl:for-each select="vc:MovementStopLine[vc:OperationType = 'Deliver']">
<xsl:variable name="OfferNumber" select="vc:ShipmentNumber"/>
<xsl:variable name="OfferCount" select="count(../vc:MovementStopLine[vc:OperationType = 'Deliver'])"/>
<xsl:if test="position() = 1">
S5*<xsl:value-of select="../vc:StopSequenceNumber+1"/>*UL<xsl:text>~</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:for-each select="vc:MovementStopLine[vc:OperationType = 'Deliver']">
<xsl:variable name="OfferNumber" select="vc:ShipmentNumber"/>
<xsl:variable name="OfferCount" select="count(../vc:MovementStopLine[vc:OperationType = 'Deliver'])"/>
<xsl:variable name="OfferPosition" select="if (position() lt 10) then position() else 0"/>
<xsl:for-each select="$shipmentPath[vc:ShipmentNumber = $OfferNumber and vc:DeliveryCommodityCode != '']">
<xsl:choose>
<xsl:when test="vc:DeliveryCommodityCode = 'Hazmat'">
<xsl:if test="$numOffers gt 1 or $numDeliverLocations = 1">
<xsl:for-each select="vc:ShipmentLine">
<xsl:variable name="ShipmentLine" select="vc:ShipmentLineNumber"/>
<xsl:choose>
<xsl:when test="$OfferCount eq 1">
L5*<xsl:value-of select="vc:OrderLineItemNumber"/><xsl:text>~</xsl:text>
</xsl:when>
<xsl:when test="position() lt 10">
L5*<xsl:value-of select="concat($OfferPosition, '0', vc:OrderLineItemNumber)"/><xsl:text>~</xsl:text>
</xsl:when>
<xsl:otherwise>
L5*<xsl:value-of select="concat($OfferPosition, vc:OrderLineItemNumber)"/><xsl:text>~</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:if>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:for-each>
<xsl:for-each select="vc:MovementStopLine[vc:OperationType = 'Pickup']">
<xsl:variable name="OfferNumber" select="vc:ShipmentNumber"/>
<xsl:variable name="OfferCount" select="count(../vc:MovementStopLine[vc:OperationType = 'Pickup'])"/>
<xsl:if test="position() = 1">
S5*<xsl:value-of select="../vc:StopSequenceNumber+1"/>*LD<xsl:text>~</xsl:text>
</xsl:if>
</xsl:for-each>
<xsl:for-each select="vc:MovementStopLine[vc:OperationType = 'Pickup']">
<xsl:variable name="OfferNumber" select="vc:ShipmentNumber"/>
<xsl:variable name="OfferCount" select="count(../vc:MovementStopLine[vc:OperationType = 'Pickup'])"/>
<xsl:variable name="OfferPosition" select="if (position() lt 10) then position() else 0"/>
<xsl:for-each select="$shipmentPath[vc:ShipmentNumber = $OfferNumber and vc:PickupCommodityCode != '']">
<xsl:choose>
<xsl:when test="vc:PickupCommodityCode = 'Hazmat'">
<xsl:for-each select="vc:ShipmentLine">
<xsl:variable name="ShipmentLine" select="vc:ShipmentLineNumber"/>
<xsl:choose>
<xsl:when test="$OfferCount eq 1">
L5*<xsl:value-of select="vc:OrderLineItemNumber"/><xsl:text>~</xsl:text>
</xsl:when>
<xsl:when test="position() lt 10">
L5*<xsl:value-of select="concat($OfferPosition, '0', vc:OrderLineItemNumber)"/><xsl:text>~</xsl:text>
</xsl:when>
<xsl:otherwise>
L5*<xsl:value-of select="concat($OfferPosition, vc:OrderLineItemNumber)"/><xsl:text>~</xsl:text>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
結果文檔:
S5*1*LD~
L5*101~
L5*102~
L5*103~
L5*201~
L5*202~
L5*301~
L5*302~
L5*303~
L5*304~
S5*2*UL~
L5*1~
L5*2~
L5*3~
S5*3*UL~
L5*101~
L5*102~
L5*201~
L5*202~
L5*203~
L5*204~
爲了滿足我們的要求,數字限制必須以某種方式構建到樣式表中。爲了討論的目的,在「S5」段之後的「L5」段的數量上期望的限制是5。在這個例子中,限制將在「S5 * 1 * LD」和「S5 * 3 * UL」之後將「L5」段的數量減少到5。在「S5 * 2 * UL」的情況下,限制不起作用。
期望的結果文檔應用了「L5」限制:
S5*1*LD~
L5*101~
L5*102~
L5*103~
L5*201~
L5*202~
S5*2*UL~
L5*1~
L5*2~
L5*3~
S5*3*UL~
L5*101~
L5*102~
L5*201~
L5*202~
L5*203~
同樣,我們的問題是:如何能期望的數值限制在樣式表編碼?
將原始搜索結果存儲在變量(臨時樹)中是我們正在尋找的答案。我們需要稍微處理樣式表,以使其更通用。感謝Martin提供指導和提供可行的解決方案。 – user3366690