Не думаю, что вам нужно, чтобы дети одного элемента были обернуты в другой <li>
.
Это преобразование (очень похоже на преобразование @Alejandro, но проще, короче и вообще не требует каких-либо параметров):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:key name="kChildren" match="tag"
use="string(../parents/item/@handle)"/>
<xsl:key name="kChildren" match="tag"
use="../parents/item/@handle"/>
<xsl:template match="/" name="buildChildrenList">
<xsl:variable name="vChildren" select=
"key('kChildren', string(@handle))"/>
<xsl:if test="$vChildren">
<ul>
<xsl:apply-templates select="$vChildren"/>
</ul>
</xsl:if>
</xsl:template>
<xsl:template match="tag">
<li>
<xsl:value-of select="."/>
<xsl:call-template name="buildChildrenList"/>
</li>
</xsl:template>
</xsl:stylesheet>
при применении к указанному исходному документу XML:
<data>
<tags>
<section id="3" handle="tags">Tags</section>
<entry id="72">
<parents>
<item handle="meetings">Meetings</item>
</parents>
<tag handle="bible-studies">Bible studies</tag>
</entry>
<entry id="51">
<parents>
<item handle="missions">Missions</item>
</parents>
<tag handle="brazil">Brazil</tag>
</entry>
<entry id="31">
<parents>
<item handle="ministry">Ministry</item>
</parents>
<tag handle="childrens-ministry">Children's ministry</tag>
</entry>
<entry id="28">
<parents>
<item handle="ministry">Ministry</item>
</parents>
<tag handle="college-and-career-ministry">College and Career ministry</tag>
</entry>
<entry id="56">
<parents>
<item handle="the-islands-of-vanuatu">The Islands of Vanuatu</item>
</parents>
<tag handle="fanafo-christian-fellowship">Fanafo Christian Fellowship</tag>
</entry>
<entry id="29">
<parents>
<item handle="ministry">Ministry</item>
</parents>
<tag handle="high-school-ministry">High School ministry</tag>
</entry>
<entry id="48">
<parents>
<item handle="missions">Missions</item>
</parents>
<tag handle="holsbybrunn-sweden">Holsbybrunn, Sweden</tag>
</entry>
<entry id="22">
<tag handle="home">Home</tag>
</entry>
<entry id="19">
<tag handle="israel">Israel</tag>
</entry>
<entry id="30">
<parents>
<item handle="ministry">Ministry</item>
</parents>
<tag handle="junior-high-ministry">Junior High ministry</tag>
</entry>
<entry id="47">
<parents>
<item handle="missions">Missions</item>
</parents>
<tag handle="kampala-uganda">Kampala, Uganda</tag>
</entry>
<entry id="49">
<parents>
<item handle="missions">Missions</item>
</parents>
<tag handle="lima-peru">Lima, Peru</tag>
</entry>
<entry id="64">
<parents>
<item handle="" />
</parents>
<tag handle="meetings">Meetings</tag>
</entry>
<entry id="32">
<parents>
<item handle="ministry">Ministry</item>
</parents>
<tag handle="men-s-ministry">Men’s ministry</tag>
</entry>
<entry id="44">
<parents>
<item handle="" />
</parents>
<tag handle="ministry">Ministry</tag>
</entry>
<entry id="33">
<parents>
<item handle="" />
</parents>
<tag handle="missions">Missions</tag>
</entry>
<entry id="54">
<parents>
<item handle="the-islands-of-vanuatu">The Islands of Vanuatu</item>
</parents>
<tag handle="natanara-christian-fellowship">Natanara Christian Fellowship</tag>
</entry>
<entry id="50">
<parents>
<item handle="missions">Missions</item>
</parents>
<tag handle="ouagadougou-burkina-faso">Ouagadougou, Burkina Faso</tag>
</entry>
<entry id="46">
<parents>
<item handle="junior-high-ministry">Junior High ministry</item>
<item handle="missions">Missions</item>
</parents>
<tag handle="the-islands-of-vanuatu">The Islands of Vanuatu</tag>
</entry>
<entry id="77">
<parents>
<item handle="missions">Missions</item>
</parents>
<tag handle="villahermosa-mexico">Villahermosa, Mexico</tag>
</entry>
<entry id="27">
<parents>
<item handle="ministry">Ministry</item>
</parents>
<tag handle="womens-ministry">Women's ministry</tag>
</entry>
<entry id="73">
<parents>
<item handle="meetings">Meetings</item>
</parents>
<tag handle="worship">Worship</tag>
</entry>
</tags>
</data>
дает желаемый, правильный результат:
<ul>
<li>Home</li>
<li>Israel</li>
<li>Meetings
<ul>
<li>Bible studies</li>
<li>Worship</li>
</ul></li>
<li>Ministry
<ul>
<li>Children's ministry</li>
<li>College and Career ministry</li>
<li>High School ministry</li>
<li>Junior High ministry
<ul>
<li>The Islands of Vanuatu
<ul>
<li>Fanafo Christian Fellowship</li>
<li>Natanara Christian Fellowship</li>
</ul></li>
</ul></li>
<li>Men’s ministry</li>
<li>Women's ministry</li>
</ul></li>
<li>Missions
<ul>
<li>Brazil</li>
<li>Holsbybrunn, Sweden</li>
<li>Kampala, Uganda</li>
<li>Lima, Peru</li>
<li>Ouagadougou, Burkina Faso</li>
<li>The Islands of Vanuatu
<ul>
<li>Fanafo Christian Fellowship</li>
<li>Natanara Christian Fellowship</li>
</ul></li>
<li>Villahermosa, Mexico</li>
</ul></li>
</ul>
Примечание : Это решение работает правильно, если у tag
более одного родителя.
Объяснение
- Ключ:
<xsl:key name="kChildren" match="tag"
use="string(../parents/item/@handle)"/>
производит все «потомки» из строкового значения атрибута handle
первого (только) item
потомка их брата parents
. Это также относится к таким элементам tag
, которые не имеют элемента parents
(в этом случае значение ключа является пустой строкой).
0,2. Второй ключ с тем же именем:
<xsl:key name="kChildren" match="tag"
use="../parents/item/@handle"/>
соответствует tag
по значению любому атрибуту handle
дочернего элемента item
их брата parents
. Это позволяет указывать tag
для всех «родителей», а не только для первых.
Как мы видим здесь, возможность иметь несколько ключей с одинаковым именем является очень мощной и полезной функцией.