передача результирующего набора из определенной пользователем функции в функцию max () - PullRequest
0 голосов
/ 21 февраля 2020

Браузер первого раза, когда я не ясно. Я совершенно новичок в xslt. Я пытаюсь написать функцию, которая передает список очищенных значений даты в функцию max (). Ниже приведен мой входной документ:

<dates>
    <date>1990-09-02Z</date>
    <date>1990-09-03Z</date>
    <date>1990-09-04Z</date>
    <date>1990-09-05Z</date>
    <date>1990-09-06Z</date>
</dates>

Как видите, строковые значения имеют завершающий символ 'Z'. Если я пытаюсь передать их напрямую в max (), используя вложенную функцию substring ()

<xsl:template match="/dates">
    <xsl:value-of select="max(xs:date(substring(//date,1,10)))"/>
</xsl:template>

, я получаю эту ошибку:

Последовательность из более чем одного элемента не разрешено в качестве первого аргумента функции fn: substring () ("1990-09-02Z", "1990-09-03Z")

, поэтому я включил объявление xsl: function в мою таблицу стилей который теперь выглядит следующим образом:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:test="http://www.blah.blah/funct"
    version="3.0">


<xsl:function name="test:funct" visibility="public">
<xsl:param name="input"/>

<xsl:sequence>  
   <xsl:for-each select="$input">
      <xsl:value-of select="xs:date(substring(.,1,10))"/>
    </xsl:for-each>
</xsl:sequence>

</xsl:function>    


<xsl:template match="/dates">
    <xsl:value-of select="max(test:funct(//date))"/>
</xsl:template>



</xsl:stylesheet>

Однако теперь я получаю следующую ошибку

Ошибка преобразования {1990-09-02} в число

Я думал, max () может обрабатывать даты? Я совершенно не понимаю, что передаётся в функцию max () и почему она не работает. вывод, который я ищу: 1990-09-06

Я пытаюсь прочитать документацию со спецификацией w3org, но эти термины слишком технические для меня, поэтому не имеют смысла. Спасибо за любую помощь, которую вы можете предложить.

Кстати, я использую обработчик Saxon-PE 9.8.0.12

edit: моя конечная цель - иметь таблицу стилей со списком функции, которые я могу включить в другие таблицы стилей xsl, поэтому в конечном итоге решение должно быть функцией. В этом конкретном случае c функция, которая создает список очищенных дат, который затем может быть передан max ().

1 Ответ

1 голос
/ 21 февраля 2020

Поскольку вы отметили это как XSLT 3, я бы предложил начать с basi c XPath 2/3, где вы можете просто написать

//date/xs:date(substring(., 1, 10))

, то есть вы можете использовать вызовы функций на последнем шаге вашего пути для извлечения подстроки и построения xs:date: https://xsltfiddle.liberty-development.net/6rexjii

Так что выражение //date/xs:date(substring(., 1, 10)) дает вам последовательность xs:date значений, вы можете затем использовать max функция для них:

max(//date/xs:date(substring(., 1, 10)))

https://xsltfiddle.liberty-development.net/6rexjii/1

Что касается написания пользовательской функции для выполнения этого последнего шага, я бы написал функция, в которой вход является xs:string и возвращает xs:date:

  <xsl:function name="mf:date" as="xs:date">
      <xsl:param name="input" as="xs:string"/>
      <xsl:sequence select="xs:date(substring($input, 1, 10))"/>
  </xsl:function>

Тогда вы можете назвать его как max(//date/mf:date(.)): https://xsltfiddle.liberty-development.net/6rexjii/2

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

  <xsl:function name="mf:dates" as="xs:date*">
      <xsl:param name="input" as="xs:string*"/>
      <xsl:sequence select="$input ! xs:date(substring(., 1, 10))"/>
  </xsl:function>

и вызовите ее с помощью

 <xsl:value-of select="max(mf:dates(//date))"/>

https://xsltfiddle.liberty-development.net/6rexjii/3

В качестве синтаксической альтернативы в XPath 3.1 можно использовать оператор стрелки =>:

<xsl:value-of select="//date => mf:dates() => max()"/>

https://xsltfiddle.liberty-development.net/6rexjii/4

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