【问题标题】:XSLT 1.0: Filter, Sort, and page a nodesetXSLT 1.0:过滤、排序和分页节点集
【发布时间】:2017-01-27 21:29:38
【问题描述】:

给定以下 XML:

<A>
  <Photos>
    <Photo>
      <PhotoID>142</PhotoID>
      <PhotoTitle>A</PhotoTitle>
      <Comment />
    </Photo>
    <Photo>
      <PhotoID>143</PhotoID>
      <PhotoTitle>B</PhotoTitle>
      <Comment />
    </Photo>
    <Photo>
      <PhotoID>144</PhotoID>
      <PhotoTitle>C</PhotoTitle>
      <Comment />
    </Photo>
    <Photo>
      <PhotoID>145</PhotoID>
      <PhotoTitle>D</PhotoTitle>
      <Comment />
    </Photo>
    <Photo>
      <PhotoID>146</PhotoID>
      <PhotoTitle>E</PhotoTitle>
      <Comment />
    </Photo>
    <Photo>
      <PhotoID>195</PhotoID>
      <PhotoTitle>F</PhotoTitle>
      <Comment>Foo</Comment>
    </Photo>
    <Photo>
      <PhotoID>196</PhotoID>
      <PhotoTitle>G</PhotoTitle>
      <Comment>Bar</Comment>
    </Photo>
    <Photo>
      <PhotoID>197</PhotoID>
      <PhotoTitle>H</PhotoTitle>
      <Comment>Baz</Comment>
    </Photo>
    <Photo>
      <PhotoID>199</PhotoID>
      <PhotoTitle>F</PhotoTitle>
      <Comment>qux</Comment>
    </Photo>
  </Photos>
</A>

我想获得类似于以下内容的 HTML 输出:

<div id="photoPage" class="page">
    <!-- Page Header Goes Here -->
    <div>
        <h2>Page Title Goes Here</h2>
        <div class="photoBox">
            <!-- Image URL goes here -->
            <div>
                <div>
                  F
                </div>
                <div>
                  Foo
                </div>
            </div>
        </div>  
        <div class="photoBox">
            <!-- Image URL goes here -->
            <div>
                <div>
                  F
                </div>
                <div>
                  Qux
                </div>
            </div>
        </div>  
    </div>
    <!-- Page Footer Goes Here -->
</div>
<div id="photoPage" class="page">
    <!-- Page Header Goes Here -->
    <div>
        <h2>Page Title Goes Here</h2>
        <div class="photoBox">
            <!-- Image URL goes here -->
            <div>
                <div>
                  G
                </div>
                <div>
                  Bar
                </div>
            </div>
        </div>  
        <div class="photoBox">
            <!-- Image URL goes here -->
            <div>
                <div>
                  H
                </div>
                <div>
                  Baz
                </div>
            </div>
        </div>  
    </div>
    <!-- Page Footer Goes Here -->
</div>

总而言之,我正在尝试过滤仅包含标题为“F”、“G”或“H”的照片,按标题和 ID 排序,然后分成两组.我已经能够完成过滤和排序,但不能分页,或分页但不能过滤和排序,但我无法做到这三个。

作为参考,我正在尝试进行类似于this solution 的分页。

这是行不通的方法:

<xsl:template name="Photos">    
    <xsl:copy>
        <xsl:apply-templates select="//Photos[Photo/PhotoTitle = 'F' or Photo/PhotoTitle = 'G' or Photo/PhotoTitle = 'H']">
        <xsl:sort select="PhotoTitle"/>
        <xsl:sort select="PhotoID"/>
      </xsl:apply-templates>
    </xsl:copy>
</xsl:template>

<xsl:template match="Photos">
    <xsl:param name="pageSize" select="2"></xsl:param>
    <xsl:for-each select="//Photos/Photo[position() mod $pageSize = 1]">
      <div id="photoPage" class="page">
        <div>
          <h2>Title</h2>
          <xsl:apply-templates select="self::*|following-sibling::*[position() &lt; $pageSize]">
          </xsl:apply-templates>
        </div>
      </div>
    </xsl:for-each>
</xsl:template>

<xsl:template match="Photo">
    <div class="photoBox">
      <!-- img tag -->
      <div>
        <div>
          <xsl:value-of select="./PhotoTitle"/>
        </div>
        <div>
          <xsl:value-of select="./Comment"/>
        </div>
      </div>
    </div>
</xsl:template>

我的想法是我明确调用第一个模板,它应该过滤和排序照片元素,应用第二个模板,它将照片元素拆分并包装成每页两个,并应用第三个模板,它输出和单独照片。

我目前得到的结果既没有过滤也没有排序,而是进行了适当的拆分。我怀疑这是由于照片模板与我明确调用的模板分开匹配。

【问题讨论】:

  • 为什么不发布您的尝试以便我们修复它,而不必从头开始为您编写代码。 --附言你说要三人一组,但我看到两人一组。

标签: xml xslt xpath xslt-1.0


【解决方案1】:

这个想法是我明确地调用第一个模板

我在您发布的代码中没有看到这样的调用。第二个模板执行xsl:for-each 选择all Photos,没有Title 过滤。

您的方法的另一个问题是,如果不先复制过滤的节点,就不能使用 following-sibling 轴(并且,由于您使用的是 XSLT 1.0,因此将生成的树片段转换为节点集,以便它可以在第二遍处理)。

您还有几个语法错误。

试试这个作为你的起点:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exsl="http://exslt.org/common"
extension-element-prefixes="exsl">
<xsl:strip-space elements="*"/>

<xsl:template match="A"> 
    <html>
        <body>
            <xsl:apply-templates/>
        </body>
    </html>
</xsl:template>

<xsl:template match="Photos"> 
    <xsl:param name="pageSize" select="2"/>
    <!-- first pass -->
    <xsl:variable name="photos">
        <xsl:for-each select="Photo[PhotoTitle = 'F' or PhotoTitle = 'G' or PhotoTitle = 'H']">
            <xsl:sort select="PhotoTitle"/>
            <xsl:sort select="PhotoID" data-type="number"/>
            <xsl:copy-of select="."/>
        </xsl:for-each>
    </xsl:variable>
    <!-- output -->
    <xsl:for-each select="exsl:node-set($photos)/Photo[position() mod $pageSize = 1]">
        <div id="photoPage" class="page">
            <div>
                <h2>Title</h2>
                <xsl:apply-templates select=". | following-sibling::Photo[position() &lt; $pageSize]"/>
            </div>
        </div>
        </xsl:for-each>
</xsl:template>

<xsl:template match="Photo">
    <div class="photoBox">
      <!-- img tag -->
      <div>
        <div>
          <xsl:value-of select="PhotoTitle"/>
        </div>
        <div>
          <xsl:value-of select="Comment"/>
        </div>
      </div>
    </div>
</xsl:template>

</xsl:stylesheet>

应用于您的示例输入,结果将是:

<html>
   <body>
      <div id="photoPage" class="page">
         <div>
            <h2>Title</h2>
            <div class="photoBox">
               <div>
                  <div>F</div>
                  <div>Foo</div>
               </div>
            </div>
            <div class="photoBox">
               <div>
                  <div>F</div>
                  <div>qux</div>
               </div>
            </div>
         </div>
      </div>
      <div id="photoPage" class="page">
         <div>
            <h2>Title</h2>
            <div class="photoBox">
               <div>
                  <div>G</div>
                  <div>Bar</div>
               </div>
            </div>
            <div class="photoBox">
               <div>
                  <div>H</div>
                  <div>Baz</div>
               </div>
            </div>
         </div>
      </div>
   </body>
</html>

【讨论】:

    猜你喜欢
    • 2014-02-06
    • 1970-01-01
    • 1970-01-01
    • 2012-09-03
    • 2012-07-16
    • 2014-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多