Используйте XSL для преобразования списка XML в дерево XHTML - PullRequest
0 голосов
/ 04 июня 2010

Мне нужно взять этот XML ...

<root>
   <item id=’1’ parent_id=’0’>ONE</item>
   <item id=’2’ parent_id=’1’>TWO</item>
   <item id=’3’ parent_id=’1’>THREE</item>
   <item id=’4’ parent_id=’2’>FOUR</item>
   <item id=’5’ parent_id=’0’>FIVE</item>
</root>

И произведите этот xhtml…

<div class=’parent’>ONE</div>
<div class=’child’>
   <div class=’parent’>TWO</div>
   <div class=’child’>
      <div class=’parent’>FOUR</div>
   </div>
   <div class=’parent’>THREE</div>
</div>
<div class=’parent’>FIVE</div>

Я понимаю, как собрать дочерние узлы и поместить их под родительский, но я не могу понять, как потом пропустить, считая их родителями, если я уже использовал их как детей.

Ответы [ 2 ]

0 голосов
/ 06 декабря 2010

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

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:key name="kItemById" match="item" use="@id"/>
    <xsl:key name="kItemByParentId" match="item" use="@parent_id"/>
    <xsl:template match="root">
        <xsl:apply-templates select="item[not(key('kItemById',@parent_id))]"/>
    </xsl:template>
    <xsl:template match="item">
        <xsl:variable name="vChild" select="key('kItemByParentId',@id)"/>
        <div class="parent">
            <xsl:value-of select="."/>
        </div>
        <xsl:if test="$vChild">
            <div class="child">
                <xsl:apply-templates select="$vChild"/>
            </div>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

Выход:

<div class="parent">ONE</div>
<div class="child">
    <div class="parent">TWO</div>
    <div class="child">
        <div class="parent">FOUR</div>
    </div>
    <div class="parent">THREE</div>
</div>
<div class="parent">FIVE</div>

Примечание : ключи для перекрестных ссылок.

0 голосов
/ 04 июня 2010

Проверено следующее, что, похоже, работает

Примените все элементы в корне с parent_id = 0, затем рекурсивно итерируйте для любых потомков.

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

<xsl:template match="/">
  <xsl:apply-templates select="root/item[@parent_id='0']"/>
</xsl:template>


<xsl:template match="item">
  <div class="parent"><xsl:value-of select="."/></div>
  <xsl:if test="count(../item[@parent_id=current()/@id]) != 0">
    <div class="child">
      <xsl:apply-templates select="../item[@parent_id=current()/@id]"/>
    </div>
  </xsl:if>
</xsl:template>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...