Сделайте два столбца из одного XML XSLT в HTML - PullRequest
0 голосов
/ 12 апреля 2011

У меня есть XML из источника, который я не могу изменить.Они отправляют его в виде списка, но списки также могут иметь встроенные списки.Вот краткий пример:

<LinkList>
  <ListHeader>A</ListHeader>
  <ArticleLink chunkiid="13121">A Test 1</ArticleLink>
  <ArticleLink chunkiid="13122">A Test 2</ArticleLink>
  <ArticleLink chunkiid="13123">A Test 3</ArticleLink>
  <LinkList>
    <ListHeader>
      <ArticleLink chunkiid="13124">A Inner List</ArticleLink>
    </ListHeader>
    <ArticleLink chunkiid="13125">A Inner Test 1</ArticleLink>
    <ArticleLink chunkiid="13126">A Inner Test 2</ArticleLink>
  </LinkList>
  <ArticleLink chunkiid="13127">A Test 4</ArticleLink>
  <ArticleLink chunkiid="13128">A Test 5</ArticleLink>
</LinkList>

Имейте в виду, что в реальной жизни это намного больше.Я хочу разделить это на две колонки, используя XSLT или CSS или JQuery.Текущий вывод, если я оставлю его в одном столбце, выглядит следующим образом:

<b>A</b>
<ul>
    <li><a href="Article.aspx?id=13121">A Test 1</a></li>
    <li><a href="Article.aspx?id=13122">A Test 2</a></li>
    <li><a href="Article.aspx?id=13123">A Test 3</a></li>
    <li>
        <b><a href="Article.aspx?id=13124">A Inner List</a></b>
        <ul>
            <li><a href="Article.aspx?id=13125">A Inner Test 1</a></li>
            <li><a href="Article.aspx?id=13126">A Inner Test 1</a></li>
        </ul>
    </li>
    <li><a href="Article.aspx?id=13127">A Test 4</a></li>
    <li><a href="Article.aspx?id=13128">A Test 5</a></li>
</ul>

Я смог разделить его с помощью XSLT, но я могу сделать это только в нижнем списке, поэтому, если есть внутренние списки, он иногда создаетодна сторона или другая длиннее.Я делаю подсчет переменной и затем применяю такой шаблон в XSLT:

<xsl:template match="LinkList">
  <xsl:if test="ListHeader = $CurrentAlphaIndex">
    <xsl:apply-templates select="@*"/>
    <xsl:apply-templates select="ListHeader"/>
    <xsl:variable name="OneSideCount">
      <xsl:value-of select="ceiling((count(child::*) - 1) div 2)" />
    </xsl:variable>
    <div class="col-50">
      <div class="layout-inner-2">
        <ul>
          <xsl:apply-templates select="*[not(self::ListHeader) and (position() - 1) &lt;= $OneSideCount]">
            <xsl:sort select="."/>
          </xsl:apply-templates>
        </ul>
      </div>
    </div>
    <div class="col-50">
      <div class="layout-inner-2">
        <ul>
          <xsl:apply-templates select="*[not(self::ListHeader) and (position() - 1) &gt; $OneSideCount]">
            <xsl:sort select="."/>
          </xsl:apply-templates>
        </ul>
      </div>
    </div>
    <div class="spacer">&amp;nbsp;</div>
  </xsl:if>
</xsl:template>

Я пропустил некоторые из шаблонов, так как не хотел, чтобы это длилось долго.Я полагаю, это показывает, как я сейчас разбиваю его, но из моего примера вы можете видеть, что правая сторона длиннее из-за внутреннего списка.

Есть ли способ оставить его в одном списке и разбить егов два столбца с помощью CSS или JQuery?Если нет, то есть ли способ подсчитать все ссылки в XML и разделить его, используя позицию (), которая также включает дочерние узлы?

Обновление Что я имею в виду под двумя столбцами:половина записей на одной стороне страницы и половина на другой.К сожалению, XSLT использует теги div только потому, что это стандарт на этом сайте, установленный клиентом и его разработчиком.

1 Ответ

1 голос
/ 12 апреля 2011

Без функций расширения просто для удовольствия:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:param name="CurrentAlphaIndex" select="'A'"/>
    <xsl:param name="pColumns" select="2"/>
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="LinkList">
        <xsl:if test="ListHeader = $CurrentAlphaIndex">
            <xsl:apply-templates select="@*"/>
            <xsl:apply-templates select="ListHeader"/>
            <xsl:variable name="vArticleLinks"
                 select="descendant-or-self::LinkList/ArticleLink"/>
            <xsl:variable name="OneSideCount"
                 select="ceiling(count($vArticleLinks) div $pColumns)"/>
            <xsl:apply-templates
                 select="$vArticleLinks[position() mod $OneSideCount = 1]"
                 mode="partition">
                <xsl:with-param name="OneSideCount"
                                select="$OneSideCount"/>
                <xsl:with-param name="pArticleLinks"
                                select="$vArticleLinks"/>
            </xsl:apply-templates>
            <div class="spacer">&amp;nbsp;</div>
        </xsl:if>
    </xsl:template>
    <xsl:template match="ArticleLink" mode="partition">
        <xsl:param name="pArticleLinks" select="/.."/>
        <xsl:param name="OneSideCount" select="0"/>
        <xsl:variable name="vOffSet"
                      select="(position() - 1) * $OneSideCount"/>
        <div class="col-50">
            <div class="layout-inner-2">
                <ul>
                    <xsl:apply-templates select="$pArticleLinks"
                                         mode="filter">
                        <xsl:with-param name="OneSideCount"
                             select="$OneSideCount"/>
                        <xsl:with-param name="pOffSet"
                             select="(position() - 1) * $OneSideCount"/>
                        <xsl:sort/>
                    </xsl:apply-templates>
                </ul>
            </div>
        </div>
    </xsl:template>
    <xsl:template match="ArticleLink" mode="filter">
        <xsl:param name="pOffSet" select="0"/>
        <xsl:param name="OneSideCount" select="0"/>
        <xsl:if test="position() > $pOffSet
                         and
                      $pOffSet + $OneSideCount >= position()">
            <xsl:apply-templates select="."/>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

Выход:

<ListHeader>A</ListHeader>
<div class="col-50">
    <div class="layout-inner-2">
        <ul>
            <ArticleLink chunkiid="13125">A Inner Test 1</ArticleLink>
            <ArticleLink chunkiid="13126">A Inner Test 2</ArticleLink>
            <ArticleLink chunkiid="13121">A Test 1</ArticleLink>
            <ArticleLink chunkiid="13122">A Test 2</ArticleLink>
        </ul>
    </div>
</div>
<div class="col-50">
    <div class="layout-inner-2">
        <ul>
            <ArticleLink chunkiid="13123">A Test 3</ArticleLink>
            <ArticleLink chunkiid="13127">A Test 4</ArticleLink>
            <ArticleLink chunkiid="13128">A Test 5</ArticleLink>
        </ul>
    </div>
</div>
<div class="spacer">&amp;nbsp;</div>

С расширениями (лучшая производительность):

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:msxsl="urn:schemas-microsoft-com:xslt"
 exclude-result-prefixes="msxsl">
    <xsl:param name="CurrentAlphaIndex" select="'A'"/>
    <xsl:param name="pColumns" select="2"/>
    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="LinkList">
        <xsl:if test="ListHeader = $CurrentAlphaIndex">
            <xsl:apply-templates select="@*|ListHeader"/>
            <xsl:variable name="vrftArticleLinks">
                <xsl:for-each
                 select="descendant-or-self::LinkList/ArticleLink">
                    <xsl:sort/>
                    <xsl:copy-of select="."/>
                </xsl:for-each>
            </xsl:variable>
            <xsl:variable name="vArticleLinks"
                 select="msxsl:node-set($vrftArticleLinks)/*"/>
            <xsl:variable name="OneSideCount"
                 select="ceiling(count($vArticleLinks) div $pColumns)"/>
            <xsl:for-each
                 select="$vArticleLinks[position() mod $OneSideCount = 1]">
                <div class="col-50">
                    <div class="layout-inner-2">
                        <ul>
                            <xsl:apply-templates
                             select=".|following-sibling::*[
                                          $OneSideCount > position()
                                       ]"/>
                        </ul>
                    </div>
                </div>
            </xsl:for-each>
            <div class="spacer">&amp;nbsp;</div>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...