Заставить таблицу стилей XSL работать с постраничным XML - PullRequest
2 голосов
/ 25 марта 2010

Прежде всего, вот ситуация. Я использую сайт хостинга гильдии, который позволяет вам вводить URL в файл XSL и другой ввод для XML. Все хорошо, когда весь нужный вам XML содержится в одном файле.

Моя проблема заключается в следующем: Список игр XML , который разбит на страницы ... посмотрите в конец файла, и вы найдете раздел <page_links>, содержащий пейджер, написанный на HTML со ссылками на /xml?page=2 и т. д. Так как сайт хостинга гильдии настроен на обработку только одной XML-страницы, я не могу получить доступ к другим XML-страницам.

Итак, я могу думать только о двух решениях, но понятия не имею, с чего начать

  1. Настройте страницу php, которая объединяет все страницы XML в одну, а затем выведите этот файл. Затем я могу использовать этот URL в процессоре XSL сайта хостинга гильдии.
  2. Каким-то образом объединить все файлы XML в таблице стилей XSL. Я нашел этот вопрос на SO (я не совсем понимаю, потому что я не знаю, что делает document($pXml1)), но я не думаю, что он будет работать, так как количество страниц будет переменной. Я думаю, что это возможно, загрузив следующую страницу, пока значение <members_to> не будет равно <members_total>.

Есть еще идеи? Я не очень хорошо знаю XSL или php, поэтому любая помощь с примерами кода будет принята с благодарностью.


Обновление: я пытаюсь использовать метод 2, описанный выше, и здесь приведен фрагмент XSLT, с которым у меня возникли проблемы. Первая страница кода отображается без проблем, но у меня проблемы с этим xsl:if, или, возможно, это оператор document().

Обновление № 2: изменен документ для использования функций string и 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()] в шаблон SuperGroup и members, но безуспешно. Я также попытался переформатировать код к чему-то похожему на этот пост и все же не повезло. Буду признателен за любые другие идеи.

1 Ответ

4 голосов
/ 26 марта 2010

Эта таблица стилей принимает страницу "0" в качестве входного документа. В шаблоне members мы проверяем наличие дополнительных страниц и, если необходимо, применяем шаблон * next-page * next2 page. Этот последний шаблон вычисляет номер страницы и выбирает элемент 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: element, поскольку имена не являются динамическими; используйте шаблоны значений атрибутов вместо 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...