So I have this data for a client ( see below ) and I want to create a bulleted list that can have any number of tiers. I also want it to be dynamic in the aspect that items can be listed more than once. The CMS is s开发者_JAVA百科et up so a TAG will claim its parents. Wherever a TAG claims its parents, its children should replicate beneath. Not sure how to tackle this with XSLT, but a simple example should end up looking something like this..
<ul>
<li>Missions</li>
<li>
<ul>
<li>Kampala, Uganda</li>
<li>Lima, Peru</li>
</ul>
</li>
</ul>
If Kampala, Uganda
also claimed something else as a parent, it would appear multiple times. If Kampala, Uganda
had other TAGS that claimed it as a parent, these children would cascade beneath Kampala, Uganda
in each instance.
<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">
<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="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>
I don't think you need the children of an item to be wrapped in another <li>
.
This transformation (quite similar to that of @Alejandro, but simpler, shorter and not requiring any parameters at all):
<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>
when applied on the referred to source XML document:
<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>
produces the wanted, correct result:
<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>
Do note: This solution works correctly when a tag
has more than one parent.
Explanation:
- The key:
<xsl:key name="kChildren" match="tag"
use="string(../parents/item/@handle)"/>
produces all the "children" from the string value of the handle
attribute of the first (only) item
child of their parents
sibling. This covers also such tag
elements that don't have any parents
sibling (in which case the key value is the empty string).
.2. A second key with the same name:
<xsl:key name="kChildren" match="tag"
use="../parents/item/@handle"/>
matches a tag
by the value of any handle
attribute of the item
child of their parents
sibling. This makes it possible to have the tag
listed for all "parents", not only for the first.
As we see here, the ability to have multiple keys with the same name is a very powerful and useful feature.
Edit: Multiple parents relationship added.
This stylesheet:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="kTagByParent"
match="tag"
use="../parents/item/@handle"/>
<xsl:template match="/" name="makeUL">
<xsl:param name="pChilds"
select="*/*/entry[not(parents/item/@handle!='')]/tag"/>
<ul>
<xsl:apply-templates select="$pChilds"/>
</ul>
</xsl:template>
<xsl:template match="tag">
<xsl:variable name="vChilds" select="key('kTagByParent',@handle)"/>
<li>
<xsl:value-of select="@handle"/>
</li>
<xsl:if test="$vChilds">
<li>
<xsl:call-template name="makeUL">
<xsl:with-param name="pChilds" select="$vChilds"/>
</xsl:call-template>
</li>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Output:
<ul>
<li>home</li>
<li>israel</li>
<li>meetings</li>
<li>
<ul>
<li>bible-studies</li>
<li>worship</li>
</ul>
</li>
<li>ministry</li>
<li>
<ul>
<li>childrens-ministry</li>
<li>college-and-career-ministry</li>
<li>high-school-ministry</li>
<li>junior-high-ministry</li>
<li>men-s-ministry</li>
<li>womens-ministry</li>
</ul>
</li>
<li>missions</li>
<li>
<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</li>
<li>
<ul>
<li>fanafo-christian-fellowship</li>
<li>natanara-christian-fellowship</li>
</ul>
</li>
<li>villahermosa-mexico</li>
</ul>
</li>
</ul>
With the new provided input at http://see.weareinto.com/525q , output:
<ul>
<li>home</li>
<li>israel</li>
<li>meetings</li>
<li>
<ul>
<li>bible-studies</li>
<li>worship</li>
</ul></li>
<li>ministry</li>
<li>
<ul>
<li>childrens-ministry</li>
<li>college-and-career-ministry</li>
<li>high-school-ministry</li>
<li>junior-high-ministry</li>
<li>
<ul>
<li>the-islands-of-vanuatu</li>
<li>
<ul>
<li>fanafo-christian-fellowship</li>
<li>natanara-christian-fellowship</li>
</ul>
</li>
</ul>
</li>
<li>men-s-ministry</li>
<li>womens-ministry</li>
</ul></li>
<li>missions</li>
<li>
<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</li>
<li>
<ul>
<li>fanafo-christian-fellowship</li>
<li>natanara-christian-fellowship</li>
</ul>
</li>
<li>villahermosa-mexico</li>
</ul>
</li>
</ul>
Note: Node set key value, new expression to get the roots.
精彩评论