我是XSLT的新手,但我在学习方面取得了进步。有人可以帮助我解决我得到的错误吗? - 不允许多个项目的序列作为'cast as'表达式中的值。
我基本上有多个实例,我只需要选择一个。第一个条件是如果变量(日期)等于期间开始日期和期间结束日期,则选择该特定付款日期。如果没有,则找到它在期间开始日期和期间结束日期内的付款日期。否则,它是“未知”。对于这个例子,我将变量transdate设置为2017-02-13,所以我只想要2017-02-13付款日期。
这是之前和转换的示例XSLT:
<?xml version='1.0' encoding='UTF-8'?>
<wd:Report_Data xmlns:wd="urn:com.workday/bsvc">
<wd:Report_Entry>
<wd:Employee_ID>1234567</wd:Employee_ID>
<wd:Current_Period/>
<wd:Current_Period/>
<wd:Current_Period/>
<wd:Current_Period>
<wd:Payment_Date>2017-02-09-08:00</wd:Payment_Date>
<wd:End_Date>2017-02-12-08:00</wd:End_Date>
<wd:Start_Date>2017-01-30-08:00</wd:Start_Date>
</wd:Current_Period>
<wd:Current_Period>
<wd:Payment_Date>2017-02-13-08:00</wd:Payment_Date>
<wd:End_Date>2017-02-13-08:00</wd:End_Date>
<wd:Start_Date>2017-02-13-08:00</wd:Start_Date>
</wd:Current_Period>
</wd:Report_Entry>
</wd:Report_Data>
这是我目前的转型XSL:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wd="urn:com.workday/bsvc"
exclude-result-prefixes="xsl xs wd">
<xsl:variable name="var.input.trans.date"><xsl:value-of select="'2017-02-13'"/></xsl:variable>
<xsl:template match="/">
<Record>
<Employee_ID><xsl:value-of select="/wd:Report_Data/wd:Report_Entry/wd:Employee_ID"/></Employee_ID>
<xsl:variable name="transDate" >
<xsl:value-of select="$var.input.trans.date"/>
</xsl:variable>
<xsl:choose>
<xsl:when test="(xs:date($transDate) = xs:date(/wd:Report_Data/wd:Report_Entry/wd:Current_Period/substring(wd:Start_Date,1,10))) and (xs:date($transDate) = xs:date(/wd:Report_Data/wd:Report_Entry/wd:Current_Period/substring(wd:End_Date,1,10))) ">
<Payment_Date><xsl:value-of select="/wd:Report_Data/wd:Report_Entry/wd:Current_Period/substring(wd:Payment_Date,1,10)"/></Payment_Date>
</xsl:when>
<xsl:when test="(xs:date($transDate) >= xs:date(/wd:Report_Data/wd:Report_Entry/wd:Current_Period/substring(wd:Start_Date,1,10))) and (xs:date($transDate) <= xs:date(/wd:Report_Data/wd:Report_Entry/wd:Current_Period/substring(wd:End_Date,1,10))) ">
<Payment_Date><xsl:value-of select="/wd:Report_Data/wd:Report_Entry/wd:Current_Period/substring(wd:Payment_Date,1,10)"/></Payment_Date>
</xsl:when>
<xsl:otherwise>
<Payment_Date><xsl:text>Unknown</xsl:text></Payment_Date>
</xsl:otherwise>
</xsl:choose>
</Record>
</xsl:template>
</xsl:stylesheet>
这是我需要作为此特定实例的输出:
<?xml version="1.0" encoding="UTF-8"?>
<Record>
<Employee_ID>1234567</Employee_ID>
<Payment_Date>2017-02-13</Payment_Date>
</Record>
答案 0 :(得分:1)
问题在于这个表达式......
xs:date(/wd:Report_Data/wd:Report_Entry/wd:Current_Period/substring(wd:Start_Date,1,10)))
其中的xpath匹配多个元素(它将返回所有开始日期),而xs:date
只需要处理一个值。
请尝试使用此XSLT。我重新调整了模板以匹配wd:Report_Entry
并简化了相对于此的xpath(因为这样可以使其与多个wd:Report_Entry
元素一起使用)。
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wd="urn:com.workday/bsvc"
exclude-result-prefixes="xsl xs wd">
<xsl:variable name="var.input.trans.date"><xsl:value-of select="'2017-02-13'"/></xsl:variable>
<xsl:template match="wd:Report_Entry">
<Record>
<Employee_ID><xsl:value-of select="wd:Employee_ID"/></Employee_ID>
<xsl:variable name="transDate" select="xs:date($var.input.trans.date)"/>
<xsl:variable name="exactmatch" select="wd:Current_Period[wd:Start_Date and wd:End_Date and $transDate = xs:date(substring(wd:Start_Date, 1, 10)) and $transDate = xs:date(substring(wd:End_Date, 1, 10))]" />
<xsl:variable name="period" select="wd:Current_Period[wd:Start_Date and wd:End_Date and $transDate ge xs:date(substring(wd:Start_Date, 1, 10)) and $transDate le xs:date(substring(wd:End_Date, 1, 10))]" />
<xsl:choose>
<xsl:when test="exactmatch">
<Payment_Date><xsl:value-of select="substring($exactmatch/wd:Payment_Date, 1, 10)"/></Payment_Date>
</xsl:when>
<xsl:when test="$period">
<Payment_Date><xsl:value-of select="substring($period/wd:Payment_Date, 1, 10)"/></Payment_Date>
</xsl:when>
<xsl:otherwise>
<Payment_Date><xsl:text>Unknown</xsl:text></Payment_Date>
</xsl:otherwise>
</xsl:choose>
</Record>
</xsl:template>
</xsl:stylesheet>
根据您的日期,可能是&#34;确切的&#34;匹配是不需要的。毕竟,如果它与开始日期和结束日期相匹配,它也符合大于等于开始日期的逻辑,并且小于等于结束日期。
试试这个
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:wd="urn:com.workday/bsvc"
exclude-result-prefixes="xsl xs wd">
<xsl:variable name="var.input.trans.date"><xsl:value-of select="'2017-02-13'"/></xsl:variable>
<xsl:template match="wd:Report_Entry">
<Record>
<Employee_ID><xsl:value-of select="wd:Employee_ID"/></Employee_ID>
<xsl:variable name="transDate" select="xs:date($var.input.trans.date)"/>
<xsl:variable name="period" select="wd:Current_Period[wd:Start_Date and wd:End_Date and $transDate ge xs:date(substring(wd:Start_Date, 1, 10)) and $transDate le xs:date(substring(wd:End_Date, 1, 10))]" />
<xsl:choose>
<xsl:when test="$period">
<Payment_Date><xsl:value-of select="substring($period/wd:Payment_Date, 1, 10)"/></Payment_Date>
</xsl:when>
<xsl:otherwise>
<Payment_Date><xsl:text>Unknown</xsl:text></Payment_Date>
</xsl:otherwise>
</xsl:choose>
</Record>
</xsl:template>
</xsl:stylesheet>