0

我对 XSL 还很陌生,正在寻找优化我的代码。如果项目数为 3 或超过 3,我需要做的是改变我的 XSL 的输出。如果有 3 个项目,每个项目<div/>应该只有 1 个<a/> 元素。如果有 6 个,<div/>则应包含 2 个<a/>元素。我下面的代码有效,但我知道必须有更好的方法。

如果 3 个项目看起来像这样

<div>
   <div>
      <a href="/link1.html">
         <div>
            <h1>Header 1</h1>
            <p>Body coy 1</p>
         </div>
      </a>
   </div>
   <div>
      <a href="/link2.html">
         <div>
            <h1>Header 2</h1>
            <p>Body coy 2</p>
         </div>
      </a>
   </div>
   <div>
      <a href="/link3.html">
         <div>
            <h1>Header 3</h1>
            <p>Body coy 3</p>
         </div>
      </a>
   </div>
</div>

如果有 6 个项目,它应该是这样的:

<div>
   <div>
      <a href="/link1.html">
         <div>
            <h1>Header 1</h1>
            <p>Body coy 1</p>
         </div>
      </a>
      <a href="/link2.html">
         <div>
            <h1>Header 2</h1>
            <p>Body coy 2</p>
         </div>
      </a>
   </div>
   <div>
      <a href="/link3.html">
         <div>
            <h1>Header 3</h1>
            <p>Body coy 3</p>
         </div>
      </a>
      <a href="/link4.html">
         <div>
            <h1>Header 4</h1>
            <p>Body coy 4</p>
         </div>
      </a>
   </div>
   <div>
      <a href="/link5.html">
         <div>
            <h1>Header 5</h1>
            <p>Body coy 5</p>
         </div>
      </a>
      <a href="/link6.html">
         <div>
            <h1>Header 6</h1>
            <p>Body coy 6</p>
         </div>
      </a>
   </div>
</div>

XML(6 项):

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <article>
        <header>Header 1</header>
        <body>Body coy 1</body>
        <url><a href="/link1.html" title="Link1">Link 1</a></url>
    </article>
    <article>
        <header>Header 2</header>
        <body>Body coy 2</body>
        <url><a href="/link2.html" title="Link2">Link 2</a></url>
    </article>
    <article>
        <header>Header 3</header>
        <body>Body coy 3</body>
        <url><a href="/link3.html" title="Link1">Link 3</a></url>
    </article>
    <article>
        <header>Header 4</header>
        <body>Body coy 4</body>
        <url><a href="/link4.html" title="Link4">Link 4</a></url>
    </article>
    <article>
        <header>Header 5</header>
        <body>Body coy 5</body>
        <url><a href="/link5.html" title="Link1">Link 5</a></url>
    </article>
    <article>
        <header>Header 6</header>
        <body>Body coy 6</body>
        <url><a href="/link6.html" title="Link1">Link 6</a></url>
    </article>
</root>

XML(3 项):

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <article>
        <header>Header 1</header>
        <body>Body coy 1</body>
        <url><a href="/link1.html" title="Link1">Link 1</a></url>
    </article>
    <article>
        <header>Header 2</header>
        <body>Body coy 2</body>
        <url><a href="/link2.html" title="Link2">Link 2</a></url>
    </article>
    <article>
        <header>Header 3</header>
        <body>Body coy 3</body>
        <url><a href="/link3.html" title="Link1">Link 3</a></url>
    </article>
</root>

XSL:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!--  the number of items to include in each group -->

    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="/root">
        <div>
            <xsl:variable name="articleCount" select="count(article)"/>
            <xsl:variable name="group" select="$articleCount div 3" />

            <xsl:choose>
                <xsl:when test="$articleCount = 3">


                    <xsl:for-each select="article">
                        <div>
                            <xsl:call-template name="articleItem">
                                <xsl:with-param name="item" select="."/>
                            </xsl:call-template>
                        </div>
                    </xsl:for-each>

                </xsl:when>
                <xsl:otherwise>
                    <xsl:apply-templates
                        select="article[position() mod 2 = 1]" >
                        <xsl:with-param name="group" select="2"/>
                    </xsl:apply-templates>
                </xsl:otherwise>
            </xsl:choose>
        </div>
    </xsl:template>

    <xsl:template match="article" mode="inner">
        <xsl:param name="group"/>
        <!-- handle items appropriately here -->

        <xsl:call-template name="articleItem">
            <xsl:with-param name="item" select="."/>
        </xsl:call-template>
    </xsl:template>

    <xsl:template match="article">
        <xsl:param name="group"/>
        <div class="article">
            <xsl:apply-templates
                select=".|following-sibling::article[$group &gt; position()]" 
                mode="inner" />
        </div>
    </xsl:template>

    <xsl:template name="articleItem">
        <xsl:param name="item"/>
        <a>
            <xsl:attribute name="href"><xsl:value-of select="url/a/@href" /></xsl:attribute>
            <xsl:call-template name="articleContent">
                <xsl:with-param name="item" select="."/>
            </xsl:call-template>
        </a>
    </xsl:template>

    <xsl:template name="articleContent">
        <xsl:param name="item"/>
        <div class="article-copy">
            <h1><xsl:value-of disable-output-escaping="yes" select="header" /></h1>
            <p><xsl:value-of disable-output-escaping="yes" select="body" /></p>
        </div>
    </xsl:template>
</xsl:stylesheet>
4

1 回答 1

0

这看起来很有效。你能试一试吗?

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!--  the number of items to include in each group -->

  <xsl:output omit-xml-declaration="yes" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:template match="/root">
    <div>
      <xsl:variable name="sideBySide" select="count(article) > 3" />

      <!-- If not($sideBySide), loop through the articles 1 at a time
           If $sideBySide, loop through articles in odd-numbered positions -->
      <xsl:for-each select="article[(position() - 1) mod (1 + $sideBySide) = 0]">
        <xsl:call-template name="articleRow">
          <!-- Pass the current article, AND its first sibling if $sideBySide -->
          <xsl:with-param name="articles" select=". | following-sibling::article[1][$sideBySide]" />
        </xsl:call-template>
      </xsl:for-each>
    </div>
  </xsl:template>

  <xsl:template name="articleRow">
    <xsl:param name="articles" />
    <div>
      <xsl:apply-templates select="$articles" />
    </div>
  </xsl:template>

  <xsl:template match="article">
    <a href="{url/a/@href}">
      <div class="article-copy">
        <h1>
          <xsl:value-of disable-output-escaping="yes" select="header" />
        </h1>
        <p>
          <xsl:value-of disable-output-escaping="yes" select="body" />
        </p>
      </div>
    </a>
  </xsl:template>
</xsl:stylesheet>
于 2013-01-21T19:02:52.080 回答