2014-10-26 2 views
-2

У меня есть файл XML, который я экспортировать из моей БД, которая структурирована, как показано ниже, 'XML в HTML-таблицы, используя XSL

<output> 
    <row> 
     <Month>October</Month> 
     <Location>kansas</Location> 
     <bus_name>bus1</bus_name> 
     <bus_type>volvo</bus_type> 
     <bus_colour>red</bus_colour> 
     <bus_count>10</bus_count> 
    </row> 
    <row> 
     <Month>October</Month> 
     <Location>kansas</Location> 
     <bus_name>bus1</bus_name> 
     <bus_type>Volvo</bus_type> 
     <bus_colour>green</bus_colour> 
     <bus_count>11</bus_count> 
    </row> 
     <Month>October</Month> 
     <Location>kansas</Location> 
     <bus_name>bus1</bus_name> 
     <bus_type>Merc</bus_type> 
     <bus_colour>blue</bus_colour> 
     <bus_count>5</bus_count> 
    </row> 
So on... 
</output> 

Мне нужен стол, чтобы посмотреть, как изображение прилагается ниже. Файл XSL и XML будет обновляться периодически. Ячейки будут иметь аналогичный цвет на основе типа шины.

Я новичок в XSL, поэтому очень сложно найти решение. Любая помощь будет оценена по достоинству.

Table Output

+0

У вас есть * конкретный вопрос? –

+0

Мне нужен XSL, который поможет мне получить таблицу из XML, который у меня есть. Основная задача - упорядочить данные в соответствии с таблицей, поскольку XML и таблица не имеют прямого прямого сопоставления. – Curious

+0

Прочтите учебник XSLT. –

ответ

0

Как разный подход, а также обработка цветов для одних и тех же bus_types.
Demo

<?xml version="1.0"?> 
<xsl:stylesheet 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
<xsl:output method="html"/> 
<xsl:template match="/"> 
<table> 
    <tr> 
     <td colspan="9">ACME BUS SERVICE</td> 
    </tr> 
    <tr> 
     <td colspan="9"> 
      Month: <xsl:value-of select="//Month"/> 
     </td> 
    </tr> 
    <tr> 
     <td>Season</td> 
     <td>Location</td> 
     <td>Bus Name</td> 
     <td colspan="2">RED</td> 
     <td colspan="2">GREEN</td> 
     <td colspan="2">BLUE</td> 
    </tr> 
    <tr> 
     <td></td> 
     <td></td> 
     <td></td> 
     <td>Bus Type</td> 
     <td>Bus Count</td> 
     <td>Bus Type</td> 
     <td>Bus Count</td> 
     <td>Bus Type</td> 
     <td>Bus Count</td> 
    </tr> 
    <xsl:for-each select="//row[Location[not(preceding::Location/. = .)]]" > 
     <xsl:variable name="currentLocation" select="./Location"/> 
     <tr> 
      <xsl:attribute name="class"> 
       <xsl:value-of select="$currentLocation"/> 
      </xsl:attribute> 
      <td> 
       <xsl:if test="position()=1">Winter</xsl:if> 
      </td> 
      <td> 
       <xsl:value-of select="$currentLocation"/> 
      </td> 
      <td> 
       <xsl:value-of select="./bus_name"/> 
      </td> 
      <td> 
       <xsl:if test="count(//row[Location= $currentLocation] 
             [bus_type = //row[Location= $currentLocation] 
             [bus_colour = 'red']/bus_type]) > 1"> 
        <xsl:attribute name="class">color</xsl:attribute> 
       </xsl:if> 
       <xsl:value-of select="//row[Location= $currentLocation] 
              [bus_colour = 'red']/bus_type"/> 
      </td> 
      <td> 
       <xsl:value-of select="//row[Location= $currentLocation] 
              [bus_colour = 'red']/bus_count"/> 
      </td> 
      <td> 
       <xsl:if test="count(//row[Location= $currentLocation] 
             [bus_type = //row[Location=$currentLocation] 
             [bus_colour = 'green']/bus_type]) > 1"> 
        <xsl:attribute name="class">color</xsl:attribute> 
       </xsl:if> 
       <xsl:value-of select="//row[Location= $currentLocation] 
              [bus_colour = 'green']/bus_type"/> 
      </td> 
      <td> 
       <xsl:value-of select="//row[Location= $currentLocation] 
              [bus_colour = 'green']/bus_count"/> 
      </td> 
      <td> 
       <xsl:if test="count(//row[Location= $currentLocation] 
             [bus_type = //row[Location=$currentLocation] 
             [bus_colour = 'blue']/bus_type]) > 1"> 
        <xsl:attribute name="class">color</xsl:attribute> 
       </xsl:if> 
       <xsl:value-of select="//row[Location= $currentLocation] 
              [bus_colour = 'blue']/bus_type"/> 
      </td> 
      <td> 
       <xsl:value-of select="//row[Location= $currentLocation] 
              [bus_colour = 'blue']/bus_count"/> 
      </td> 
     </tr> 
    </xsl:for-each> 
</table> 
</xsl:template> 
</xsl:stylesheet> 

Для каждого местоположения, местоположение устанавливается как имя класса к <tr>, например <tr class="kansas">. Каждый td с типом шины, который используется более одного раза в месте, получает класс = «цвет». Таким образом, чтобы отобразить таблицу с разными цветами, вы можете просто добавить CSS, например, например. .kansas .color { background-color: blue; }. Если вы хотите отобразить один и тот же цвет на основе типа bus_type, просто отредактируйте имя класса «цвет» в xslt для текущего типа bus_type.

Примечание: В связанном примере я добавил только одну строку для Техаса, чтобы показать, что XSLT отображает несколько местоположений, устанавливает сезон только для первого, а также будет работать, если не все цвета предоставляются для место нахождения. И выход недействителен HTML (без html-, head-, body-tags и т. Д.). Как вы уже упоминали, вы хотите получить HTML-выход, у вас, вероятно, уже есть XSLT, генерирующий действительный HTML-код, в котором вы можете настроить/включить часть, которая вам нужна для таблицы.

Update на вопрос в комментариях: Чтобы задать имя класса для <tr> на имя bus_type (в случае bus_type используется более чем один раз в месте) вместо местоположения:

Изменить это выше XSLT:

<tr> 
<xsl:attribute name="class"> 
    <xsl:value-of select="$currentLocation"/> 
</xsl:attribute> 

в

<tr> 
<xsl:if test="count(//row[Location=$currentLocation]) > 
       count(//row[Location=$currentLocation]/ 
         bus_type[not(. = preceding::bus_type)])"> 
    <xsl:attribute name="class"> 
     <xsl:value-of select="//row[Location=$currentLocation]/ 
           bus_type[ . = preceding::bus_type]"/> 
    </xsl:attribute> 
</xsl:if> 

Обновлено Demo 2 для этого.

Дополнительные примечания и вопросы: Одна настройка для OP XML заключалась в том, чтобы изменить строчный «volvo» на «Volvo».В случае, если исходный экспорт из БД действительно смешивает имена верхнего и нижнего регистра, это можно обрабатывать в XSLT, чтобы вводить все шинные имена (для получения уникальных значений), а в верхнем регистре - первую букву для значения в <td>. Также было бы полезно знать, используете ли вы XSLT 2.0 или XSLT 1.0, поскольку XSLT 2.0 предоставляет функции для упрощения некоторых задач - например, 2.0 предоставляет функцию lower-case(), где в версии 1.0 это может быть достигнуто с использованием translate(). В качестве ссылки для этого, как вы упомянули, вы новичок в XSL: How can I convert a string to upper- or lower-case with XSLT?
Дальнейший вопрос: поскольку пример XML является только частью экспорта DB - если для каждого местоположения будет только одна строка или если возможно, что существуют различные строки, например kansas bus1, kansas bus2 и т. д.

Обновление 2 для второго вопроса в комментариях: я могу добавить (почти) объяснение строки за строкой и оставить комментарий после завершения. Я предполагаю, что нет необходимости покрывать часть HTML, но только XSLT. В то же время, как вы упомянули вы новичок в XSLT, может быть, может быть полезным следующее:
для <xsl:template match="/"> - https://stackoverflow.com/questions/3127108/xsl-xsltemplate-match
для XPath осей - http://www.xmlplease.com/axis
для некоторых основ, например, - In what order do templates in an XSLT document execute, and do they match on the source XML or the buffered output?

Обратите внимание, что в SO следует избегать расширенных комментариев - при наличии слишком большого количества комментариев ниже сообщения будет отображаться автоматическое сообщение, предлагающее перейти в чат. Поскольку вам нужна репутация 20 в чате (https://stackoverflow.com/help/privileges), на данный момент это будет невозможно.

+0

GENIUS! .. Работает как очарование! – Curious

+0

Я хотел бы применить другой цвет к разным строкам подходящего типа шины. Это будет слишком сложно? – Curious

+0

@ Curious Glad Я был в состоянии помочь. Re diff. цвет: это зависит. Если вы хотите только цветные типы шин, которые используются более одного раза в одной строке, это не проблема, потому что вы можете установить diff. цвета в зависимости от родительского tr (например, .kansas .volvo - синий, .texas .volvo - красный, если вы хотите изменить имя класса на тип шины, но это также будет работать с использованием .color для td). Если вы хотите окрасить, например. volvo в texas, когда он используется только один раз, это будет другой подход, поскольку в настоящее время только типы шин окрашиваются, когда они используются более одного раза в одном месте. –

0

Первые три узла должен быть отображен с первым рядом

Теперь , что является конкретным вопросом. Предполагая, что ваш вход устроен так, что каждая группа из 3-х последовательных <row> элементов карты в одной строке таблицы (внутренние позиции группы совпадающих позиций столбцов), попробуйте это следующим образом:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output method="xml" omit-xml-declaration="yes" version="1.0" encoding="utf-8" indent="yes"/> 

<xsl:template match="/output"> 
    <table border="1"> 
     <tr> 
      <!-- build your header here --> 
     </tr> 
     <xsl:for-each select="row[position() mod 3 = 1]" > 
      <tr> 
       <td><xsl:value-of select="Location"/></td> 
       <td><xsl:value-of select="bus_name"/></td> 
       <xsl:for-each select=". | following-sibling::row[position() &lt; 3]"> 
        <td><xsl:value-of select="bus_type"/></td> 
        <td><xsl:value-of select="bus_colour"/></td> 
        <td><xsl:value-of select="bus_count"/></td> 
       </xsl:for-each> 
      </tr> 
     </xsl:for-each> 
    </table> 
</xsl:template> 

</xsl:stylesheet> 

Я предлагаю вам задать отдельный вопрос относительно окраски. Удостоверьтесь, что мы точно понимаем, что известно заранее (например, список известных типов шин?) И каков требуемый результат (отправьте его в качестве кода).

+0

Спасибо Майку за ответ, я опробовал XSL вы предоставили, но т Im получать только Канзас и автобусов 1 в первом ряду, остальное пусто, и им только получать одну строку, заголовок Расположение Bus Имя RED GREEN BLUE – Curious

+0

@Curious http://www.xsltcake.com/slices/9ys6fT - P.S. убедитесь, что ваш вход хорошо сформирован; то, что вы разместили здесь, нет. –

+0

Как просмотреть его в формате таблицы HTML? – Curious