我被要求生成從XML文檔生成的逗號分隔列表。當折扣只包含在車輛節點下組合在一起的節點時,它工作正常(我對XPath的理解有限)。然後我被要求增加一個位於XML不同部分的折扣。使用這種方法我似乎無法獲得我需要的節點的價值。爲了澄清,我不創建這個XML文件,它由供應商系統生成,大約5K行。我使用SO的post作爲創建列表的基礎。使用XPath/XSLT從XML樹中不同級別的XML節點創建連接逗號分隔列表
所需的輸出(如果在環路節點= '0' 或PaymentPlanCd = 'PaidInFull' 添加到列表中! - 僞代碼)
多轎廂,房主,親和,在-Agency轉移,需提前預定,無事故,年行駛里程,在全額貼息
我得到一個最後的額外的逗號付費,所以我改成一個空格基礎的方法,似乎工作(方法2)。儘管如此,我寧願使用基於逗號的方法(方法1)。以下是XML文檔和我目前正在努力工作的代碼示例。如果有一個更容易或更有說服力的解決方案,我就會全神貫注。
示例XML(@pval代表 「建議值」)
<dataStore>
<session>
<data>
<policy>
<PersPolicy>
<PaymentOption>
<PaymentPlanCd>PaidInFull</PaymentPlanCd>
</PaymentOption>
</PersPolicy>
<line>
<vehicle id="1">
<DiscountPremMultiCar pval="Multi-Car">80</DiscountPremMultiCar>
<DiscountPremHomeowners pval="Homeowner">63</DiscountPremHomeowners>
<DiscountPremAffinity pval="Affinity">0</DiscountPremAffinity>
<DiscountPremInAgencyTransfer pval="In-Agency Transfer">57</DiscountPremInAgencyTransfer>
<DiscountPremAdvPurchase pval="Advanced Purchase">15</DiscountPremAdvPurchase>
<DiscountPremIncidentFree pval="Incident Free">30</DiscountPremIncidentFree>
<DiscountPremAnnualMileage pval="Annual Mileage">0</DiscountPremAnnualMileage>
</vehicle>
<vehicle id="2">
<DiscountPremMultiCar pval="Multi-Car">80</DiscountPremMultiCar>
<DiscountPremHomeowners pval="Homeowner">63</DiscountPremHomeowners>
<DiscountPremAffinity pval="Affinity">0</DiscountPremAffinity>
<DiscountPremInAgencyTransfer pval="In-Agency Transfer">57</DiscountPremInAgencyTransfer>
<DiscountPremAdvPurchase pval="Advanced Purchase">15</DiscountPremAdvPurchase>
<DiscountPremIncidentFree pval="Incident Free">30</DiscountPremIncidentFree>
<DiscountPremAnnualMileage pval="Annual Mileage">0</DiscountPremAnnualMileage>
</vehicle>
</line>
</policy>
</data>
</session>
</dataStore>
XSLT/XPath的
<xsl:for-each select="//session/data/policy/line/vehicle">
<xsl:call-template name="VehicleDiscounts" />
</xsl:for-each>
方法1
<xsl:template name="VehicleDiscounts">
<xsl:for-each select="DiscountPremAdvPurchase/text() | DiscountPremAffinity/text() | DiscountPremAnnualMileage/text() | DiscountPremEmployee/text() | DiscountPremHomeowners/text() | DiscountPremInAgencyTransfer/text() | DiscountPremMultiCar/text() | DiscountPremMultiPolicy/text() | DiscountPremIncidentFree/text() | ../../../PersPolicy/PaymentOptions/PaymentPlanCd/text()">
<xsl:if test="../. != '0'">
<xsl:value-of select="../@pval"/>
<xsl:if test="not(position() = last())">, </xsl:if>
</xsl:if>
</xsl:for-each>
</xsl:template>
方法2
<xsl:template name="VehicleDiscounts">
<xsl:for-each select="DiscountPremAdvPurchase/text() | DiscountPremAffinity/text() | DiscountPremAnnualMileage/text() | DiscountPremEmployee/text() | DiscountPremHomeowners/text() | DiscountPremInAgencyTransfer/text() | DiscountPremMultiCar/text() | DiscountPremMultiPolicy/text() | DiscountPremIncidentFree/text() | ../../../PersPolicy/PaymentOptions/PaymentPlanCd/text()">
<xsl:choose>
<xsl:when test="name(../.) = 'DiscountPremAdvPurchase'">
<xsl:if test="../. != '0'">
Advance Purchase
<xsl:if test="not(position() = last())">    </xsl:if>
</xsl:if>
</xsl:when>
<xsl:when test="name(../.) = 'DiscountPremAffinity'">
<xsl:if test="../. != '0'">
Affinity
<xsl:if test="not(position() = last())">    </xsl:if>
</xsl:if>
</xsl:when>
<xsl:when test="name(../.) = 'DiscountPremEmployee'">
<xsl:if test="../. != '0'">
Group
<xsl:if test="not(position() = last())">    </xsl:if>
</xsl:if>
</xsl:when>
<xsl:when test="name(../.) = 'DiscountPremHomeowners'">
<xsl:if test="../. != '0'">
Homeowners
<xsl:if test="not(position() = last())">    </xsl:if>
</xsl:if>
</xsl:when>
<xsl:when test="name(../.) = 'DiscountPremInAgencyTransfer'">
<xsl:if test="../. != '0'">
In-Agency Transfer
<xsl:if test="not(position() = last())">    </xsl:if>
</xsl:if>
</xsl:when>
<xsl:when test="name(../.) = 'DiscountPremMultiCar'">
<xsl:if test="../. != '0'">
Multi-Car
<xsl:if test="not(position() = last())">    </xsl:if>
</xsl:if>
</xsl:when>
<xsl:when test="name(../.) = 'DiscountPremMultiPolicy'">
<xsl:if test="../. != '0'">
Multi-Policy
<xsl:if test="not(position() = last())">    </xsl:if>
</xsl:if>
</xsl:when>
<xsl:when test="name(../.) = 'DiscountPremIncidentFree'">
<xsl:if test="../. != '0'">
Incident-Free
<xsl:if test="not(position() = last())">    </xsl:if>
</xsl:if>
</xsl:when>
<xsl:when test="name(../.) = 'DiscountPremAnnualMileage'">
<xsl:if test="../. != '0'">
Annual Mileage
<xsl:if test="not(position() = last())">    </xsl:if>
</xsl:if>
</xsl:when>
<!-- This is what I have no clue about -->
<xsl:when test="name(../.) = 'PaymentPlanCd'">
Paid In Full Discount
<xsl:if test="../. != '0'">
Paid In Full Discount
<xsl:if test="not(position() = last())">    </xsl:if>
</xsl:if>
</xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:template>
我將如何獲得方法1在這種情況下工作?感謝所有的幫助。
我不明白這個部分: 「*(如果在環路節點= '0' 或PaymentPlanCd = 'PaidInFull' 添加到列表中!)*」 – 2014-09-10 18:10:04
那是參考for-each循環中的節點。 ()| DiscountPremEmployee/text()| DiscountPremEmployee/text()| DiscountPremInAgencyTransfer/text()| DiscountPremMultiCar/text()|折扣優先購買折扣/ text()|折扣優惠折扣/ )| DiscountPremMultiPolicy/text()| DiscountPremIncidentFree/text()| ../../../ PersPolicy/PaymentOptions/PaymentPlanCd/text()「>'基本上僞代碼。 – mmarceau 2014-09-10 18:26:18
但它是什麼意思**?通常,CSV輸出在每行中的每個「列」都有一個「字段」。 IOW,不能排除任何節點,否則下列節點將被移動到錯誤的「列」。 – 2014-09-10 18:35:25