使XSL样式表适用于分页XML

时间:2010-03-25 17:27:20

标签: xml xslt

首先,这是情况。我正在使用一个公会托管网站,它允许您输入XSL文件的URL和XML的另一个输入。当你想要的所有XML都包含在一个文件中时,一切都很好。

我的问题是这个Game Roster XML分页...看看文件底部附近你会发现一个<page_links>部分,其中包含一个用HTML编写的寻呼机,其中包含{{1}的链接因为公会托管站点设置为只处理一个XML页面,所以我无法访问其他XML页面。

所以,我只能想到两个解决方案,但我不知道如何开始

  1. 设置一个将所有XML页面合并为一个的php页面,然后输出该文件。然后,我可以在公会托管网站XSL处理器中使用此URL。
  2. 以某种方式组合XSL样式表中的所有XML文件。我在SO上发现了this question(我真的不明白它,因为我不知道/xml?page=2正在做什么),但我不认为它会起作用,因为页数会变数。我认为这可以通过加载下一页来实现,直到document($pXml1)值等于<members_to>
  3. 还有其他想法吗?我不太了解XSL或php,所以对代码示例的任何帮助都将非常感激。


    更新:我正在尝试上面的方法2,这里是一个XSLT的片段,我遇到了麻烦。代码的第一页显示没有问题,但是我遇到了这个<members_total>的问题,或者可能是xsl:if语句。

    更新#2:更改文档以使用字符串&amp; concat函数,但它仍然无效。

    document()

    更新#3:感谢Lachlan的伟大开端!但我试图用HTML输出。我有一个“addrow”模板和一个主模板,我不知道如何与你提供的XSL集成在一起。这就是我所拥有的:

    <xsl:template name="morepages">
    
     <xsl:param name="page">1</xsl:param>
     <xsl:param name="url">
      <xsl:value-of select="concat(SuperGroup/profule_url,'/xml?page=')"/>
     </xsl:param> 
    
     <xsl:if test="document(string(concat($url,$page)))/SuperGroup/members_to &lt; document(string(concat($url,$page)))/SuperGroup/members_total">
       <xsl:for-each select="document(string(concat($url,$page + 1)))/SuperGroup/members/members_node">
       <xsl:call-template name="addrow" />
      </xsl:for-each>
      <!-- Increment page index-->
      <xsl:call-template name="morepages">
       <xsl:with-param name="page" select="$page + 1"/>
      </xsl:call-template>
     </xsl:if>
    </xsl:template>
    

    更新#4:我仍然被卡住了。此XSL不会加载任何其他XML页面。我尝试将 <!-- add a member row --> <xsl:template name="addrow"> <tr> <td class="coName"> <xsl:element name="a"> <xsl:attribute name="target"> <xsl:text>_blank</xsl:text> </xsl:attribute> <xsl:attribute name="href"> <xsl:value-of select="profile_url"/> </xsl:attribute> <xsl:value-of select="pcname"/> </xsl:element> </td> <xsl:element name="td"> <xsl:attribute name="class"> <xsl:text>coAccount</xsl:text> </xsl:attribute> <xsl:value-of select="pcaccount"/> </xsl:element> <td class="coLevel"><xsl:value-of select="ilevel"/></td> <xsl:if test="irank!=''"> <td class="coRank"> <xsl:value-of select="irank"/> </td> </xsl:if> <td class="coStatus"><xsl:value-of select="pcmapname"/></td> </tr> </xsl:template> <!-- main template --> <xsl:template match="/"> <div class="coGuildName"> <xsl:element name="img"> <xsl:attribute name="src"> <xsl:text>http://champions-online.com</xsl:text> <xsl:value-of select="SuperGroup/guild_name_img"/> </xsl:attribute> </xsl:element> </div> <table width="100%" cellspacing="0" cellpadding="0" id="coRoster" align="center"> <thead> <tr class="ForumCategoryHeader"> <th class="coName">Name</th> <th class="coAccount">Account</th> <th class="coLevel">Level</th> <xsl:if test="SuperGroup/ranks!=''"> <th class="coRank">Rank</th> </xsl:if> <th class="coStatus">Status</th> </tr> </thead> <tbody> <xsl:for-each select="SuperGroup/members/members_node"> <xsl:call-template name="addrow" /> </xsl:for-each> <!-- if less then total members shown, load next XML page --> <xsl:if test="SuperGroup/members_to &lt; SuperGroup/members_total"> <xsl:call-template name="morepages"/> </xsl:if> </tbody> </table> </xsl:template> 添加到SuperGroup[position()]SuperGroup模板但未成功。我也尝试将代码重新格式化为类似于this post的东西,但仍然没有运气。我会很感激任何其他想法。

1 个答案:

答案 0 :(得分:4)

此样式表将页面“0”作为输入文档。在members模板中,我们会检查更多网页,并根据需要应用“下一页”SuperGroup模板。最后一个模板计算页码并从下一个文档中提取members元素。

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

    <xsl:output method="xml" indent="yes"/>

    <xsl:variable name="server">
        <xsl:text>http://champions-online.com/super_groups/Phoenix%20Force/xml</xsl:text>
    </xsl:variable>

    <xsl:template match="SuperGroup">
        <members>
            <xsl:apply-templates select="members"/>
        </members>
    </xsl:template>

    <xsl:template match="members">
        <xsl:copy-of select="members_node" />
        <xsl:if test="/SuperGroup/members_total != /SuperGroup/members_to">
            <xsl:apply-templates select="/SuperGroup" mode="next-page" />
        </xsl:if>
    </xsl:template>

    <xsl:template match="SuperGroup" mode="next-page">
        <xsl:variable name="this" select="(members_from - 1) div 20" />
        <xsl:variable name="page" select="1 + $this" />
        <xsl:variable name="url" select="concat($server,'?page=',$page)" />

        <xsl:apply-templates select="document($url)/SuperGroup/members" />
    </xsl:template>

</xsl:stylesheet>

将其与示例3中的主样式表合并,我们得到以下结果。

我做了一些一般的改进:使用文字结果元素而不是xsl:元素,因为名称不是动态的;使用属性值模板而不是xsl:attribute。

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

    <xsl:output method="html"/>

    <xsl:variable name="server">
        <xsl:text>http://champions-online.com/super_groups/Phoenix%20Force/xml</xsl:text>
    </xsl:variable>

    <xsl:template match="members_node">
        <tr>
            <td class="coName">
                <a target="_blank" href="{profile_url}">
                    <xsl:value-of select="pcname"/>
                </a>
            </td>
            <td class="coAccount">
                <xsl:value-of select="pcaccount"/>
            </td>
            <td class="coLevel">
                <xsl:value-of select="ilevel"/>
            </td>
            <xsl:if test="irank!=''">
                <td class="coRank">
                    <xsl:value-of select="irank"/>
                </td>
            </xsl:if>
            <td class="coStatus">
                <xsl:value-of select="pcmapname"/>
            </td>
        </tr>
    </xsl:template>

    <xsl:template match="/">
        <div class="coGuildName">
            <img src="http://champions-online.com{SuperGroup/guild_name_img}"/>
        </div>
        <table width="100%" cellspacing="0" cellpadding="0" id="coRoster" align="center">
            <thead>
                <tr class="ForumCategoryHeader">
                    <th class="coName">Name</th>
                    <th class="coAccount">Account</th>
                    <th class="coLevel">Level</th>
                    <xsl:if test="SuperGroup/ranks!=''">
                        <th class="coRank">Rank</th>
                    </xsl:if>
                    <th class="coStatus">Status</th>
                </tr>
            </thead>
            <tbody>
                <xsl:apply-templates select="SuperGroup/members" />
            </tbody>
        </table>
    </xsl:template>

    <xsl:template match="members">
        <xsl:apply-templates select="members_node" />
        <xsl:if test="/SuperGroup/members_total != /SuperGroup/members_to">
            <xsl:apply-templates select="/SuperGroup" mode="next-page" />
        </xsl:if>
    </xsl:template>

    <xsl:template match="SuperGroup" mode="next-page">
        <xsl:variable name="this" select="(members_from - 1) div 20" />
        <xsl:variable name="page" select="1 + $this" />
        <xsl:variable name="url" select="concat($server,'?page=',$page)" />
        <xsl:apply-templates select="document($url)/SuperGroup/members" />
    </xsl:template>

</xsl:stylesheet>