0

私は XSLT に非常に慣れていません。プロジェクトのある時点で立ち往生しています。以下の XML を取得して、目的の HTML を生成する必要があります。

サブセクション「追加」の下にある子ノードを取得し、それらを 2 つずつ HTML 行にグループ化して、各行に左要素と右要素を配置する必要があります。

適切な左右の要素を取得できます。次に、すべての子ノードを 1 つの大きな行にグループ化するか、各子ノードを個別の行にグループ化します。ただし、左要素と右要素を持つ行内に 2 つの HTML グループを作成することはできません。

show="" 属性に追加するストーリーの数を制限する必要があります。これは常に偶数の整数を返します。制限が機能しており、行数を計算できます。しかし、それらを 2 列に分割することはできません。

コピー ノードを使用する必要があることはわかっていますが、機能させることができません。

次の XML があります。

<?xml version="1.0" ?>
<fullpage>
<section name="tops">
    <subsect name="featured" count="1">
        <article>
            <url>http://www.myurl.com</url>
            <title>Title Element</title>
            <description>Description</description>
            <align></align>
            <size>2</size>
        </article>
    </subsect>
    <subsect name="additional" count="7" show="6">
        <article>
            <url>http://www.myurl.com</url>
            <title>Title Element</title>
            <description>Description</description>
            <align>left</align>
        </article>
        <article>
            <url>http://www.myurl.com</url>
            <title>Title Element</title>
            <description>Description</description>
            <align>right</align>
        </article>
        <article>
            <url>http://www.myurl.com</url>
            <title>Title Element</title>
            <description>Description</description>
            <align>left</align>
        </article>
        <article>
            <url>http://www.myurl.com</url>
            <title>Title Element</title>
            <description>Description</description>
            <align>right</align>
        </article>
        <article>
            <url>http://www.myurl.com</url>
            <title>Title Element</title>
            <description>Description</description>
            <align>left</align>
        </article>
        <article>
            <url>http://www.myurl.com</url>
            <title>Title Element</title>
            <description>Description</description>
            <align>right</align>
        </article>
        <article>
            <url>http://www.myurl.com</url>
            <title>Title Element</title>
            <description>Description</description>
            <align>left</align>
        </article>
    </subsect>
</section>
<section name="section2">
    <article>
        ...
    </article>
    <article>
        ...
    </article>
    <article>
        ...
    </article>
    <article>
        ...
    </article>
</section>
</fullpage>

これまでの XSLT は次のとおりです。

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>

<xsl:variable name="topadd" select="fullpage/section[@name='tops']/subsect[@name='additional']/@show" />
<xsl:variable name="topaddrows" select="fullpage/section[@name='tops']/subsect[@name='additional']/@show div 2" />

<!-- top news -->
<div class="bucket">
    <xsl:for-each select="fullpage/section[@name='tops']/subsect[@name='featured']">
     <xsl:choose>
        <xsl:when test="article/size = '2'">
         <div class="col2Feature">
            <ul>
             <li> Two <xsl:value-of select="article/title"/> </li>
            </ul>
         </div>
        </xsl:when>
        <xsl:when test="article/size = '4'">
         <div class="col4Feature">
            <ul>
             <li> Four <xsl:value-of select="article/title"/> </li>
            </ul>
         </div>
        </xsl:when>
        <xsl:when test="article/size = '6'">
         <div class="col6Feature">
            <ul>
             <li> Six <xsl:value-of select="article/title"/> </li>
            </ul>
         </div>
        </xsl:when>
        <xsl:when test="article/size = '8'">
         <div class="col8Feature">
            <ul>
             <li> Eight <xsl:value-of select="article/title"/> </li>
            </ul>
         </div>
        </xsl:when>
     </xsl:choose>
     <!-- /feature -->

    </xsl:for-each>
</div>
<!-- /top news --> 

<xsl:value-of select="$topaddrows"/>
<xsl:for-each select="fullpage/section[@name='tops']/subsect[@name='additional']/article">
 <xsl:if test="not(position() > $topadd)">
    <xsl:choose>
     <xsl:when test="align = 'left'">
        <div class="bucketL">
         <ul>
            <li> <xsl:value-of select="title"/> </li>
         </ul>
        </div>
     </xsl:when>
     <xsl:when test="align = 'right'">
        <div class="bucketR">
         <ul>
            <li> <xsl:value-of select="title"/> </li>
         </ul>
        </div>
     </xsl:when>
    </xsl:choose>
 </xsl:if>
</xsl:for-each>

</body>
</html>
</xsl:template>
</xsl:stylesheet>

必要な HTML:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Untitled Document</title>
</head>

<body>
<div class="bucket">
<div class="col2Feature">
    <ul>
        <li> Two Title Element</li>
    </ul>
</div>
</div>
<div class="col2">
<div class="bucketL">
    <ul>
        <li>Title Element</li>
    </ul>
</div>
<div class="bucketR">
    <ul>
        <li>Title Element</li>
    </ul>
</div>
</div>
<div class="col2">
<div class="bucketL">
    <ul>
        <li>Title Element</li>
    </ul>
</div>
<div class="bucketR">
    <ul>
        <li>Title Element</li>
    </ul>
</div>
</div>
<div class="col2">
<div class="bucketL">
    <ul>
        <li>Title Element</li>
    </ul>
</div>
<div class="bucketR">
    <ul>
        <li>Title Element</li>
    </ul>
</div>
</div>
</body>
</html>
4

2 に答える 2

0

以下は、スタイルシートに組み込まれた推定なしで、サイズに基づいて行を単純に計算するソリューションです。クラス名の一部をどこから取得しているのかを推測する必要がありましたが、それを変更できると考えました。これは XSLT 2.0 を使用しています ... XSLT 1.0 で行き詰まっている場合は、Tim のソリューションをフォローアップできます。以下の解決策は、コンテンツによるグループ化ではなく、計算によるグループ化について学生に教えていることを示しています (多くの学生は、コンテンツによるグループ化を行う必要があると信じています)。

t:\ftemp>type joe.xml 
<?xml version="1.0" ?>
<fullpage>
<section name="tops">
    <subsect name="featured" count="1">
        <article>
            <url>http://www.myurl.com</url>
            <title>Title Element</title>
            <description>Description</description>
            <align></align>
            <size>2</size>
        </article>
    </subsect>
    <subsect name="additional" count="7" show="6">
        <article>
            <url>http://www.myurl.com</url>
            <title>Title Element</title>
            <description>Description</description>
            <align>left</align>
        </article>
        <article>
            <url>http://www.myurl.com</url>
            <title>Title Element</title>
            <description>Description</description>
            <align>right</align>
        </article>
        <article>
            <url>http://www.myurl.com</url>
            <title>Title Element</title>
            <description>Description</description>
            <align>left</align>
        </article>
        <article>
            <url>http://www.myurl.com</url>
            <title>Title Element</title>
            <description>Description</description>
            <align>right</align>
        </article>
        <article>
            <url>http://www.myurl.com</url>
            <title>Title Element</title>
            <description>Description</description>
            <align>left</align>
        </article>
        <article>
            <url>http://www.myurl.com</url>
            <title>Title Element</title>
            <description>Description</description>
            <align>right</align>
        </article>
        <article>
            <url>http://www.myurl.com</url>
            <title>Title Element</title>
            <description>Description</description>
            <align>left</align>
        </article>
    </subsect>
</section>
</fullpage>
t:\ftemp>call xslt2 joe.xml joe.xsl 
<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html
  PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
      <title>Untitled Document</title>
   </head>
   <body>
      <div class="bucket">
         <div class="col2Feature">
            <ul>
               <li>Title Element</li>
            </ul>
         </div>
      </div>
      <div class="col2">
         <div class="bucketL">
            <ul>
               <li>Title Element</li>
            </ul>
         </div>
         <div class="bucketR">
            <ul>
               <li>Title Element</li>
            </ul>
         </div>
      </div>
      <div class="col2">
         <div class="bucketL">
            <ul>
               <li>Title Element</li>
            </ul>
         </div>
         <div class="bucketR">
            <ul>
               <li>Title Element</li>
            </ul>
         </div>
      </div>
      <div class="col2">
         <div class="bucketL">
            <ul>
               <li>Title Element</li>
            </ul>
         </div>
         <div class="bucketR">
            <ul>
               <li>Title Element</li>
            </ul>
         </div>
      </div>
   </body>
</html>
t:\ftemp>type joe.xsl 
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns="http://www.w3.org/1999/xhtml"
                version="2.0">

<xsl:output indent="yes" 
            doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"
    doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/>

<xsl:template match="/">
<html>
<head>
<title>Untitled Document</title>
</head>

<body>
  <xsl:apply-templates select="fullpage/section"/>
</body>
</html>
</xsl:template>

<xsl:template match="section">
  <xsl:variable name="cols" select="subsect[1]/article/size"/>
  <div class="bucket">
    <div class="col{$cols}Feature">
      <ul>
        <li>
          <xsl:apply-templates select="subsect[1]/article/title/node()"/>
        </li>
      </ul>
    </div>
  </div>
  <xsl:for-each-group group-by="(position()-1) idiv $cols"
    select="subsect[2]/article[position()&lt;=current()/subsect[2]/@show]">
    <div class="col{$cols}">
      <xsl:for-each select="current-group()">
        <div class="bucket{upper-case(substring(align,1,1))}">
          <ul>
            <li><xsl:apply-templates select="title/node()"/></li>
          </ul>
        </div>
      </xsl:for-each>
    </div>
  </xsl:for-each-group>
</xsl:template>

</xsl:stylesheet>
t:\ftemp>rem Done! 
于 2013-08-08T23:57:12.250 に答える
0

達成したいことを行う方法は、現在のxsl:for-eachを変更して、各「行」の最初に表示される記事要素のみを選択することです。つまり、位置 1、3、5 などの記事要素...

<xsl:for-each select="fullpage/section[@name='tops']/subsect[@name='additional']
                      /article[position() mod 2 = 1]">

実際、記事要素の総数に関するチェックを条件に追加して、 xsl:ifチェックを回避することもできます。

<xsl:for-each select="fullpage/section[@name='tops']/subsect[@name='additional']
                      /article[not(position() > $topadd)][position() mod 2 = 1]">

次に、この XSLT ループ内で、現在の記事のタイトルと次の記事を次のように出力できます。

<div class="col2">
    <div class="bucketL">
     <ul>
        <li> <xsl:value-of select="title"/> </li>
     </ul>
    </div>
    <div class="bucketR">
     <ul>
        <li> <xsl:value-of select="following-sibling::article[1]/title"/> </li>
     </ul>
    </div>
</div>

ただし、XSLT を学びたいと考えている場合は、繰り返されるコードがたくさんあるため、XSLT を少し整理することができることを指摘する価値があります。

たとえばfullpage/section[@name='tops']、さまざまな場所で xpath 式を使用します。XSLT の出番となるテンプレート マッチングを利用することで、これを単純化できます。次のように上部セクションを選択することから始めます。

<xsl:apply-templates select="fullpage/section[@name='tops']"/>

次に、記事を取得するためのセクションに一致するテンプレート内で、これを行います。これは、現在のxsl:for-eachよりもわずかに短くなっています。

<xsl:apply-templates select="subsect[@name='additional']/article[not(position() &gt; $topadd)][position() mod 2 = 1]"/>

属性値テンプレートも利用できます。たとえば、「おすすめ」セクションのクラス属性を出力するには、次のようにします。

<div class="col{article/size}Feature">

中括弧は、文字どおりに出力するのではなく、評価する式を示します。

この XSLT を試してください。XML に適用すると、必要な出力が得られるはずです。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
   <xsl:variable name="topadd" select="/fullpage/section[@name='tops']/subsect[@name='additional']/@show"/>
   <xsl:variable name="topaddrows" select="$topadd div 2"/>

   <xsl:template match="/">
      <html>
         <body>
            <div class="bucket">
               <xsl:apply-templates select="fullpage/section[@name='tops']"/>
            </div>
         </body>
      </html>
   </xsl:template>

   <xsl:template match="section">
      <xsl:apply-templates select="subsect[@name='featured']"/>
      <xsl:apply-templates select="subsect[@name='additional']/article[not(position() &gt; $topadd)][position() mod 2 = 1]"/>
   </xsl:template>

   <xsl:template match="subsect">
      <div class="col{article/size}Feature">
         <ul>
            <li>
               <xsl:choose>
                  <xsl:when test="article/size = '2'"> Two </xsl:when>
                  <xsl:when test="article/size = '4'"> Four </xsl:when>
                  <xsl:when test="article/size = '6'"> Six </xsl:when>
                  <xsl:when test="article/size = '8'"> Eight </xsl:when>
               </xsl:choose>
               <xsl:value-of select="article/title"/>
            </li>
         </ul>
      </div>
   </xsl:template>

   <xsl:template match="article">
      <div class="col2">
         <xsl:apply-templates select="title"/>
         <xsl:apply-templates select="following-sibling::article[1]/title">
            <xsl:with-param name="class" select="'bucketR'"/>
         </xsl:apply-templates>
      </div>
   </xsl:template>

   <xsl:template match="title">
      <xsl:param name="class" select="'bucketL'"/>
      <div class="{$class}">
         <ul>
            <li>
               <xsl:value-of select="."/>
            </li>
         </ul>
      </div>
   </xsl:template>
</xsl:stylesheet>

また、最終的なテンプレートでパラメーターを使用していることにも注意してください。これにより、左右のタイトルに異なるクラス名を出力できます。

于 2013-08-08T22:40:15.270 に答える