Javascript в XSLT

Рейтинг: 0Ответов: 1Опубликовано: 01.07.2023

Нужно в результирующем документе ставить текущую дату и надо вставить код джаваскрипт в шаблон, который будет дату выводить, ведь это нельзя сделать средствами xslt. Как вставить джаваскрипт функцию выводящую текущую дату в тело xslt-шаблона?

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:fo="http://www.w3.org/1999/XSL/Format"
                xmlns:abcd="http://www.tdwg.org/schemas/abcd/2.06"
                version="1.0">
  <xsl:template match="abcd:DataSets">
    <fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format">
      <fo:layout-master-set>
        <fo:simple-page-master master-name="letter"
                               page-height="11in" page-width="8.5in"
                               margin-top="0.5in" margin-bottom="0.5in"
                               margin-left="0.5in" margin-right="0.5in">
          <fo:region-body/>
        </fo:simple-page-master>
      </fo:layout-master-set>

      <fo:page-sequence master-reference="letter">
        <fo:flow flow-name="xsl-region-body">
          <xsl:for-each select="abcd:DataSet">
            <!-- тут нужно вывести дату текущую -->
            
            ...

</xsl:stylesheet>

Ответы

▲ -1Принят

Если вы используете .Net XslCompiledTransform, вот как это реализовать на c#.

XSLT 1.0

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:csharp="urn:my-scripts" exclude-result-prefixes="msxsl csharp">
    <xsl:output indent="yes" method="xml"/>

    <xsl:template match="/">
        <root>
            <CurrentDateTime>
                <xsl:value-of select="csharp:CurrentDateTime('yyyy-MM-ddTHH:mm:ss.fff')"/>
            </CurrentDateTime>
            <CurrentDate>
                <xsl:value-of select="csharp:CurrentDateTime('yyyy-MM-dd')"/>
            </CurrentDate>
            <DefaultDateTime>
                <xsl:value-of select="csharp:CurrentDateTime('')"/>
            </DefaultDateTime>
        </root>
    </xsl:template>

    <msxsl:script language="C#" implements-prefix="csharp">
    <![CDATA[
       public string CurrentDateTime(string format)
       {
            // default format
            if (string.IsNullOrEmpty(format)) {
                format = "yyyy-MM-ddTHH:mm:ss.fffzzz";
            }

            return DateTime.Now.ToString(format);
       }
    ]]>
    </msxsl:script>
</xsl:stylesheet>

Результат

<?xml version="1.0" encoding="utf-8"?>
<root>
  <CurrentDateTime>2023-07-01T22:47:26.224</CurrentDateTime>
  <CurrentDate>2023-07-01</CurrentDate>
  <DefaultDateTime>2023-07-01T22:47:26.224-04:00</DefaultDateTime>
</root>

XSLT 1.0

У меня нет вашей среды, поэтому я сделал это для Microsoft Windows. Возможно, вам потребуется настроить функцию и ее интеграцию в XSLT.

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                xmlns:jscript="http://www.url.com"
                exclude-result-prefixes="msxsl jscript">
    <xsl:output indent="yes" method="xml"/>

    <xsl:template match="/">
        <root>
            <CurrentDate>
                <xsl:value-of select="jscript:CurrentDate()"/>
            </CurrentDate>
            <CurrentDate>
                <xsl:value-of select="jscript:CurrentDateFormatted()"/>
            </CurrentDate>
        </root>
    </xsl:template>

    <msxsl:script language="JScript" implements-prefix="jscript"><![CDATA[
    function CurrentDate(){
        var today = new Date();
    
        return today.toLocaleDateString('ru-RU');
    }

    function CurrentDateFormatted(){
        var today = new Date();
        var Year = today.getFullYear();
        var Month = ((today.getMonth()+1).length != 2 ? "0" + (today.getMonth() + 1) : (today.getMonth()+1));
        var Day = (today.getDate().length != 2 ?"0" + today.getDate() : today.getDate());
    
        return Year + "-" + Month + "-" + Day;
    }
    ]]>
    </msxsl:script>
</xsl:stylesheet>

Результат

<?xml version="1.0" encoding="utf-8"?>
<root>
  <CurrentDate>Wednesday, July 5, 2023</CurrentDate>
  <CurrentDate>2023-07-05</CurrentDate>
</root>

XSLT 1.0 with EXSLT

Похоже, что libxslt не поддерживает функции расширения, написанные на Javascript.

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                extension-element-prefixes="date str func"
                xmlns:date="http://exslt.org/dates-and-times"
                xmlns:str="http://exslt.org/strings"
                exclude-result-prefixes="str func">
    <xsl:import href="date.format-date.function.xsl"/>
    <xsl:output indent="yes" method="xml"/>

    <xsl:template match="/">
        <root>
            <CurrentDate>
                <xsl:value-of select="date:date-time()"/>
            </CurrentDate>
            <CurrentDate>
                <xsl:value-of select="date:format-date(date:date-time(),'yyyy-MMM-dd')"/>
            </CurrentDate>
        </root>
    </xsl:template>
</xsl:stylesheet>

Результат

<?xml version='1.0' encoding='UTF-8'?>
<root>
  <CurrentDate>2023-07-05T15:37:40-04:00</CurrentDate>
  <CurrentDate>2023-Jul-05</CurrentDate>
</root>