我有来自我无法改变的来源的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) <= $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) > $OneSideCount]">
<xsl:sort select="."/>
</xsl:apply-templates>
</ul>
</div>
</div>
<div class="spacer">&nbsp;</div>
</xsl:if>
</xsl:template>
我遗漏了一些模板,因为我不想这么长。我认为这显示了我现在如何分解它,但是从我的例子中你可以看到右边因为内部列表而更长。
有没有办法让它保留一个列表并使用CSS或JQuery将其分成两列?如果没有,我可以计算XML中的所有链接,并使用还包含子节点的position()将其拆分?
更新 我的意思是两列是在页面的一边有一半的记录而在另一边有一半。抱歉,XSLT仅使用div标签,因为这是客户及其设计人员在此网站上设置的标准。
答案 0 :(得分:1)
没有扩展功能只是为了好玩:
<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">&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">&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">&nbsp;</div>
</xsl:if>
</xsl:template>
</xsl:stylesheet>