Использование XSLT для создания хорошо отформатированной вложенной таблицы из неизвестного XML

1

Задача, которую я дал: Мой босс хочет, чтобы я создал XSLT, который принимает XML неизвестной структуры, и помещал его во вложенную таблицу (имена тегов в виде заголовков таблицы), не повторяя, по возможности, заголовки таблиц. Я почти мог получить то, что он хочет (таблица)

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

Данные среды: Я работаю с XSLT и PHP (объекты DOM). Мой босс хочет, чтобы я стал экспертом XSLT в компаниях, поэтому, если это возможно через чистый XSLT, это будет оценено.

Дополнительная информация: по запросу людей, отвечающих на запросы, дополнительная информация (код) ниже. Задача состоит в том, чтобы сделать что-то вроде фрагмента XML ниже в таблице ниже для отображения. К сожалению, код, который у меня был, в настоящее время находится в состоянии потока, поэтому я не буду его публиковать (если вопрос все еще остается открытым, когда я снова получаю его стабильным, я отправлю его).

XML-фрагмент:

<root>
    <request>
        <details>
            <columnname>name1</columnname>
            <operator></operator>
            <value>val</value>
            <seq>1</seq>
        </details>
    </request>
    <request>
        <details>
            <columnname>name2</columnname>
            <operator>OP</operator>
            <value>val</value>
            <seq>2</seq>
        </details>
    </request>
    <request>
        <details>
            <columnname>name3</columnname>
            <value>val</value>
            <seq>3</seq>
        </details>
    </request>
    <response>
        <details>
            <columnname>name4</columnname>
            <value>val</value>
            <seq>4</seq>
        </details>
    </response>
</root>

Желаемый результат

<table border="1" style="border-collapse:collapse;width:100%">
    <tr>
        <th>root</th>
    </tr>
    <tr>
        <td>
            <table border="1" style="border-collapse:collapse;width:100%">
                <tr>
                    <th>request</th>
                    <th>response</th>
                </tr>
                <tr>
                    <td>
                        <table border="1" style="border-collapse:collapse;width:100%">
                            <tr>
                                <th>details</th>
                            </tr>
                            <tr>
                                <td>
                                    <table border="1" style="border-collapse:collapse;width:100%">
                                        <tr>
                                            <th>columnname</th>
                                            <th>operator</th>
                                            <th>value</th>
                                            <th>seq</th>
                                        </tr>
                                        <tr>
                                            <td>name1</td>
                                            <td></td>
                                            <td>val</td>
                                            <td>1</td>
                                        </tr>
                                        <tr>
                                            <td>name2</td>
                                            <td>OP</td>
                                            <td>val</td>
                                            <td>2</td>
                                        </tr>
                                        <tr>
                                            <td>name3</td>
                                            <td></td>
                                            <td>val</td>
                                            <td>3</td>
                                        </tr>
                                    </table>
                                </td>
                            </tr>
                        </table>
                    </td>
                    <td>
                        <table border="1" style="border-collapse:collapse;width:100%">
                            <tr>
                                <th>details</th>
                            </tr>
                            <tr>
                                <td>
                                    <table border="1" style="border-collapse:collapse;width:100%">
                                        <tr>
                                            <th>columnname</th>
                                            <th>value</th>
                                            <th>seq</th>
                                        </tr>
                                        <tr>
                                            <td>name4</td>
                                            <td>val</td>
                                            <td>4</td>
                                        </tr>
                                    </table>
                                </td>
                            </tr>
                        </table>
                    </td>
                </tr>
            </table>
        </td>
    </tr>
</table>

Ответ на michael.hor257k: Он будет выглядеть примерно так.

<table border="1" style="border-collapse:collapse;width:100%">
    <tr>
        <th>root</th>
    </tr>
    <tr>
        <td>
            <table border="1" style="border-collapse:collapse;width:100%">
                <tr>
                    <th>parent</th>
                    <th>uncle</th>
                </tr>
                <tr>
                    <td>
                        <table border="1" style="border-collapse:collapse;width:100%">
                            <tr>
                                <th>child</th>
                                <th>nephew</th>
                            </tr>
                            <tr>
                                <td>
                                    <table border="1" style="border-collapse:collapse;width:100%">
                                        <tr>
                                            <th>string</th>
                                            <th>number</th>
                                            <th>grandchild</th>
                                            <th>date</th>
                                        </tr>
                                        <tr>
                                            <td>A</td>
                                            <td></td>
                                            <td></td>
                                            <td></td>
                                        </tr>
                                        <tr>
                                            <td>B</td>
                                            <td></td>
                                            <td></td>
                                            <td></td>
                                        </tr>
                                        <tr>
                                            <td>C</td>
                                            <td>1</td>
                                            <td>
                                                <table border="1" style="border-collapse:collapse;width:100%">
                                                    <tr>
                                                        <th>string</th>
                                                        <th>substring</th>
                                                        <th>number</th>
                                                    </tr>
                                                    <tr>
                                                        <td>DD</td>
                                                        <td>EE</td>
                                                        <td>33</td>
                                                    </tr>
                                                </table>
                                            </td>
                                            <td></td>
                                        </tr>
                                        <tr>
                                            <td></td>
                                            <td>2</td>
                                            <td></td>
                                            <td></td>
                                        </tr>
                                        <tr>
                                            <td>F</td>
                                            <td></td>
                                            <td></td>
                                            <td>2015-02-12</td>
                                        </tr>
                                    </table>
                                </td>
                                <td>
                                    <table border="1" style="border-collapse:collapse;width:100%">
                                        <tr>
                                            <th>string</th>
                                        </tr>
                                        <tr>
                                            <td>G</td>
                                        </tr>
                                    </table>
                                </td>
                            </tr>
                        </table>
                    </td>
                    <td>
                        <table border="1" style="border-collapse:collapse;width:100%">
                            <tr>
                                <th>niece</th>
                            </tr>
                            <tr>
                                <td>
                                    <table border="1" style="border-collapse:collapse;width:100%">
                                        <tr>
                                            <th>string</th>
                                        </tr>
                                        <tr>
                                            <td>H</td>
                                        </tr>
                                    </table>
                                </td>
                            </tr>
                        </table>
                    </td>
                </tr>
            </table>
        </td>
    </tr>
</table>
  • 0
    Я не знаю, что означает « вложенная таблица ». Пожалуйста, опубликуйте пример или два ввода и ожидаемый результат каждого.
  • 1
    добро пожаловать в stackoverflow. Это отличный ресурс, чтобы «помочь мне с моей проблемой», НО мы должны понимать вашу проблему как некоторый специфический код, который нужно исправить. Если вы «почти в состоянии получить то, что он хочет», то отредактируйте свой вопрос, включив в него. небольшая выборка входных данных, б. ваш ожидаемый результат от этих данных, c. код, который вы используете, d. любые подробности об используемой вами среде (java, саксонские парсеры и т. д., OR xsh, xmllint, xmlstarlet и т. д., т. е. текущий вывод и любые сообщения об ошибках. Используйте инструмент форматирования {} в левом верхнем углу окна редактирования текста, чтобы выделить код и данные для фмт.
Показать ещё 7 комментариев
Теги:
xslt
dom
xslt-1.0

1 ответ

1
Лучший ответ

Как я уже сказал в комментариях, это будет непросто. В принципе, вы хотите удалить любые дублированные узлы с одним и тем же путем (где путь вычисляется с использованием только имен узлов) и отображать результирующую иерархию.

Для этого требуется сделать проход предварительной обработки, чтобы назначить всем узлам их путь. Нам также необходимо предоставить каждому узлу свой родительский путь, чтобы его можно было назвать позже его новым родителем (который раньше мог быть его дядей или дядей или...).

На втором и последнем шаге мы будем применять группировку Muenchian к результату первого прохода, оставляя только отдельные узлы по пути.

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

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="node-by-path" match="node" use="@path" />
<xsl:key name="node-by-parent-path" match="node" use="@parent-path" />

<xsl:template match="/">
    <!-- first-pass -->
    <xsl:variable name="first-pass">
        <xsl:apply-templates select="*" mode="firstpass"/>
    </xsl:variable>
    <!-- output -->
    <ul>
        <xsl:apply-templates select="exsl:node-set($first-pass)/node[@parent-path='']" />
    </ul>
</xsl:template>

<xsl:template match="*" mode="firstpass">
    <xsl:variable name="parent-path">
        <xsl:for-each select="ancestor::*">
            <xsl:value-of select="concat('/', name())"/>
        </xsl:for-each>                 
    </xsl:variable> 
    <node name="{name()}" parent-path="{$parent-path}" path="{concat($parent-path, '/', name())}">
        <xsl:apply-templates select="*" mode="firstpass"/>
    </node>
</xsl:template>

<xsl:template match="node">
    <li>
        <xsl:value-of select="@name"/>
        <xsl:variable name="next" select="key('node-by-parent-path', @path)" />
        <xsl:if test="$next">
            <ul>
                <xsl:apply-templates select="$next[count(. | key('node-by-path', @path)[1]) = 1]"/>
            </ul>
        </xsl:if>
    </li>
</xsl:template> 

</xsl:stylesheet>

Тестовый ввод XML

<root>
   <parent>
      <child>
         <string>A</string>
         <string>B</string>
      </child>
      <child>
         <string>C</string>
         <number>1</number>
         <number>2</number>
         <grandchild>
            <string>DD</string>
            <substring>EE</substring>
            <number>33</number>
         </grandchild>
      </child>
   </parent>
   <parent>
      <child>
         <string>F</string>
         <date>2015-02-12</date>
      </child>
      <nephew>
         <string>G</string>
      </nephew>
   </parent>
   <uncle>
      <niece>
         <string>H</string>
      </niece>
   </uncle>
</root>

результат

<?xml version="1.0" encoding="UTF-8"?>
<ul>
   <li>root<ul>
         <li>parent<ul>
               <li>child<ul>
                     <li>string</li>
                     <li>number</li>
                     <li>grandchild<ul>
                           <li>string</li>
                           <li>substring</li>
                           <li>number</li>
                        </ul>
                     </li>
                     <li>date</li>
                  </ul>
               </li>
               <li>nephew<ul>
                     <li>string</li>
                  </ul>
               </li>
            </ul>
         </li>
         <li>uncle<ul>
               <li>niece<ul>
                     <li>string</li>
                  </ul>
               </li>
            </ul>
         </li>
      </ul>
   </li>
</ul>

Вынесено

Изображение 174551

Ещё вопросы

Сообщество Overcoder
Наверх
Меню