XSL-преобразование для табличных данных - PullRequest
0 голосов
/ 10 ноября 2010

У меня есть некоторый XML, который хранит информацию столбца и данные строки из таблицы в следующей форме:

<?xml version="1.0" encoding="utf-8"?>
<table>
  <columns>
    <column id="1">
      <name>Date</name>
      <type>Date</type>
    </column>
    <column id="2">
      <name>Name</name>
      <type>String</type>
    </column>
  </columns>
  <rows>
    <row id="1">
      <columns>
        <column id="1">
          <name>Date</name>
          <value>1-Dec-2010</value>
          <localDate>1-Dec-2010 00:00:00 GMT</localDate>
        </column>
        <column id="2">
          <name>Name</name>
          <value>Jim</value>
        </column>
      </columns>
    </row>
    <row id="2">
      <columns>
        <column id="1">
          <name>Date</name>
          <value>2-Dec-2010</value>
          <localDate>2-Dec-2010 00:00:00 GMT</localDate>
        </column>
        <column id="2">
          <name>Name</name>
          <value>Jane</value>
        </column>
      </columns>
    </row>
  </rows>
</table>

ПРИМЕЧАНИЕ. Это урезанная версия моего xml.У меня намного больше строк, и я храню гораздо больше информации о каждом столбце.

Можно ли применить преобразование XSL, которое будет проходить по каждой строке в xml и выводить значение каждого столбца.Если столбец имеет тип DateTime (как указано в информации о столбце), я хочу вывести текстовое значение localDate , в противном случае я просто выведу текстовое значение value .

Я могу сделать немного XSL, но я не уверен, как вы будете проверять другую часть документа, которая по существу будет отображаться из tableModel / rows / row / columns / column в tableModel / columns / column.

По сути, я вывожу это как CSV.У меня есть код для добавления информации о столбцах для каждого / tableModel / rows / row / columns / column xml, но я считаю, что в этом нет необходимости, и это делает XML слишком большим для обработки Netbeans / Visual Studio (около 7 МБ).

Вывод, который я пытаюсь получить:

Date,Name
1-Dec-2010 00:00:00 GMT,Jim
2-Dec-2010 00:00:00 GMT,Jane

Большое спасибо,

Andez

Ответы [ 2 ]

2 голосов
/ 10 ноября 2010

Итак, следующий код производит описанный вывод для входной выборки

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">

  <xsl:param name="sep" select="','"/>
  <xsl:param name="lf" select="'&#10;'"/>

  <xsl:output method="text"/>

  <xsl:template match="/">
    <xsl:apply-templates select="table/columns/column/name"/>
    <xsl:value-of select="$lf"/>
    <xsl:apply-templates select="table/rows/row"/>
  </xsl:template>

  <xsl:template match="column/name">
    <xsl:value-of select="."/>
    <xsl:if test="position() != last()">
      <xsl:value-of select="$sep"/>
    </xsl:if>
  </xsl:template>

  <xsl:template match="rows/row">
    <xsl:apply-templates select="columns/column"/>
    <xsl:value-of select="$lf"/>
  </xsl:template>

  <xsl:template match="row/columns/column[not(localDate)]">
    <xsl:value-of select="value"/>
    <xsl:if test="position() != last()">
      <xsl:value-of select="$sep"/>
    </xsl:if>
  </xsl:template>

  <xsl:template match="row/columns/column[localDate]">
    <xsl:value-of select="localDate"/>
    <xsl:if test="position() != last()">
      <xsl:value-of select="$sep"/>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>

, но он не смотрит на соответствующий тип столбца, он просто выводит элемент localDate, если он присутствует.Этого достаточно?Пожалуйста, также укажите, можете ли вы использовать XSLT 2.0 (реализованный в AltovaXML Tools или Saxon 9), который облегчает такие вещи.

[править] Я хотел использовать ключ в шаблоне совпадений, и хотя это запрещенов XSLT 1.0, но, похоже, это работает, поэтому следующая реализация - лучшее выполнение вашего требования:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="1.0">

  <xsl:param name="sep" select="','"/>
  <xsl:param name="lf" select="'&#10;'"/>

  <xsl:key name="k1" match="table/columns/column" use="@id"/>

  <xsl:output method="text"/>

  <xsl:template match="/">
    <xsl:apply-templates select="table/columns/column/name"/>
    <xsl:value-of select="$lf"/>
    <xsl:apply-templates select="table/rows/row"/>
  </xsl:template>

  <xsl:template match="column/name">
    <xsl:value-of select="."/>
    <xsl:if test="position() != last()">
      <xsl:value-of select="$sep"/>
    </xsl:if>
  </xsl:template>

  <xsl:template match="rows/row">
    <xsl:apply-templates select="columns/column"/>
    <xsl:value-of select="$lf"/>
  </xsl:template>

  <xsl:template match="row/columns/column[not(key('k1', @id)/type = 'Date')]">
    <xsl:value-of select="value"/>
    <xsl:if test="position() != last()">
      <xsl:value-of select="$sep"/>
    </xsl:if>
  </xsl:template>

  <xsl:template match="row/columns/column[key('k1', @id)/type = 'Date']">
    <xsl:value-of select="localDate"/>
    <xsl:if test="position() != last()">
      <xsl:value-of select="$sep"/>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>
0 голосов
/ 10 ноября 2010

Это менее многословно, но, может быть ... эзотерическая таблица стилей:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:key name="kDataType" match="type" use="../@id"/>
    <xsl:template match="value|table/*/*/name">
        <xsl:variable name="vIsDateType"
                      select="key('kDataType',../@id)='Date'"/>
        <xsl:value-of
             select="concat(substring(',',
                                      1 div boolean(../preceding-sibling::*)),
                            self::name,
                            self::value[not($vIsDateType)],
                            ../localDate[$vIsDateType],
                            substring('&#xA;',
                                      1 div not(../following-sibling::*)))"/>
    </xsl:template>
    <xsl:template match="text()"/>
</xsl:stylesheet>

Выход:

Date,Name
1-Dec-2010 00:00:00 GMT,Jim
2-Dec-2010 00:00:00 GMT,Jane
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...