【问题标题】:xml creation with xslt (items per page with delta)使用 xslt 创建 xml(每页有 delta 项)
【发布时间】:2009-11-30 06:01:49
【问题描述】:

我正在使用 XSLT 1.0 来转换一些 XML 文档。我有一个问题要做一件事,我需要一些帮助:

我的 XML 文档中有一组项目,例如:

<item1>...</item1>  
<item2>...</item2>  
<!-- ... -->  
<itemN>...</itemN>

我想根据 delta(每页的项目)创建类似的东西,例如 delta 是三个:

<page>  
  <item1>...</item1>  
  <item2>...</item2>  
  <item3>...</item3>  
</page>  
<page>  
  <item4>...</item4>  
  <item5>...</item5>    
  <item6>...</item6>  
</page>

所以,基本上是在 XSLT 中创建一个 XML 结构,每页将放置固定数量的项目。

如果尝试过这样的事情(为了使用节点集):

<xsl:variable name="all_items_per_delta">  
  <xsl:for-each select="item">    
    <!-- if position is one or if mod of 3 then insert a page node, 
         so for first contract and for 3th, 6th, 9th... item -->
    <xsl:if test="position() = 1">  
      <page>  
    </xsl:if>  
    <!-- in the meantime for every contract insert the contract node -->
    <item>
      <!-- ... -->
    </item> 
    <!-- if position is one or if mod of 3 then insert a page node, 
         so for first item and for 3th, 6th, 9th... item--> 
    <xsl:if test="( (position() mod 3) = 0) ) and ( position() != last() )"> 
      </page>
      <page>
    </xsl:if>    
    <!-- if the position is last just end the page element -->
    <xsl:if test="position() = last()">  `  
      </page>
    </xsl:if>
  </xsl:for-each>
</xsl:variable>

但这不起作用,因为 xslt 解析器说

'Expected end of tag 'page' 

这是我要添加的第一个&lt;page&gt; 标签。看来我必须在同一行结束页面选项卡&lt;/page&gt;。不幸的是,&lt;xslt:if&gt; 不起作用。

请指教,我怎样才能制作这种树片段结构,以便以后使用 EXSL 扩展提取节点集。 谢谢。

【问题讨论】:

    标签: xslt


    【解决方案1】:

    之所以不起作用是因为 XSLT 本身必须是格式良好的 XML;例如这个:

    <xsl:if test="...">
       </page>
    </xsl:if>
    

    不是格式良好的 XML。简而言之,你不能在一个结构内有一个开始标签,而在另一个结构内有一个结束标签。

    现在关于如何正确处理这个问题。一种简单的方法是获取外循环中的每个第_n_个元素,并为其生成&lt;page&gt;元素;然后将该元素以及以下 n-1 个元素放入该 &lt;page&gt;:

    <xsl:for-each select="item[position() mod $n = 0]">
       <page>
           <xsl:copy-of select=". | following-sibling::item[position() &lt; $n)]">
       </page>
    </xsl:for-each>
    

    或者,您可能想要使用Muenchean method,按position() mod $n 对项目进行分组。

    【讨论】:

    • +1,虽然我会把它表达为following-sibling::item[position() &amp;lt;= $n]
    • 实际上似乎我们都错了,应该是&lt; $n - 我的代码 p 产生了 $n-1 个项目(自己,然后是 $n-2 个),而你的代码会产生 $n+ 1(自己和 $n 跟随)。
    【解决方案2】:

    我使用 Pavel 的答案,稍作改动,用于分页:

    <xsl:param name="itemsPerPage" select="10"/>
    
    <xsl:for-each select="item[position() mod $itemsPerPage = 1 or position() = 1]">
      <page>
        <xsl:for-each select=". | following-sibling::item[position() &lt; $itemsPerPage]" >
        <!-- code to print out items -->
        </xsl:for-each>
      </page>
    </xsl:for-each>
    

    我认为您需要 or position() = 1 来包含列表中的第一个项目。另外,请注意mod $itemsPerPage = 1。例如,如果您希望每页有 10 个项目,则需要在第一个 for-each 循环中选择项目 1、11、21 等。

    【讨论】:

      【解决方案3】:

      这需要一种在 XSLT 中进行分组的方法。 XSLT 1.0 提供的支持很少,它需要 Munchean 方法的天才来解决它。 XSLT 2.0 有更多支持(但不是所有环境,例如一些 MS 环境)都支持 XSLT2.0。

      一些资源(来自有用的 XML 专家)是:

      http://www.jenitennison.com/xslt/grouping/

      http://www.dpawson.co.uk/xsl/sect2/N4486.html

      http://www.xml.com/pub/a/2003/11/05/tr.html

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-09-23
        • 2013-12-10
        • 1970-01-01
        • 2019-04-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多