Проверьте, является ли строка допустимой датой или нет в XSLT

У меня есть документ xml, в котором есть несколько узлов даты, и я пытаюсь получить их значения, если значения являются допустимыми датами, в противном случае пустая строка.

XML:

<root>
  <START_DATE><![CDATA[03/05/2015]]></START_DATE>
  <START_DATE><![CDATA[05/05/2015]]></START_DATE>
  <START_DATE><![CDATA[Online]]></START_DATE>
</root>

XSLT:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" version="1.0">
  <xsl:output method="text" indent="yes" />
  <xsl:template match="@*|node()">
    <xsl:apply-templates select="@*|node()" />
  </xsl:template>

  <xsl:template match="START_DATE">
    <xsl:copy>
        <xsl:value-of select="if(string(normalize-space(.)) castable as xs:date) then normalize-space(.) else ''"></xsl:value-of>
    </xsl:copy>
    <xsl:text>&#44;</xsl:text>
  </xsl:template>
</xsl:transform>

Вывод:

,,,

Ожидается:

03/05/2015,05/05/2015,,

person Beginner    schedule 08.05.2015    source источник
comment
Пожалуйста, укажите XSLT 1.0 или 2.0. В вашей таблице стилей заявлена ​​версия 1.0, но она будет работать только с процессором XSLT 2.0. Изначально вы отметили этот вопрос Xalan, теперь вы удалили этот тег. Просьба уточнить.   -  person michael.hor257k    schedule 08.05.2015
comment
@ michael.hor257k Процессор Xalan, и я отметил его тегом.   -  person Beginner    schedule 08.05.2015


Ответы (1)


получить их значения, если значения являются допустимыми датами, в противном случае пустая строка

Xalan — процессор XSLT 1.0. В XSLT 1.0 нет понятия «дата», поэтому вам придется выполнять проверку самостоятельно. Точный метод зависит от того, что именно означает «действительная дата» в этом контексте.

Если достаточно убедиться, что строка, представляющая собой дату, отформатирована как дата (т. е. имеет точно такой шаблон "##/##/####"), тогда тест может быть довольно просто:

<xsl:if test="translate(., '123456789', '000000000') = '00/00/0000'">
    <!-- result if valid -->
</xsl:if>

Если вам также нужно проверить, является ли предполагаемая дата действительной датой в григорианском календаре (например, не «13/13/2015»), тогда это становится намного сложнее.


Примечание о XSLT 2.0:

В XSLT 2.0 вы можете использовать castable as xs:date для проверки правильности даты. Однако даже допустимая дата в формате MM/DD/YYYY или DD/MM/YYYY не пройдет этот тест. Вы должны сначала преобразовать эти строки в формат YYYY-MM-DD.

person michael.hor257k    schedule 08.05.2015
comment
В 2.0 я проверял так: <xsl:value-of select="if(string(replace(normalize-space(.), '([0-9]{2})\D([0-9]{2})\D([0-9]{4})', '$3-$1-$2')) castable as xs:date) then normalize-space(.) else ''"></xsl:value-of> - person Beginner; 08.05.2015
comment
Так почему ты убрал это из своего поста? - person michael.hor257k; 08.05.2015
comment
Так как это решение 2.0. Но я хочу какое-то решение в 1.0, если это возможно. - person Beginner; 08.05.2015
comment
Я имел в виду, почему вы удалили часть кода XSLT 2.0, где вы переставляете строку? Решение для XSLT 1.0 находится в моем ответе выше. - person michael.hor257k; 08.05.2015
comment
Я просто проверял. Но мне нужна и эта часть. Спасибо, сработало :) - person Beginner; 08.05.2015