XSLT - 从多个节点中选择一个节点。不允许使用多个项目的序列作为'cast as'表达式

时间:2017-02-09 01:00:11

标签: xslt

我是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) &gt;= xs:date(/wd:Report_Data/wd:Report_Entry/wd:Current_Period/substring(wd:Start_Date,1,10))) and (xs:date($transDate) &lt;= 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>

1 个答案:

答案 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>