2014-02-28 24 views
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~ 

同樣,我們的問題是:如何能期望的數值限制在樣式表編碼?

回答

0

我想你可以第一個結果存儲在一個變量,然後組和算作是需要的,更容易處理,我選擇來包裝中間結果爲XML:

<?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" 
exclude-result-prefixes="t vc"> 

<xsl:output method="text"/> 

<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:variable name="items"> 
    <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"> 
       <item>S5*<xsl:value-of select="../vc:StopSequenceNumber+1"/>*UL<xsl:text>~</xsl:text></item> 
      </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"> 
             <item>L5*<xsl:value-of select="vc:OrderLineItemNumber"/><xsl:text>~</xsl:text></item> 
            </xsl:when> 
            <xsl:when test="position() lt 10"> 
             <item>L5*<xsl:value-of select="concat($OfferPosition, '0', vc:OrderLineItemNumber)"/><xsl:text>~</xsl:text></item> 
            </xsl:when> 
            <xsl:otherwise> 
             <item>L5*<xsl:value-of select="concat($OfferPosition, vc:OrderLineItemNumber)"/><xsl:text>~</xsl:text></item> 
            </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"> 
       <item>S5*<xsl:value-of select="../vc:StopSequenceNumber+1"/>*LD<xsl:text>~</xsl:text></item> 
      </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"> 
            <item>L5*<xsl:value-of select="vc:OrderLineItemNumber"/><xsl:text>~</xsl:text></item> 
           </xsl:when> 
           <xsl:when test="position() lt 10"> 
            <item>L5*<xsl:value-of select="concat($OfferPosition, '0', vc:OrderLineItemNumber)"/><xsl:text>~</xsl:text></item> 
           </xsl:when> 
           <xsl:otherwise> 
            <item>L5*<xsl:value-of select="concat($OfferPosition, vc:OrderLineItemNumber)"/><xsl:text>~</xsl:text></item> 
           </xsl:otherwise> 
          </xsl:choose> 
         </xsl:for-each> 
        </xsl:when> 
       </xsl:choose> 
      </xsl:for-each> 
     </xsl:for-each> 
    </xsl:for-each> 
    </xsl:variable> 

    <xsl:for-each-group select="$items/item" group-starting-with="item[starts-with(., 'S5*')]"> 
    <xsl:if test="position() gt 1"><xsl:text>&#10;</xsl:text></xsl:if> 
    <xsl:value-of select="if (starts-with(., 'S5*1*LD') or starts-with(., 'S5*3*UL')) 
          then current-group()[position() le 6] else current-group()" 
        separator="&#10;"/> 
    </xsl:for-each-group> 
</xsl:template> 
</xsl:stylesheet> 

隨着該樣式表和你的輸入撒克遜9.5輸出

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~ 
+0

將原始搜索結果存儲在變量(臨時樹)中是我們正在尋找的答案。我們需要稍微處理樣式表,以使其更通用。感謝Martin提供指導和提供可行的解決方案。 – user3366690