2017-01-02 2 views
0

Позвольте мне начать с примера и поработать над вопросом. Вот очень простой и чистый XML данные:Обработка XSLT-вывода с использованием XSLT в том же документе, плоские данные для узлов дерева

<?xml version="1.0" encoding="UTF-8"?> 
<?xml-stylesheet type="text/xsl" href="flatdata.xsl"?> 

<db> 
<item> 
    <parent></parent> 
    <id>1</id> 
    <title>lorem ipsum</title> 
</item> 

<item> 
    <parent></parent> 
    <id>2</id> 
    <title>dolor sit amet</title> 
</item> 

<item> 
    <parent>1</parent> 
    <id>3</id> 
    <title>consectetur adipiscing elit.</title> 
</item> 

<item> 
    <parent>1</parent> 
    <id>4</id> 
    <title>Nunc varius tempus sem et fringilla</title> 
</item> 

<item> 
    <parent>2</parent> 
    <id>5</id> 
    <title>Aenean egestas</title> 
</item> 

<item> 
    <parent>2</parent> 
    <id>6</id> 
    <title>turpis vel placerat suscipit</title> 
</item> 

<item> 
    <parent>5</parent> 
    <id>7</id> 
    <title>ligula nulla consequat justo</title> 
</item> 
</db> 

Это плоская база данных элементов со структурой дерева, скрывающейся внутри, данный <parent> отношений.

XSLT, которая преобразует это вложенная структуру, чтобы выявить древовидное Взаимоотношение item с довольно прост (я сделал свою домашнюю работу):

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

<xsl:template match="/"> 
    <html> 
     <body> 
      <xsl:apply-templates select="db"/> 
     </body> 
    </html> 
</xsl:template> 

<xsl:template match="db"> 
    <ul> 
     <xsl:apply-templates select="item[parent='']"/> 
    </ul> 
</xsl:template> 

<xsl:template match="item"> 
    <xsl:variable name="vId" select="id"/> 
    <xsl:variable name="vChildren" select="../item[parent=$vId]"/> 
    <li> 
     <b><xsl:value-of select="concat(id,': ')"/></b> <xsl:value-of select="title"/> 
     <xsl:if test="$vChildren"> 
      <ul> 
       <xsl:apply-templates select="$vChildren"/> 
      </ul> 
     </xsl:if> 
    </li> 
</xsl:template> 
</xsl:stylesheet> 

, который дает следующий результат:

<ul> 
<li> 
    <b>1: </b>lorem ipsum 
    <ul> 
     <li><b>3: </b>consectetur adipiscing elit.</li> 
     <li><b>4: </b>Nunc varius tempus sem et fringilla</li> 
    </ul> 
</li> 
<li> 
    <b>2: </b>dolor sit amet 
    <ul> 
     <li> 
      <b>5: </b>Aenean egestas 
      <ul> 
       <li> 
        <b>7: </b>ligula nulla consequat justo 
       </li> 
      </ul> 
     </li> 
     <li> 
      <b>6: </b>turpis vel placerat suscipit 
     </li> 
    </ul> 
</li> 
</ul> 

Ситуация в том, что эта вложенная (древовидная) структура удобнее обрабатывать с помощью XSLT для моих целей. Я могу использовать простой XPath и т. Д., Чтобы проанализировать, сколько item имеет количество потомков и т. Д. XML-данные, которые я получаю от источника, являются плоскими, я ничего не могу с этим поделать.

Итак, как один

  1. идентифицировать и создать структуру дерева некоторый формат (не должен быть HTML, конечно, было бы неизбежно некоторый внутренний формат, или набор узлов?) И
  2. обрабатывать это дерево с помощью XSLT, на той же таблице стилей?

Я пытаюсь отобразить результаты базы данных flatdata через XSLT в современных браузерах, поэтому я предполагаю, что это означает, что я застрял с 1.0 (справа?).

ответ

0

Вы можете создать глобальную переменную <xsl:variable name="rtf"><xsl:apply-templates/></xsl:variable> в любой версии XSLT, однако в XSLT 1.0 вы бы тогда фрагмент результирующего дерева, которое вы можете только выход с xsl:copy-of но не перемещаться с помощью XPath, если не использовать функцию расширения как exsl:node-set в <xsl:variable name="ns" select="exsl:node-set($rtf)" xmlns:exsl="http://exslt.org/common"/>. Однако там, где внутри браузеров возникает проблема, поскольку IE и Edge не поддерживают exsl:node-set, только проприетарный msxsl:node-set в другом пространстве имен (xmlns:msxsl="urn:schemas-microsoft-com:xslt"). Используя функцию расширения, можно обмануть IE в распознавание exsl:node-set, но этот подход не работает в Edge. Таким образом, в кросс-браузерном XSLT 1.0 вы можете использовать xsl:choose/xsl:when/xsl:if для тестирования, например. function-available('exsl:node-set') Эта функция поддерживается, чтобы затем преобразовать фрагмент дерева результатов в набор узлов.

В качестве альтернативы вы можете заглянуть в Saxon-CE или Saxon-JS, в результате чего XSLT 2.0 появится в браузерах, где ограничений на фрагменты дерева результатов не существует.

Смежные вопросы