2017-02-09 1 views
0

Я новичок в XSLT, но я добиваюсь прогресса в обучении. Может ли кто-нибудь помочь мне с ошибкой, которую я получаю? -Последовательность более чем одного элемента не допускается как значение в выражении «cast as».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> 
+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 и упростил xpaths относительно этого (потому что это позволяет ему работать с несколькими элементами 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> 

В зависимости от вашей даты, может быть, «точное» совпадение не требуется. В конце концов, если он совпадает с датой начала и окончания, он также выполняет логику быть более чем равной начальной дате и меньше, чем конечная дата.

Попробуйте это слишком

<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> 
+0

Это прекрасно! Большое спасибо за решение и четкое объяснение! –

Смежные вопросы