Xpoint
   [напомнить пароль]

Функции расширения в XSL

Метки: [без меток]
2008-01-17 08:58:12 [обр] walek[досье]

Добрый день друзья!
Имею XML вида:

<rss version="2.0">
<channel>
   <item>
      <title>test</title>
      <id>31092</id>
      <pubDate>16.01.2008 18:02</pubDate>
   </item>
</channel>

И имею xls:

<xsl:template match="item">
<xsl:if test="js:New() &gt; substring(pubDate, 1, 2) + 1">
   new
</xsl:if>

Я хочу чтобы локальное время сравнивалось с временем публикации. Хочу это сделать с помощью функции javascript.
Имею следующий скрипт:

<SCRIPT Language="JavaScript">
<!--
function New()
{
   var today = new Date()
   var year = today.getYear()
   if(year<1000) year+=1900

   document.write(today.getDate() + "." + 
   (today.getMonth()+1) + "." + (year+"").substring(2,4))
}
//-->
</SCRIPT>

Пытаюсь это сделать в xls:

<xsl:stylesheet version="1.1"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:js="javascript:code">

<xsl:script language="javascript" implements-prefix="js">
function New()
{
   var today = new Date()
   var year = today.getYear()
   if(year<1000) year+=1900

   document.write(today.getDate() + "." + 
   (today.getMonth()+1) + "." + (year+"").substring(2,4))
}
</xsl:script>
<xsl:template match="item">
<xsl:if test="js:New() &gt; substring(pubDate, 1, 2) + 1">
   new
</xsl:if>

Процессор MSXML4.
Начинает ругаться в функции на знак < , да и вообще не работает. Что я делаю не так?
Спасибо!

спустя 10 минут [обр] Lynn «Кофеман»(52/571)[досье]
В XML символы <, > и & должны записываться как &lt;, &gt; и &amp; соответственно.
спустя 3 минуты [обр] walek[досье]
Хорошо, поправил. Но все равно не работает :(
спустя 28 минут [обр] Dennis F. Latypoff aka funky_dennis(10/78)[досье]
<xsl:script language="javascript" implements-prefix="js">
<![CDATA[
function New()
{
   var today = new Date()
   var year = today.getYear()
   if(year<1000) year+=1900

   document.write(today.getDate() + "." + 
   (today.getMonth()+1) + "." + (year+"").substring(2,4))
}
]]>
</xsl:script>
спустя 8 минут [обр] walek[досье]

Хм .... кстати, в CDATA тоже пробовал ранее обрамлять, не работает.
Думаю есть смысл привести полный XLS:

<?xml version="1.0" encoding="WINDOWS-1251"?>
<xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:js="javascript:code">

<xsl:script language="javascript" implements-prefix="js">
<![CDATA[
function New()
{
   var today = new Date()
   var year = today.getYear()
   if(year<1000) year+=1900

   document.write(today.getDate() + "." + 
   (today.getMonth()+1) + "." + (year+"").substring(2,4))
}
]]>
</xsl:script>

<xsl:output method="html" indent="yes"/>
<xsl:template match="/">
<style>
img
   {
   border: 0px;
   }
.float_l
   {
   FLOAT: left;
   }
.float_r
   {
   position: absolute;
   FLOAT: right;
   right: 1%;
   }
</style>

<xsl:apply-templates select="rss/channel"/>
</xsl:template>

<xsl:template match="channel">

<xsl:choose>
<xsl:when test="count(item) = 0">
</xsl:when>
<xsl:otherwise>
<div class="blockHead">
<div class="float_l">
<a class="blockHead" href="{link}"><xsl:value-of select="title" /></a>
</div>
<div class="float_r">
<a href="{link}"><img SRC="/info/images/List.gif" title="Список" /></a>
</div>
</div>
<xsl:apply-templates select="item"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

<xsl:template match="item">
<div class="info8ul">
<xsl:if test="image!=0">
   <img style="margin-right: 10px" align="left" src="{image/url}" />
</xsl:if>


<!--<xsl:value-of select="substring(pubDate, 1, 2)+1"  />-->

<span class="head8"><xsl:value-of select="title" /></span>
<span class="dateNews"><xsl:value-of select="substring(pubDate, 1, 5)" /></span>
&#160;<span class="head8"><xsl:value-of select="title" disable-output-escaping="yes" /></span>
&#160;<xsl:value-of select="description" disable-output-escaping="yes" />
&#160;<xsl:apply-templates select="alink"/>
</div>

</xsl:template>
<xsl:template match="alink">
<xsl:element name="a">
<xsl:attribute name="href">
<xsl:value-of select="." />
</xsl:attribute>
<xsl:attribute name="target">
<xsl:value-of select="@target" />
</xsl:attribute>
<xsl:value-of select="@text" />
</xsl:element>
</xsl:template>

</xsl:stylesheet>

спустя 2 часа 34 минуты [обр] Dennis F. Latypoff aka funky_dennis(10/78)[досье]
я, если честно, таким геморроем никогда не занимался, но есть подозрение, что JS функция должна возвращать что-то, а не печатать с помощью document.write...
спустя 14 дней [обр] walek[досье]

Хорошо, немного переписал скрипт:

function New()
{
   var d = new Date();
   var sd = "";
   if (d != null)
   {
      sd += d.getDate() + "."; 
      sd += (d.getMonth()+1)  + "."; 
      sd += d.getFullYear();
   }
   return sd;
}

Но я уже все проверил. Курил документацию. Не помогает.
Даже если просто попытаться вывести текущую дату

<xsl:value-of select="js:New()" />

Не работает.
Может все-таки кто-то сталкивался подобным?
Спасибо

спустя 1 день 2 часа [обр] Александр Лукьянов(221/781)[досье]

Похоже, не ту документацию курили :-)
XSLT 1.1 использовать не стоит вообще - хотя бы потому, что он так и остался драфтом. MSXML, AFAIR, не поддерживает ни XSLT 1.1, ни xsl:script. Вместо xsl:script у MS есть msxsl:script с аналогичной функциональностью. Т.е. писать нужно что-то вроде:

<xsl:stylesheet version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:msxsl="urn:schemas-microsoft-com:xslt"
      xmlns:js="javascript:code">

<msxsl:script language="JScript" implements-prefix="js">
...

а если нужно все-таки XSLT 1.1, то еще и дублировать все функции в xsl:script. Но мне кажется, что сильно проще передавать дату в XSLT-шаблон параметром :-)

msxml:script

спустя 2 дня 19 часов [обр] walek[досье]
Александр Лукьянов, спасибо.
Прошу прощения за навязчивость, но я так понимаю вы предлагаете передать javascript функцию преобразования даты в XSLT-шаблон параметром - <param> ?
Хм .... а не подскажите, каким образом это реализовать? Что-то я в сметении ...
спустя 1 час 3 минуты [обр] Dennis F. Latypoff aka funky_dennis(10/78)[досье]
передать не функцию, а значение.
спустя 34 минуты [обр] walek[досье]
Dennis F. Latypoff aka funky_dennis, да прошу прощения, конечно значение.
спустя 1 час 50 минут [обр] walek[досье]

Вообщем ребята получилось:

xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  xmlns:ext="urn:extension-functions"
  exclude-result-prefixes="msxsl ext">

  <xsl:output encoding="windows-1251"/>

  <msxsl:script
    language="JavaScript"
    implements-prefix="ext">
    function date()
    {  
       now = new Date;
       return now.getDate() + '.' + 
             (now.getMonth() + 1) + '.' + 
             now.getYear();
    }
  </msxsl:script>

Тогда такой вопрос. Имею дату к примеру 04.02.2008 каким образом мне прибавить один день к этой дате? Ну примерно вот так 04.02.2008 + 1. Если прибавлять таким образом, то выводится NaNa

спустя 27 минут [обр] Lynn «Кофеман»(52/571)[досье]
date = new Date;
date.setDate(date.getDate() + 1)
спустя 10 минут [обр] walek[досье]
Lynn, спасибо, но хотелось бы средствами XSL :-)
Т.е. имея дату <pubDate>04.02.2008 17:29</pubDate> могу я прибавить к ней один день, скажем вот так: substring(pubDate, 1, 10) + 1 ?
Спасибо
спустя 21 минуту [обр] Lynn «Кофеман»(52/571)[досье]
Теоретически можно, но на практике вы замучаетесь отслеживать «32 марта» и високосные года.
Лучше создавайте все нужные даты заранее и передавайте их в XSLT или используйте функции расширения.
спустя 24 минуты [обр] walek[досье]

Lynn, спасибо.
Даты выгружаются с учетом 32 марта и високосного года.
Меня вот что интересует: мне нужно сравнить 2 даты, текущую (клиентскую) и дату публикации.
И сравнить по алгоритму
Если текущая < даты публикации + 1 день, то ....
Я делаю примерно так:

<xsl:if test="ext:date() &lt; substring(pubDate, 1, 10) + 1">
text
</xsl:if>

Но, чувствую что выражение substring(pubDate, 1, 10) + 1 глупость ...

спустя 15 минут [обр] Алексей Севрюков(14/1280)[досье]
walek[досье] Правильно чувствуете. Работа с датами намного сложнее, чем простой substring и прибавление единички. Сравнивайте либо на JS, либо изначально храните нужную дату + 1 день, как говорит Lynn «Кофеман»[досье].
спустя 1 минуту [обр] Алексей Севрюков(14/1280)[досье]
P.S. Сравнить две даты в формате ISO - проблем нет (сравниваются просто как строки). Сложности именно в прибавлении 1го дня.
спустя 4 минуты [обр] Lynn «Кофеман»(52/571)[досье]
Что-то вы странного хотите…
Я бы, если уж нельзя такое сравнение сделать до преобразования, сделал бы функцию для сравнения. Т.к. сравнивать даты в вашем написании всё равно нельзя.
<xsl:if test="checkdate(pubDate)">
…
</xsl>
спустя 19 часов [обр] walek[досье]
Нужную дату + 1 день не получиться хранить, к сожалению. Располагаю только XSLT преобразованием. Хорошо. Значит нужно, значение узла pubDate перевести в дату. Я так понимаю через document.getElementById("pubDate") нужно получить доступ к значению узла в JS? Прошу прощения за глупые вопросы, если они действительно глупы, впервые занимаюсь подобным.
Спасибо.
спустя 31 минуту [обр] walek[досье]
Извиняюсь, не через document.getElementById("pubDate"), а через document.getElementByTagName("pubDate")
спустя 14 минут [обр] Dennis F. Latypoff aka funky_dennis(10/78)[досье]
Не через document.getElementByTagName("pubDate"), а через document.getElementsByTagName("pubDate")
спустя 12 минут [обр] Александр Лукьянов(221/781)[досье]
walek[досье]
А может, проще использовать Date and times? Msxml вроде все поддерживает, заодно можете посмотреть, как там реализована работа с датами.
спустя 6 дней [обр] walek[досье]

Алексей Севрюков, прошу прощения что фактически спрашиваю не по теме, но все-же.
Решил получить доступ к дате вот так:

  function convertDate(strData){
      var NewData = "";
      if (strData[0].text=="")
         return NewData;
      var Day = strData[0].text.substr(0, 10);
      return Day;
   }

Функцию вызываю так <xsl:value-of select="ext:convertDate(pubDate)" /> pubDate содержит 04.02.2008 17:29
Дата вываливается в формате дд.мм.гг.
Хорошо, тогда пробую преобразовывать строку в дату, пробую вот так:

  function convertDate(strData){
      var NewData = "";
      if (strData[0].text=="")
         return NewData;
      var Day = strData[0].text.substr(0, 10);
      return Day;
      var converted = Date.parse(Day);
      var myDate = new Date(converted);
      return myDate;   
   }

Но преобразования не происходит.
Где моя ошибка?
Спасибо.

спустя 1 час 2 минуты [обр] Алексей Севрюков(14/1280)[досье]
Помоему Вам просто нужно почитать про даты и методы работы с ними в JS. Думаю все сразу станет понятно.
спустя 7 дней [обр] walek[досье]

Да, действительно был пробел в знаниях.
Прочитал, подумал. Использую вот такой скрипт:

<?xml version="1.0" encoding="WINDOWS-1251"?>
<xsl:stylesheet
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:msxsl="urn:schemas-microsoft-com:xslt"
  xmlns:ext="urn:extension-functions"
  exclude-result-prefixes="msxsl ext">

<xsl:output encoding="windows-1251"/>

<msxsl:script
    language="JavaScript"
    implements-prefix="ext">

<![CDATA[
function convertDate(strData)
{
   var pubDateTxt = strData[0].text.substr(0); //Дата из <pubDate>19.2.2008 17:25</pubDate>
   pubDateTxt = pubDateTxt
      .replace(/\./g, '/')
      .replace(/^(\d+\/)(\d+\/)/, function($0, $1, $2)
      {
         return $2 + $1;
      });
   var pubDateObj = new Date(pubDateTxt);
   var now = new Date();
   if (now - pubDateObj > 60 * 60 * 24 * 1000)
   {
      var txt = 'NEW!';
       return txt;
   }
}
]]>
</msxsl:script>

Вывожу так:

<xsl:value-of select="ext:convertDate(pubDate)" /><BR />

Не подскажите, что я упустил?
Спасибо!

спустя 1 минуту [обр] walek[досье]
Скрипт рабочий. Все в порядке. Но в XSLT не работает :(
спустя 21 час [обр] Александр Лукьянов(221/781)[досье]
Функция должна возвращать значение, которое XSLT-процессор может преобразовать к одному из типов, которые ему известны.
Если Вы пишете под MSXML, то можете дебаггинг производить прямо в IE - просто открывать в нем XML-файл, все ошибки получите на экран.
спустя 5 дней [обр] walek[досье]
Проблему разрешил, всем спасибо!
Powered by POEM™ Engine Copyright © 2002-2005