Попытка создать динамический каскадный список - PullRequest
1 голос
/ 06 марта 2011

Итак, у меня есть эти данные для клиента (см. Ниже), и я хочу создать маркированный список, который может иметь любое количество уровней.Я также хочу, чтобы это было динамичным в том смысле, что элементы могут быть перечислены более одного раза.CMS настроена так, что TAG будет требовать своих родителей.Везде, где TAG заявляет о своих родителях, его дети должны копироваться ниже.Не уверен, как справиться с этим с помощью XSLT, но простой пример должен выглядеть примерно так:

<ul>
    <li>Missions</li>
    <li>
        <ul>
            <li>Kampala, Uganda</li>
            <li>Lima, Peru</li>
        </ul>
    </li>
</ul>

Если бы Kampala, Uganda также требовал что-то еще в качестве родителя, это появилось бы несколько раз.Если бы у Kampala, Uganda были другие теги, которые утверждали, что он является родителем, эти дети будут каскадно ниже Kampala, Uganda в каждом случае.

<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>

Ответы [ 2 ]

1 голос
/ 06 марта 2011

Не думаю, что вам нужно, чтобы дети одного элемента были обернуты в другой <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 более одного родителя.

Объяснение

  1. Ключ:

<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 для всех «родителей», а не только для первых.

Как мы видим здесь, возможность иметь несколько ключей с одинаковым именем является очень мощной и полезной функцией.

1 голос
/ 06 марта 2011

Редактировать : добавлены отношения с несколькими родителями.

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

<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>

Выход:

<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>

С новым предоставленным входом на http://see.weareinto.com/525q, выход:

<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>

Примечание : узел задает значение ключа, новое выражение для получения корней.

...