Выбор XPath на основе атрибутов даты истечения срока действия - PullRequest
1 голос
/ 24 апреля 2009

Учитывая этот XML:

<?xml version="1.0" encoding="utf-8"?>
<content dataType="XML">
  <item type="Promotion" name="Sample Promotion" expires="04/01/2009">
    <![CDATA[
      <p>Details here.</p>
    ]]>
  </item>
  <item type="Promotion" name="Sample Promotion 2" expires="05/01/2009">
    <![CDATA[
      <p>Details here.</p>
    ]]>
  </item>
</content>

Каким будет XPath для выбора предметов, которые еще не истекли?

Ответы [ 4 ]

2 голосов
/ 24 апреля 2009

Элементы с истекшим сроком действия <item> могут быть выбраны одним выражением XPath , если указана текущая дата - либо в переменной, либо в виде буквенной строки.

В приведенном ниже решении в качестве языка хостинга для XPath 1.0 используется XSLT 1.0.

Для удобства текущая дата указана как глобальный <xsl:param> параметр с именем pToday.

Другое удобство заключается в том, что значения для текущего года, месяца и дня определяются в переменных $vthisYear, $vthisMonth и $vthisDay. При необходимости все эти ссылки на переменные могут быть заменены в выражении XPath правой частью их определений.

Требуемое одиночное выражение XPath включено в следующее преобразование XSLT:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"
  cdata-section-elements="item"/>


 <xsl:param name="pToday" select="'04/23/2009'"/>

 <xsl:variable name="vthisDay" select=
  "substring($pToday,4,2)"/>

 <xsl:variable name="vthisMonth" select=
  "substring($pToday,1,2)"/>

 <xsl:variable name="vthisYear" select=
  "substring($pToday,7)"/>

    <xsl:template match="/">
     <nonExpired>
          <xsl:copy-of select=
          "/*/item
                [$vthisYear &lt; substring(@expires,7)
               or
                  ($vthisYear = substring(@expires,7)
                 and
                   $vthisMonth &lt; substring(@expires,1,2)
                   )
             or
                  ($vthisYear = substring(@expires,7)
                 and
                   $vthisMonth = substring(@expires,1,2)
                 and
                   $vthisDay &lt;= substring(@expires,4,2)
                   )
                ]

          "/>
      </nonExpired>
    </xsl:template>
</xsl:stylesheet>

Когда вышеуказанное преобразование применяется к предоставленному документу XML :

<content dataType="XML">
    <item type="Promotion" name="Sample Promotion" expires="04/01/2009"><![CDATA[      <p>Details here.</p>    ]]></item>
    <item type="Promotion" name="Sample Promotion 2" expires="05/01/2009"><![CDATA[      <p>Details here.</p>    ]]></item>
</content>

желаемый результат получается :

<nonExpired>
   <item type="Promotion" name="Sample Promotion 2" expires="05/01/2009"><![CDATA[      <p>Details here.</p>    ]]></item>
</nonExpired>

Примечание : Решение oneporter также будет работать при условии исправления некоторых мелких ошибок в нем. Кроме того, он нуждается в доработке из-за нереалистичного ожидания, что текущая дата будет предоставлена ​​в другом формате, чем даты в атрибутах @expires.

1 голос
/ 24 апреля 2009

Я новичок в xslt, но если вы используете 1.0 или 1.1, я бы где-то получил текущую дату, а затем сравнил две строки. Эта страница описывает методы dos и * nix для извлечения даты. Тогда я, вероятно, реорганизовал бы значения так, чтобы они были сопоставимы (я предполагаю, что $ current_date - это строка формата YYYYMMDD)

<xsl:if test="number(concat(substring(.[@expires],5,4),
   substring(.[@expires],3,2),substring(.[@expires],1,2))&lt;number(
   $current_date">
...
</xsl>

Но, как я уже сказал, я только начал с xsl. Так что это может быть действительно неуклюжим решением простой проблемы.

0 голосов
/ 24 апреля 2009

XPath 2.0 поддерживает некоторые функции даты:

http://www.w3.org/TR/xpath-functions/#durations-dates-times

http://www.w3.org/TR/xpath-functions/#func-date-less-than

0 голосов
/ 24 апреля 2009

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

В качестве альтернативы, вы можете использовать подстроки для извлечения фрагментов атрибута. Однако вы столкнетесь с проблемами, если атрибуты не отформатированы точно, а выражения будут огромными.

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