Jquery 从一个XML XSLT到HTML生成两列

Jquery 从一个XML XSLT到HTML生成两列,jquery,html,css,xml,xslt,Jquery,Html,Css,Xml,Xslt,我的XML来自一个我无法更改的源。他们将其作为列表发送,但列表也可以包含嵌入式列表。下面是一个简短的例子: <LinkList> <ListHeader>A</ListHeader> <ArticleLink chunkiid="13121">A Test 1</ArticleLink> <ArticleLink chunkiid="13122">A Test 2</ArticleLink> &l

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

A.

  • 我已经能够使用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>
    
    
    
    &;nbsp;
    我遗漏了一些模板,因为我不想让它太长。我想这显示了我现在是如何分解它的,但是从我的示例中,您可以看到,由于内部列表的原因,右侧的部分更长

    有没有办法留下一个列表,然后使用CSS或JQuery将其分成两列?如果没有,是否有一种方法可以计算XML中的所有链接,并使用还包含子节点的position()将其拆分

    更新
    我所说的两列是指一半的记录在页面的一边,另一半在另一边。很抱歉,XSLT只使用div标记,因为这是客户端及其设计器在此网站上设置的标准。

    没有扩展功能,只是为了好玩:

    <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>
    
    
    &;nbsp;
    
    输出:

    <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>
    
    A
    
      内部测试1 内部测试2 测试1 A测试2
      测试3 测试4 测试5
    &;nbsp;
    具有扩展(更好的性能):

    
    
    &;nbsp;
    您可以获取所需数据并将其添加到一个新节点中,然后从该节点开始工作,这样您就可以使用一个平面列表。我如何将其返回到内部列表?我需要内部列表保持原样,但我会询问客户是否同意我将其制作为一个平面列表。请注意,我花了一段时间才明白“列”是什么意思。如果您想将列表项的一半放在一个
    div
    中,另一半放在另一个
    div
    中,那么您应该这样说。把
    div
    column称为“column”是不标准的。还要注意的是,我认为你要求的是不可能的。如果允许您将列表展平,那么您可以在每个
    div
    中放入大致正确的数量。例如,在示例中总共有8个
    ArticleLink
    元素。使用平面列表,您可以在每个
    div
    中放置4个。但是,如果这三个内部链接必须保持在一起,那么无论你如何分组,结果都将是不均匀的(假设你想保持有序)。感谢你的回答,我今天将看一看这是如何工作的。经过一系列研究,他们最终将你所拥有的进行了扁平化。谢谢@韦伯曼:不客气。我只是想用另一种简单的方法来解决没有扩展的问题。明天我将再次讨论这个问题。
    <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>