2010-03-25 60 views
2

首先,这里是情况。我正在使用一个公会托管站点,该站点允许您将URL输入到XSL文件和另一个XML输入。当你想要的所有XML都包含在一个文件中时,一切顺利。制作XSL样式表使用分页XML工作

我的问题是这样的Game Roster XML这是分页...看看接近该文件的底部,你会发现一个<page_links>节,其中包含写在HTML链接到/xml?page=2等寻呼机由于公会托管网站设置只处理一个XML页面,我无法访问其他XML页面。

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

  1. 成立,结合了所有的XML页面转换成一个PHP页面,然后输出文件。然后,我可以在公会托管站点XSL处理器中使用此URL。
  2. 以某种方式组合XSL样式表中的所有XML文件。我在SO上找到了this question(我并不是很了解它,因为我不知道document($pXml1)在做什么),但我认为它不会起作用,因为页数会变化。我认为这可能是通过加载下一页,直到<members_to>值等于<members_total>

还有其他想法吗?我不知道XSL或PHP,所以任何帮助与代码示例将不胜感激。


更新:我试着上面的方法2,这里是我遇到麻烦的XSLT片段。代码的第一页显示没有问题,但我遇到了这个xsl:if,或者可能是document()声明的问题。

更新#2:将文档更改为使用字符串& concat函数,但它仍然不起作用。

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

更新#3:感谢您的伟大的开始拉克兰!但我试图用HTML输出。我有一个“addrow”模板和一个主模板,我不知道如何将它与您提供的XSL整合在一起。以下是我有:

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

更新#4:我仍然坚持。这个XSL不会加载任何额外的XML页面。我曾尝试将SuperGroup[position()]添加到SuperGroupmembers模板中,但未成功。我也尝试将代码重新格式化为类似this post的东西,但仍然没有运气。我会很感激任何其他的想法。

+0

我敢肯定你可以用XSLT递归地做到这一点。该例中的'document'函数调用'pxml1'变量中指定的uri。 – 2010-03-25 20:49:50

+0

@Jweede:谢谢!这是我正在尝试的方法,但是我在上面的代码片段中遇到了问题。 – Mottie 2010-03-25 23:08:04

回答

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:属性。

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

哇,谢谢你!它比我从其他例子中拼凑出来的要简单得多。我已经更新了关于如何将XSL与我已经完成的工作集成的问题。正如你在我的代码中看到的那样,我正在调用我在第二次更新中包含的“morepages”模板。感谢你目前的帮助! – Mottie 2010-03-26 06:04:46

+0

再次感谢!我不得不将''中的选择改为“SuperGroup/members/members_node”以获得正确的输出,但它仍然只显示第一页。最初的页面实际上是页面“1”,但我不确定这是否是问题。 – Mottie 2010-03-26 07:16:37

+0

糟糕,没关系你是对的,它确实从第0页开始。 – Mottie 2010-03-26 07:26:40