【发布时间】:2014-03-01 22:10:08
【问题描述】:
我和一位同事被提出了一项新要求。请查看以下内容。
我们需要转换 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。在此示例中,该限制会将“L5”段的数量减少到“S5*1*LD”和“S5*3*UL”之后的每个段数为 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~
同样,我们的问题是:如何在样式表中编码所需的数值限制?
【问题讨论】:
标签: xslt-2.0