Как рассчитать разницу во времени (длительность) в xslt 1.0? - PullRequest
3 голосов
/ 04 января 2012

Я использую xlstproc для преобразования некоторого XML-файла в другой файл формата XML, во время преобразования мне нужно вычислить значение разницы во времени (длительности в секундах или минутах: секундах) между полями начала и конца.

... <start>2011-12-13 16:15:26</start> <end>2011-12-13 16:17:27</end> ...

Я нашел синтаксис шаблона, но не смог его использовать.

<xsl:call-template name="date:duration">
  <xsl:with-param name="seconds" select="number" />?
</xsl:call-template>

Буду признателен, если кто-нибудь подскажет мне, как достичь моей цели.Заранее спасибо!

1 Ответ

6 голосов
/ 04 января 2012

Я сделал для вас часть вашей работы и нашел эту дату: функция продолжительности , которую вы, похоже, пытаетесь использовать. Однако date: duration преобразует количество секунд в форматированную строку длительности, тогда как вы хотите найти разницу (длительность) между двумя строками datetime.

Вы, вероятно, хотите вместо date: разница . Если вы прочитаете документацию для этой функции / шаблона , вы найдете следующие аргументы:

Обе даты должны быть усеченными справа строкой даты / времени в одном из форматы, определенные в [Схема XML, часть 2: типы данных]. ... Допустимые форматы: ...

xs:dateTime (CCYY-MM-DDThh:mm:ss)
...

Там есть курсив в оригинале: CCYY-MM-DDThhh: мм: сс за исключением того, что Т не выделено курсивом. Другими словами, временные строки нуждаются в литерале T между датой и временем, тогда как у вас есть пробел.

Так что я бы предложил исправить это:

<start>2011-12-13T16:15:26</start>
  <end>2011-12-13T16:17:27</end>

Передайте строки start и end в качестве параметров в шаблон. Вы можете сделать это, просто передав узлы элементов start и end, которые будут автоматически преобразованы в строки на основе их текстового содержимого:

<xsl:variable name="time-diff-dur">
  <xsl:call-template name="date:difference">
    <xsl:with-param name="start" select="start" />
    <xsl:with-param name="end" select="end" />
  </xsl:call-template>
</xsl:variable>
<!-- The above returns a duration formatted string, so convert that to seconds: -->
<xsl:variable name="time-diff-sec">
  <xsl:call-template name="date:seconds">
    <xsl:with-param name="seconds" select="$time-diff-dur" />?
  </xsl:call-template>
</xsl:variable>

В этом коде предполагается, что узел контекста является родителем элементов <start> и <end>. После приведенного выше кода переменная $time-diff-sec будет содержать фрагмент дерева результатов, который при необходимости можно преобразовать в число, используя number($time-diff-sec).

Дайте нам знать, работает ли это. Если нет, укажите конкретно , каким был результат и чем он отличается от ожидаемого.

Обновление:

Я только что заметил, что вы используете xsltproc (который использует libxslt). Согласно этой документации , libxslt изначально поддерживает date:differencedate:seconds). Таким образом, вы можете вызывать эти функции как функции вместо определения именованного шаблона и вызова его как шаблона. Это будет гораздо меньше кода для вас, хотя и менее переносимым:

<xsl:variable name="time-diff-sec"
    select="date:seconds(date:difference(start, end))" />

Как и раньше, вам нужно будет где-то объявить префикс пространства имен date, обычно в элементе xsl:stylesheet:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:date="http://exslt.org/dates-and-times"
    extension-element-prefixes="date">

Обновление 2:

См. этот ответ для переносимого шаблона XSLT 1.0 для преобразования строки даты в число секунд, что позволяет легко вычитать одну дату из другой. (Спасибо Сэму Б. за этот комментарий).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...