Подсчет XML по условию даты с помощью xslt - PullRequest
2 голосов
/ 21 марта 2012

Я работаю с xslt впервые. У меня 2.0, но это единственное преимущество, к которому у меня есть доступ с имеющейся у нас библиотекой преобразования c #. Я пытаюсь подсчитать количество дочерних узлов в документе XML, которые содержат дату более 12 лет назад и имеют определенный атрибут типа.

Пример структуры XML:

<xml version=\"1.0\" encoding=\"utf-8\"?>
<... />
<Dependents>
<Dependent><DOB>1964-04-01</DOB><DependentType>Spouse</DependentType></Dependent>
<Dependent><DOB>2000-01-01</DOB><DependentType>Child</DependentType></Dependent>
<Dependent><DOB>2012-01-01</DOB><DependentType>Child</DependentType></Dependent>
</Dependents>
<... />

, где <... /> означает некоторые дополнительные несвязанные вещи.

Итак, я хочу, чтобы количество детей младше 12 лет. (У меня есть число зависимых типов = работающих детей всех возрастов, это просто меньше 12 лет, что доставляет мне неприятности). Подход, который мне предложили, состоял в том, чтобы создать переменную, которая существует 12 лет назад с сегодняшнего дня, и использовать ее в качестве основы для сравнения в функции count(). Это звучит разумно, но я застрял при построении даты без использования сторонних библиотек (например, exslt), которые так часто связаны в таких вопросах, как простые, удобные ответы.

xslt, который я получил за это:

<xsl:variable name="today" select="current-dateTime()" as="xs:dateTime" />
<xsl:variable name="twelveyearsago" select="xs:dateTime(concat(year-from-dateTime($today) - 12, '-', month-from-dateTime($today), '-', day-from-dateTime($today)))" />
<xsl:text>12yearsago=</xsl:text><xsl:value-of select="$twelveyearsago" />

И это не работает, потому что month-date-dateTime (и предполагаемый day-date-dateTime) не добавляет начальные нули. На сегодня, 21 марта 2012 года, я возвращаюсь: Saxon.Api.DynamicError: Недопустимое значение dateTime "2000-3-21" (месяц должен состоять из двух цифр) (ссылка на функцию W3Schools xpath подразумевает, что они должен , но они этого не делают.)

Я хотел бы вывести:

<xsl:text>&amp;numberofchildren=</xsl:text><xsl:value-of select="count(//InsuranceRequest/HealthInsurance/Dependents/Dependent/DependentType[text() = 'Child'])" />
<xsl:text>&amp;childrenunder12=</xsl:text><xsl:value-of select="children under twelve" />

Чем больше я стучу головой об это, тем больше я чувствую, что есть более простой подход, которого я просто не вижу.

Редактировать: Я очистил синтаксис xslt, чтобы он был действительным, а не строкой c # с двойными кавычками.

1 Ответ

3 голосов
/ 21 марта 2012

Вы можете просто вычесть продолжительность из 12 лет, как в <xsl:variable name="twelveyearsago" select="$today - xs:yearMonthDuration('P12Y')"/>, а затем использовать, например, //Dependent[DependentType = 'Child' and xs:date(DOB) >= $twelveyearsago].

[править] Вот шаблон, который отлично скомпилируется и выполняется с Saxon 9.4:

  <xsl:template match="/">
    <xsl:variable name="today" select="current-date()"/>
    <xsl:variable name="twelve-years-ago" select="$today - xs:yearMonthDuration('P12Y')"/>
    <xsl:value-of select="count(//Dependent[DependentType = 'Child' and xs:date(DOB) >= $twelve-years-ago])"/>
  </xsl:template>
...