[英]Create a concatenated, comma separated list from XML nodes at different levels in the XML tree using XPath/XSLT
我被要求生成从XML文档生成的逗号分隔列表。 当折扣仅包含在车辆节点下分组在一起的节点时,它可以正常工作(我对XPath的了解有限)。 然后,我被要求添加另一个折扣,该折扣位于XML的不同部分。 使用这种方法,我似乎无法获得所需节点的价值。 为了澄清起见,我不创建此XML文件,它是由供应商系统生成的,大约5K行。 我使用SO的这篇文章作为创建列表的基础。
所需的输出 (如果循环中的节点!='0'或PaymentPlanCd!='PaidInFull'添加到列表-伪代码)
多车,房主,亲和力,机构内转移,预购,无事故,年度里程,全额折扣
最后,我得到了一个额外的逗号,因此我改用了似乎可行的基于空格的方法(方法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>
方法二
<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起作用? 感谢您的所有帮助。
我不确定这里的困难是什么。 您能否尝试以下样式表,并以简单的非技术性语言告诉我们-缺少什么(如有)?
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:template match="/">
<xsl:text>Multi-Car,Homeowner,Affinity,In-Agency Transfer,Advanced Purchase,Incident Free,Annual Mileage,Paid in Full Discount </xsl:text>
<xsl:for-each select="dataStore/session/data/policy/line/vehicle">
<xsl:for-each select="*">
<xsl:value-of select="."/>
<xsl:text>,</xsl:text>
</xsl:for-each>
<xsl:value-of select="../../PersPolicy/PaymentOption/PaymentPlanCd"/>
<xsl:if test="not(position()=last())">
<xsl:text> </xsl:text>
</xsl:if>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.