Книга: Технология XSLT

Данные, разделенные запятыми (CSV)

Данные, разделенные запятыми (CSV)

Рекурсивную методику замены, которую мы представили выше, можно использовать для того, чтобы разметить данные, разделенные запятыми (или CSV, comma-separated values). CSV — это старый простой формат представления данных, в котором они просто перечисляются через запятую, например:

a, b, с, d, e, f, g

и так далее. Формат CSV был одним из первых шагов к созданию языков разметки: данные в нем уже размечались запятыми.

Покажем на простом примере, как можно преобразовать CSV-данные в XML-документ. Пусть входящий документ выглядит как:

<data>a, b, с, d, e, f</data>

Для того чтобы решение было как можно более общим, вынесем создание XML-разметки для каждого из элементов этой последовательности в отдельный шаблон:

<xsl:template name="item">
 <xsl:param name="item"/>
 <item><xsl:copy-of select="$item"/></item>
</xsl:template>

Тогда головной размечающий шаблон запишется в виде.

Листинг 11.18. Шаблон, размечающий данные в строковом формате

<xsl:template name="markup" match="text()" mode="CSV">
 <xsl:param name="str" select="."/>
 <xsl:param name="delimiter" select="','"/>
 <xsl:choose>
  <xsl:when test="contains($str,$delimiter)">
   <xsl:call-template name="item">
    <xsl:with-param name="item"
     select="substring-before($str, $delimiter)"/>
   </xsl:call-template>
   <xsl:call-template name="markup">
    <xsl:with-param name="str"
     select="substring-after($str, $delimiter)"/>
   </xsl:call-template>
   <xsl:with-param name="delimiter" select="$delimiter"/>
  </xsl:when>
  <xsl:otherwise>
   <xsl:call-template name="item">
    <xsl:with-param name="item" select="$str"/>
   </xsl:call-template>
  </xsl:otherwise>
 </xsl:choose>
</xsl:template>

На вход шаблон markup принимает два параметра — str, строка, которую нужно разметить (по умолчанию — значение текущего узла) и delimiter — строка, разделяющая отдельные значения в str (по умолчанию — запятая ",").

Шаблон, форматирующий содержимое элемента data, будет в таком случае выглядеть следующим образом:

<xsl:template match="data">
 <xsl:copy>
  <xsl:apply-templates mode="CSV"/>
 </xsl:copy>
</xsl:template>

Результат этого преобразования будет иметь следующий вид:

<data>
 <item>a</item>
 <item> b</item>
 <item> c</item>
 <item> d</item>
 <item> e</item>
 <item> f</item>
</data>

Обратим внимание на то, что в элементах item присутствуют лишние пробелы, которые в начальной последовательности шли за запятыми. Избавиться от них можно, указав в качестве разделяющей строки символ ", ":

<xsl:template match="data">
 <xsl:copy>
  <xsl:apply-templates mode="CSV">
   <xsl:with-param name="delimiter" select="', '"/>
  </xsl:apply-templates>
 </xsl:copy>
</xsl:template>

Результатом, как и следовало ожидать, будет:

<data>
 <item>a</item>
 <item>b</item>
 <item>c</item>
 <item>d</item>
 <item>e</item>
 <item>f</item>
</data>

Кстати сказать, того же эффекта можно было добиться, изменив шаблон item, который отвечает за XML-представление каждого из элементов последовательности.

Оглавление книги


Генерация: 1.207. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз