将XSLT节点随机插入列表

将XSLT节点随机插入列表,xslt,Xslt,我正在尝试合并两个列表,以便帖子按日期顺序排列,广告以随机间隔添加到列表中 这是我所能做到的 输入XML列表1博客文章 <root> <page> <content createdDate="2015-01-01">Post 1</content> </page> <page> <content createdDate="2015-01-02

我正在尝试合并两个列表,以便帖子按日期顺序排列,广告以随机间隔添加到列表中

这是我所能做到的

输入XML列表1博客文章

   <root>
      <page>
         <content createdDate="2015-01-01">Post 1</content>
      </page>
      <page>
         <content createdDate="2015-01-02">Post 2</content>
      </page>
      <page>
         <content createdDate="2015-01-03">Post 3</content>
      </page>
   </root>
输入XML列表2广告

  <root>
      <advert>
         <content>Advert 1</content>
      </advert>
      <advert>
         <content>Advert 2</content>
      </advert>
      <advert>
         <content>Advert 3</content>
      </advert>
   </root>
输出带有随机广告插入和按日期顺序发布的XML

   <root>
      <merged>
         <content createdDate="2015-01-03">Post 3</content>
      </merged>
      <merged>
         <content>Advert 2</content>
      </merged>
      <merged>
         <content createdDate="2015-01-02">Post 2</content>
      </merged>
      <merged>
         <content createdDate="2015-01-01">Post 1</content>
      </merged>
      <merged>
         <content>Advert 3</content>
      </merged>
      <merged>
         <content>Advert 1</content>
      </merged>
   </root>
XSLT

    <xsl:variable name="mergedData">
       <xsl:for-each select="$currentPage/descendant::cwsBlogItem [@isDoc and string(umbracoNaviHide) != '1']">
           <xsl:copy-of select="."/>
       </xsl:for-each>
    </xsl:variable>

    <xsl:variable name="mergedAdverts">
            <xsl:for-each select="$adverts/descendant::cwsMediumBanner [@isDoc and string(umbracoNaviHide) != '1']">
                <xsl:copy-of select="."/>
            </xsl:for-each>
    </xsl:variable>

    <xsl:variable name="numberOfAdverts" select="count(msxsl:node-set($mergedAdverts)/*)"/>
    <xsl:variable name="numberOfRecords" select="count(msxsl:node-set($mergedData)/*)"/>

    <msxsl:script language="JavaScript" implements-prefix="cws">
        function Random(r) { return Math.ceil(Math.random()*r); }
    </msxsl:script>

    <xsl:apply-templates select="msxsl:node-set($mergedData)/* ">
       <xsl:sort select="@createDate" order="descending" data-type="text" />
       <xsl:sort select="cws:Random($numberOfRecords + $numberOfAdverts)" order="descending"  />
    </xsl:apply-templates>   

非常感谢任何帮助

我建议您这样做:

XSLT1.0

这将为每个广告指定一个介于0和页数-1之间的随机位置。然后,每个页面将模板应用于从位置0开始对应其位置的广告。结果是所有的广告最终都会出现在第一页和最后一页之间

注:
我使用了EXSLT数学:随机函数来生成随机数;您需要使用自己的处理器方法进行合并。

是否可以显示您试图合并的两个列表的示例,以及您期望的输出示例?谢谢添加了示例列表。谢谢你,迈克尔。正是我需要的
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
xmlns:math="http://exslt.org/math"
extension-element-prefixes="exsl math">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:param name="adverts-doc" select="document('adverts.xml')" />

<xsl:variable name="count-pages" select="count(/root/page)" />

<xsl:variable name="ads">
    <xsl:for-each select="$adverts-doc/root/advert">
        <ad rand="{floor(math:random() * ($count-pages - 1))}">
            <xsl:copy-of select="content"/>
        </ad>
    </xsl:for-each>
</xsl:variable>


<xsl:template match="/root">
    <xsl:copy>
        <xsl:apply-templates select="page">
            <xsl:sort select="content/@createdDate" data-type="text" order="ascending"/>
        </xsl:apply-templates>
    </xsl:copy>     
</xsl:template>

<xsl:template match="page">
    <merged>
        <xsl:copy-of select="content"/>
    </merged>
    <xsl:variable name="i" select="position()" />
    <xsl:apply-templates select="exsl:node-set($ads)/ad[@rand = $i - 1]"/>
</xsl:template>

<xsl:template match="ad">
    <merged>
        <xsl:copy-of select="content"/>
    </merged>
</xsl:template>

</xsl:stylesheet>