Таблица XML в HTML с помощью XSLT - PullRequest
4 голосов
/ 14 апреля 2011

Мне нужно иметь возможность превратить простые наборы данных xml в таблицы html, и у меня возникают проблемы с поиском примеров синтаксиса, которые соответствуют моим потребностям.Я хотел бы использовать одну таблицу стилей, которая может конвертировать похожие выглядящие наборы данных в HTML-таблицы с переменными столбцами.Это означает, что он не может использовать любые жестко закодированные имена элементов, кроме «строк» ​​и «строк».

Таблица стилей, которую я ищу, сможет преобразовать:

<?xml version="1.0" encoding="UTF-8"?>
<rows>
  <row>
    <AccountId>BlPUAA0</AccountId>
    <AccountName>Initech</AccountName>
    <AcocuntStatus>Client</AcocuntStatus>
  </row>
  <row>
    <AccountId>CJxIAAW</AccountId>
    <AccountName>Intertrode</AccountName>
    <AcocuntStatus>Prospect</AcocuntStatus>
  </row>
</rows>

в:

<table>
  <tr>
    <th>AccountId</th>
    <th>AccountName</th>
    <th>AcocuntStatus</th>
  </tr>
  <tr>
    <td>BlPUAA0</td>
    <td>Initech</td>
    <td>Client</td>
  </tr>
  <tr>
    <td>CJxIAAW</td>
    <td>Intertrode</td>
    <td>Client</td>
  </tr>
</table>

и это:

<?xml version="1.0" encoding="UTF-8"?>
<rows>
  <row>
    <AccountId>BlPUAA0</AccountId>
    <AccountName>Initech</AccountName>
  </row>
  <row>
    <AccountId>CJxIAAW</AccountId>
    <AccountName>Intertrode</AccountName>
  </row>
</rows>

в это:

<table>
  <tr>
    <th>AccountId</th>
    <th>AccountName</th>
  </tr>
  <tr>
    <td>BlPUAA0</td>
    <td>Initech</td>
  </tr>
  <tr>
    <td>CJxIAAW</td>
    <td>Intertrode</td>
  </tr>
</table>

Ответы [ 4 ]

6 голосов
/ 14 апреля 2011

Простое и короткое решение :

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

 <xsl:template match="/*">
     <table><xsl:apply-templates select="row"/></table>
 </xsl:template>

 <xsl:template match="row[1]">
  <tr><xsl:apply-templates select="*" mode="header"/></tr>
  <xsl:call-template name="standardRow"/>
 </xsl:template>

 <xsl:template match="row" name="standardRow">
  <tr><xsl:apply-templates select="*"/></tr>
 </xsl:template>

 <xsl:template match="row/*">
  <td><xsl:apply-templates select="node()"/></td>
 </xsl:template>

 <xsl:template match="row/*" mode="header">
  <th><xsl:value-of select="name()"/></th>
 </xsl:template>
</xsl:stylesheet>

при применении к первому предоставленному документу XML :

<rows>
    <row>
        <AccountId>BlPUAA0</AccountId>
        <AccountName>Initech</AccountName>
        <AcocuntStatus>Client</AcocuntStatus>
    </row>
    <row>
        <AccountId>CJxIAAW</AccountId>
        <AccountName>Intertrode</AccountName>
        <AcocuntStatus>Prospect</AcocuntStatus>
    </row>
</rows>

желаемый, правильный результат получается:

<table>
   <tr>
      <th>AccountId</th>
      <th>AccountName</th>
      <th>AcocuntStatus</th>
   </tr>
   <tr>
      <td>BlPUAA0</td>
      <td>Initech</td>
      <td>Client</td>
   </tr>
   <tr>
      <td>CJxIAAW</td>
      <td>Intertrode</td>
      <td>Prospect</td>
   </tr>
</table>

при применении ко второму предоставленному документу XML:

<rows>
    <row>
        <AccountId>BlPUAA0</AccountId>
        <AccountName>Initech</AccountName>
    </row>
    <row>
        <AccountId>CJxIAAW</AccountId>
        <AccountName>Intertrode</AccountName>
    </row>
</rows>

снова желаемый, правильный результат:

<table>
   <tr>
      <th>AccountId</th>
      <th>AccountName</th>
   </tr>
   <tr>
      <td>BlPUAA0</td>
      <td>Initech</td>
   </tr>
   <tr>
      <td>CJxIAAW</td>
      <td>Intertrode</td>
   </tr>
</table>
4 голосов
/ 15 апреля 2011

У меня возникло желание попытаться решить эту проблему вскоре после публикации вопроса, и вот что я придумала. Я полагаю, это заставляет вас ждать 24 часа, прежде чем вы сможете ответить на него самостоятельно.

<?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" indent="yes" omit-xml-declaration="yes"/>
  <xsl:template match="/">
    <table>
      <tr>
        <xsl:for-each select="rows/row[1]/*">
          <th>
            <xsl:value-of select ="local-name()"/>
          </th>
        </xsl:for-each>
      </tr>
      <xsl:for-each select="rows/row">
        <tr>
          <xsl:for-each select="*">
            <td>
              <xsl:value-of select="."/>
            </td>
          </xsl:for-each>
        </tr>
      </xsl:for-each>
    </table>
  </xsl:template>
</xsl:stylesheet>
2 голосов
/ 14 апреля 2011

Эта таблица стилей:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <table>
            <xsl:apply-templates select="rows/row[1]" />
        </table>
    </xsl:template>
    <xsl:template match="row">
        <tr>
            <xsl:apply-templates mode="th" />
        </tr>
        <xsl:apply-templates select="../row" mode="td" />
    </xsl:template>
    <xsl:template match="row/*" mode="th">
        <th>
            <xsl:value-of select="local-name()" />
        </th>
    </xsl:template>
    <xsl:template match="row" mode="td">
        <tr>
            <xsl:apply-templates />
        </tr>
    </xsl:template>
    <xsl:template match="row/*">
        <td>
            <xsl:apply-templates />
        </td>
    </xsl:template>
</xsl:stylesheet>

Применительно к:

<rows>
    <row>
        <AccountId>BlPUAA0</AccountId>
        <AccountName>Initech</AccountName>
        <AcocuntStatus>Client</AcocuntStatus>
    </row>
    <row>
        <AccountId>CJxIAAW</AccountId>
        <AccountName>Intertrode</AccountName>
        <AcocuntStatus>Prospect</AcocuntStatus>
    </row>
</rows>

Производит:

<table>
    <tr>
        <th>AccountId</th>
        <th>AccountName</th>
        <th>AcocuntStatus</th>
    </tr>
    <tr>
        <td>BlPUAA0</td>
        <td>Initech</td>
        <td>Client</td>
    </tr>
    <tr>
        <td>CJxIAAW</td>
        <td>Intertrode</td>
        <td>Prospect</td>
    </tr>
</table>

И применяется к:

<rows>
  <row>
    <AccountId>BlPUAA0</AccountId>
    <AccountName>Initech</AccountName>
  </row>
  <row>
    <AccountId>CJxIAAW</AccountId>
    <AccountName>Intertrode</AccountName>
  </row>
</rows>

Производит:

<table>
    <tr>
        <th>AccountId</th>
        <th>AccountName</th>
    </tr>
    <tr>
        <td>BlPUAA0</td>
        <td>Initech</td>
    </tr>
    <tr>
        <td>CJxIAAW</td>
        <td>Intertrode</td>
    </tr>
</table>

В качестве альтернативы, эта таблица стилей выдает тот же вывод, используя условный шаблон и на один шаблон меньше:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <table>
            <xsl:apply-templates select="rows/row" />
        </table>
    </xsl:template>
    <xsl:template match="row">
        <xsl:if test="position()=1">
            <tr>
                <xsl:apply-templates mode="th" />
            </tr>
        </xsl:if>
        <tr>
            <xsl:apply-templates />
        </tr>
    </xsl:template>
    <xsl:template match="row/*" mode="th">
        <th>
            <xsl:value-of select="local-name()" />
        </th>
    </xsl:template>
    <xsl:template match="row/*">
        <td>
            <xsl:apply-templates />
        </td>
    </xsl:template>
</xsl:stylesheet>
0 голосов
/ 29 июля 2014

Несколько дней назад я опубликовал статью, надеюсь, она вам поможет: http://web.swfideas.com/?p=12191

Исходя из этих данных:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Edited by XMLSpy -->
<table-node>
  <tbody>
    <tr>
      <td>[C1R1]</td>
      <td>[C2R1]</td>
    </tr>
    <tr>
      <td>[C1R2]</td>
      <td>[C2R2]</td>
    </tr>
    <tr>
      <td>[C1R3]</td>
      <td>[C2R3]</td>
    </tr>
  </tbody>
</table-node>

Теперь ядро ​​нашего XSLT-шаблона:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!-- Coded by SWFideas -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- table template -->
<xsl:template match="table-node">
    <table style="border:solid #000000 1px;border-spacing: 0;border-collapse: collapse;">
        <xsl:for-each select="tbody">
            <tbody>
                <xsl:for-each select="tr">
                    <tr>
                        <xsl:for-each select="td">
                            <td style="border:solid #000000 1px; padding: 5px;">
                                <xsl:value-of select="."/>
                            </td>
                        </xsl:for-each>                     
                    </tr>                 
                </xsl:for-each>
            </tbody>
        </xsl:for-each>
    <table>
</xsl:template>
</xsl:stylesheet>

В этом первом подходе я избегаю использования COLSPAN и других реальных свойств (обещаю, что это скоро произойдет). Таким образом, результат, если мы применим наш XSLT, будет таким:

<table style="border:solid #000000 1px;border-spacing: 0;border-collapse: collapse;">
    <tbody>
        <tr>
            <td style="border:solid #000000 1px; padding: 5px;">[C1R1]</td>
            <td style="border:solid #000000 1px; padding: 5px;">[C2R1]</td>
        </tr>
        <tr>
            <td style="border:solid #000000 1px; padding: 5px;">[C1R2]</td>
            <td style="border:solid #000000 1px; padding: 5px;">[C2R2]</td>
        </tr>
        <tr>
            <td style="border:solid #000000 1px; padding: 5px;">[C1R3]</td>
            <td style="border:solid #000000 1px; padding: 5px;">[C2R3]</td>
        </tr>
    </tbody>
</table>

Вы можете попробовать это здесь: http://www.xsltcake.com/slices/gNfh6i/2

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...