Математика і XSLT, Різне, Інтернет-технології, статті

Автор: Боб Дішам, 5 липня 2001
Оригінал статті: www.xml.com/
Переклад: B.Ярошевіч, 1 листопада 2001

Повна підтримка в XSLT математичних можливостей XPath дозволяє нам виконувати всі основні види арифметичних операцій і навіть трохи більше. Давайте розглянемо таблицю стилів, що демонструє ці можливості. Для цього візьмемо наступний XML-документ:

<numbers>
  <x>4</x>
  <y>3.2</y>
  <z>11</z>
</numbers>

В кожному рядку від A до N цієї таблиці стилів проводяться (або намагаються) різні обчислення. Ці обчислення проводяться над числами з документа вище і над деякими іншими, що жорстко задані в таблиці стилів або отримані за допомогою функцій, які повертають числа.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     version="1.0">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:template match="numbers">
  A. 4 + 3.2        = <xsl:value-of select="x + y"/>
  B. 3.2 - 4        = <xsl:value-of select="y - x"/>
  C. 4 * 3.2        = <xsl:value-of select="x * y"/>
  D. 11/3.2         = <xsl:value-of select="z div y"/>
  E. 4 + 3.2 * 11   = <xsl:value-of select="x+y*z"/>
  F. (4 + 3.2) * 11 = <xsl:value-of select="(x+y)*z"/>
  G. 11 mod 4       = <xsl:value-of select="z mod x"/>
  H. 4 + 3.2 + 11   = <xsl:value-of select="sum(*)"/>
  I. floor(3.2)     = <xsl:value-of select="floor(y)"/>
  J. ceiling(3.2)   = <xsl:value-of select="ceiling(y)"/>
  K. round(3.2)     = <xsl:value-of select="round(y)"/>
  L. 11 + count(*)  = <xsl:value-of select="11+count(*)"/>
  M. 3.2 + string-length("3.2") = 
     <xsl:value-of select="y + string-length(y)"/>
  N. 11 + "hello"     = <xsl:value-of select="z + 'hello'"/>
</xsl:template>
</xsl:stylesheet>

Перед тим, як говорити про те, що робиться в кожному рядку, дававайте подивимося на результат застосування таблиці стилів до нашого документу numbers.

  A. 4 + 3.2        = 7.2
  B. 3.2 - 4        = -0.8
  C. 4 * 3.2        = 12.8
  D. 11/3.2         = 3.4375
  E. 4 + 3.2 * 11   = 39.2
  F. (4 + 3.2) * 11 = 79.2
  G. 11 mod 4       = 3
  H. 4 + 3.2 + 11   = 18.2
  I. floor(3.2)     = 3
  J. ceiling(3.2)   = 4
  K. round(3.2)     = 3
  L. 11 + count(*)  = 14
  M. 3.2 + string-length("3.2") = 
     6.2
  N. 11 + "hello"     = NaN

Таблиця стилів складається з одного шаблону, який застосовується до елемента вихідного дерева numbers. Сам шаблон в свою чергу складається з набору команд xsl:value-of, В яких атрибути select використовують значення елементів x, y, І z, Дочірніх по відношенню до numbers, Для виконання різних математичних операцій. У математичних виразах, подібних цим, можна використовувати повну потужність XPath для вказівки, з яким елементом або атрибутом проводити обчислення, проте наша таблиця стилів більше призначена для демонстрації широти доступних математичних операцій, а не для того, щоб показати, як з використанням химерних виразів XPath працювати, наприклад, з елементами і атрибутами з парних частин документа.

У рядку A шаблону складаються значення x (4) і значення y (3.2) і результат їх підсумовування, 7.2, поміщається в результуюче дерево. Це досить просто, але таким чином видно, що ми не обмежені цілими числами в математиці таблиць стилів.

У рядку B ми з 3.2 віднімаємо 4, що дає -0.8. Негативні числа не повинні представляти будь-які труднощі для XSLT-процесорів.

Попередження

При роботі з деякими XSLT-процесорами використання десяткових чисел може дати невелику помилку. Наприклад, “3.2 – 4” з нашого прикладу може дати “- .7999999999999998” для деяких процесорів. І начебто помилка в .0000000000000002 Невелика, проте це показує, що математика не є сильною стороною XSLT.

У рядку C ми перемножуємо 4 і 3.2, використовуючи зірочку (*) в якості оператор множення. В результаті виходить 12.8.

У рядку D проводиться поділ значення елемента z, (11), на 3.2, що демонструє можливість XSLT-процесора виконувати ділення з плаваючою крапкою. Хоча в більшості мов програмування традиційно використовується символ слеша (/) для позначення математичного ділення, в XPath вже зарезервовано цей символ для розділення кроків у дорозі вибірки (location path) XPath (наприклад, wine/vintage для подання елемента vintage, Дочірнього по відношенню до елементу wine). Тому, XPath і XSLT використовують для позначення ділення рядок “div”.

У рядках E і F показується, що круглі дужки так само впливають на черговість виконання операторів, як і в нормальній математичній нотації: без них множення виконується перед складанням, таким чином 4 + 3.2 * 11 = 4 + 35.2. З круглими ж дужками навколо “4 +3.2” це складання виконується першим, і тепер (4 + 3.2) * 11 = 7.2 * 11.

У рядку G демонструється дія оператора mod, Який повертає залишок при діленні Перші терми на другий. Приклад показує, що 11 mod 4 дорівнює 3, так як 4 входить в 11 двічі плюс 3 в залишку. Цей оператор зручно застосовувати для перевірки ділиться Чи одне число на інше – треба тільки перевірити, чи рівний залишок нулю.

У рядку H демонструється функція sum(). Маючи список вузлів в якості аргументу, вона повертає суму всіх чисел в цьому списку. Зірочка (*) позначає “все дочірні елементи контекстного вузла”, тобто в нашому прикладі елементи x, y і z, Дочірні по відношенню до елементу numbers.

В рядки I і J ілюструють застосування функцій floor() і ceiling(). Якщо їх застосувати до цілих числах, то вони їх і повернуть. Якщо ж застосувати floor() до числа, неявляющімуся цілим, то вона поверне найбільше ціле менше аргументу. В нашому прикладі, floor(3.2) є 3. У той же час функція ceiling повертає найменше ціле число, яке більше, ніж число в аргументі; в нашому прикладі ceiling(3.2) дорівнює 4.

Функція round() в рядку K округлює число, повертаючи найближчим до нього ціле число. Так, коли на вхід їй подається 3.2, вона повертає 3, якщо ж на вході 3.5 або 3.6, то результатом буде 4.

Рядок L містить іншу XPath-функцію, count(), Яка повертає кількість вузлів в множині, зазначеному в її аргументі. XPath надає кілька функцій, які не є чисто математичними, але тим не менше повертають числа і можуть використовуватися в різних обчисленнях: count(), last(), position(), І string-length(). Так, у рядку M демонструється функція string-length(), Що повертає довжину рядка.

У рядку N демонструється, що буває, коли ви намагаєтеся провести які-небудь математичні обчислення з чимось, що не є числом: при спробі скласти 11 і рядок “Hello” результатом буде рядок “NaN” (скорочення від “Not a Number”). Коли ви берете число зі змісту елемента або значення атрибута і використовуєте його обчислень, ви не завжди можете бути впевненим, що це дійсно число, таким чином чітко певну поведінку XSLT для некоректних випадків спрощує подібну перевірку.

XSLT призначений для маніпулювання текстом, а не числами, але ви можете використовувати математичні операції, що надаються XSLT, для здійснення досить складних обчислень. Наприклад, наступна таблиця стилів, яку можна застосовувати до будь-якого документу, обчислює значення pi. Точність результату залежить від значення змінної iterations.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     version="1.0">
<xsl:output method="text"/>
 
  <xsl:when test="$i &lt;= $iterations">
    <xsl:call-template name="pi">
      <xsl:with-param name="i" select="$i + 4"/>
      <xsl:with-param name="piValue" 
           select="$piValue + (4 div $i) - (4 div ($i + 2))"/>
    </xsl:call-template>
  </xsl:when>
 
  <xsl:otherwise>
   <xsl:value-of select="$piValue"/>
  </xsl:otherwise>
  </xsl:choose>
</xsl:template>
<xsl:template match="/">
  <xsl:call-template name="pi"/>
</xsl:template>
</xsl:stylesheet>

Обчислення засноване на рекурсивному застосуванні іменованого шаблону. З таким початковим значенням iterations таблиця стилів видасть наступний результат:

3.1415259869231935

З такою кількістю ітерацій відповідь має точність аж до четвертого знака після коми. Звичайно, якщо ви хочете обчислювати значення pi більш серйозно, існує багато мов програмування, більш пристосованих для задач такого роду, але при цьому корисно знати, що при необхідності ви можете в XSLT здійснювати досить складні математичні обчислення.

Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*