XSLT密钥,嵌套或多个

时间:2014-06-04 23:24:16

标签: xml xslt muenchian-grouping

这是我的xml(大大简化和缩短,在我的真实交易中有100个'电影'元素)

<mediaList>
    <movie>
        <title>Hugo</title>
        <genreWrap>
            <genre>Children and Family</genre>
            <subGenre>Book Characters</subGenre>
            <subGenre>Family Adventures</subGenre>
            <subGenre>Family Dramas</subGenre>
        </genreWrap>
        <genreWrap>
            <genre>Drama</genre>
            <subGenre>Family Dramas</subGenre>
        </genreWrap>
    </movie>
    <movie>
        <title>Vanishing Point</title>
        <genreWrap>
            <genre>Action and Adventure</genre>
            <subGenre>Action Classics</subGenre>
            <subGenre>Action Thrillers</subGenre>
        </genreWrap>
        <genreWrap>
            <genre>Thrillers</genre>
            <subGenre>Action Thrillers</subGenre>
        </genreWrap>
    </movie>
    <movie>
        <title>White Lightning</title>
        <genreWrap>
            <genre>Action and Adventure</genre>
            <subGenre>Crime Action</subGenre>
        </genreWrap>
        <genreWrap>
            <genre>Sports and Fitness</genre>
            <subGenre>Motorsports</subGenre>
            <subSubGenre>Auto Racing</subSubGenre>
        </genreWrap>
    </movie>
    <movie>
        <title>Kon-Tiki</title>
        <genreWrap>
            <genre>Action and Adventure</genre>
            <subGenre>Adventures</subGenre>
            <subGenre>Foreign Action and Adventure</subGenre>
        </genreWrap>
        <genreWrap>
            <genre>Drama</genre>
            <subGenre>Dramas Based on Real Life</subGenre>
            <subGenre>Family Dramas</subGenre>
            <subGenre>Period Pieces</subGenre>
            <subSubGenre>20th Century Period Pieces</subSubGenre>
        </genreWrap>
        <genreWrap>
            <genre>Foreign</genre>
            <subGenre>Foreign Action and Adventure</subGenre>
            <subGenre>Foreign Dramas</subGenre>
            <subGenre>Foreign Languages</subGenre>
            <subGenre>Foreign Regions</subGenre>
            <subSubGenre>Norwegian Language</subSubGenre>
            <subSubGenre>Scandinavia</subSubGenre>
        </genreWrap>
    </movie>
    <movie>
        <title>Mummy, The</title>
        <director>Stephen Sommers</director>
        <genreWrap>
            <genre>Action and Adventure</genre>
            <subGenre>Action Thrillers</subGenre>
            <subGenre>Adventures</subGenre>
        </genreWrap>
        <genreWrap>
            <genre>Horror</genre>
            <subGenre>Monsters</subGenre>
        </genreWrap>
        <genreWrap>
            <genre>Thrillers</genre>
            <subGenre>Action Thrillers</subGenre>
            <subGenre>Supernatural Thrillers</subGenre>
        </genreWrap>
    </movie>
</mediaList>

我删除了除了这个例子中的标题和流派之外的所有内容,因为这是绊倒我的部分。我正在尝试将它们放入一个好的格式,以用作可导航的工具栏

类似的东西:

                <ul>
                    <li>Action and Adventures
                        <ul>
                            <li>
                               Action Classics
                            </li>
                             <li>
                               Action Thrillers
                             </li>
                             <li>
                               Adventures
                             </li>
                             <li>
                               Crime Action
                             </li>
                             <li>
                               Foreign Action and Adventure
                             </li>
                        </ul>
                     </li>
                    <li>Children and Family
                        <ul>
                            <li>
                               Book Characters
                            </li>
                             <li>
                               Family Adventures 
                             </li>
                             <li>
                               Family Dramas
                             </li>
                        </ul>
                     </li>
                 </ul>

等。每个“流派”得到一个<li>,并且它的所有subGenre被放置在它下面的新<ul>中,如果有一个subSubGenre(就像Kon-Tiki那样)它只会扩展一个级别。

我一直在读密钥和Muenchian Grouping -

我的XSL文件顶部有这个键

<xsl:key name="movieByGenre" match="genre" use="."/>

并且理解它通过我给他们的名字索引了流派元素,然后使用

select="movie//*[generate-id() = generate-id(key('movieByGenre', .)[1])]"

<xsl:for-each><xsl:apply-templates>我可以为每种类型做任何我喜欢的事情。这很好。

这让subGenres出现在每个杀死我的地方。

我有这个,这是错误的,但我无法弄清楚如何使它正确。

<?xml version="1.0" encoding="UTF-8"?>
        <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
            <xsl:output method="html" indent="yes"/>

        <xsl:key name="keyGenre" match="genre" use="."/>    
        <xsl:key name="keySubGenre" match="subGenre" use="../genre"/> 

        <xsl:template match="mediaList">
            <ul>
      <xsl:for-each select="movie//*[generate-id() = generate-id(key('keyGenre', .)[1])]">  
                      <xsl:sort order="ascending"/>
                            <li>
                   <xsl:value-of select="."/>
                 <ul>
                    <li>
<xsl:for-each select="movie//*[generate-id() = generate-id(key('keySubGenre', .)[1])]">
                                <xsl:sort order="ascending"/>
    <xsl:value-of select="."/>
</li>
    </xsl:for-each>
</ul>
</li>
                </xsl:for-each>
     </ul>
    </xsl:template>
          </xsl:stylesheet>

如果您能解释它是如何工作的,我很乐意接受xsl 2.0解决方案!但我对1.0有更坚定的把握。

1 个答案:

答案 0 :(得分:1)

我不确定你想如何处理subSubGenres - 它们似乎没有嵌套在subGenres下面。对于前两个级别,请尝试:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:key name="genre" match="genre" use="."/>  
<xsl:key name="subGenre-by-genre" match="subGenre" use="../genre"/> 
<xsl:key name="subGenre" match="subGenre" use="concat(../genre, '|', .)"/> 

<xsl:template match="/">
    <ul>
        <!-- for each distinct genre ... -->
        <xsl:for-each select="mediaList/movie/genreWrap/genre[generate-id()=generate-id(key('genre', .)[1])]">  
            <xsl:sort/>
            <li>
                <xsl:variable name="genre" select="." />
                <xsl:value-of select="$genre"/>
                <ul>
                    <!-- ... get the list of the relevant sub-genres ... -->
                    <xsl:variable name="mySubGenres" select="key('subGenre-by-genre', .)" />
                    <!-- ... and de-dupe it -->
                    <xsl:for-each select="$mySubGenres[generate-id()=generate-id(key('subGenre', concat($genre, '|', .))[1])]">
                        <xsl:sort/>
                        <li><xsl:value-of select="."/></li>
                    </xsl:for-each>
                </ul>
            </li>
        </xsl:for-each>
    </ul>
</xsl:template>

</xsl:stylesheet>