0

特定のノード値の最初の出現に一致させたいのですが、困惑しています。

私は試し<xsl:when test="root/content/contentType = root/content/contentType[.='generic'][1]">ましたが、すべての出来事に一致します。<xsl:when test="root/content/contentType[.='generic'][1]">

最後に、以下の出力HTMLを作成します。最初のアイテムにはヘッダーがありますが、すべてのアイテムには同じ値のクラスがあります。

これが私のXMLです。

どんなアイデアでも大歓迎です。

XML:

<root>
    <content>
        <contentType>ingredients</contentType>
        <listItems>
            <item>Item 1</item>
            <item>Item 2</item>
        </listItems>
    </content>
    <content>
        <contentType>generic</contentType>
        <listItems>
            <item>Item 1</item>
            <item>Item 2</item>
        </listItems>
    </content>
    <content>
        <contentType>generic</contentType>
        <listItems>
            <item>Item 1</item>
            <item>Item 2</item>
        </listItems>
    </content>
    <content>
        <contentType>ingredients</contentType>
        <listItems>
            <item>Item 1</item>
            <item>Item 2</item>
        </listItems>
    </content>
    <content>
        <contentType>directions</contentType>
        <listItems>
            <item>Item 1</item>
            <item>Item 2</item>
        </listItems>
    </content>
</root>

必要な出力:

<div class="ingredients">
    <h2>Ingredients</h2>
    <ul>
        <li>Item 1</li>
        <li>Item 2</li>
    </ul>
</div>
<div class="generic">
    <h2>Generic</h2>
    <ul>
        <li>Item 1</li>
        <li>Item 2</li>
    </ul>
</div>
<div class="generic">
    <ul>
        <li>Item 1</li>
        <li>Item 2</li>
    </ul>
</div>
<div class="ingredients">
    <ul>
        <li>Item 1</li>
        <li>Item 2</li>
    </ul>
</div>
<div class="directions">
    <h2>Directions</h2>
    <ul>
        <li>Item 1</li>
        <li>Item 2</li>
    </ul>
</div>

編集:

XSL:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:template match="/">

        <xsl:for-each select="root/content">
            <div>
                <xsl:attribute name="class"><xsl:value-of select="./contentType"/></xsl:attribute>

                <xsl:choose>
                    <xsl:when test="./contentType[.='ingredients'][1]">
                        <h2><xsl:value-of select="./contentType"/></h2>
                    </xsl:when>
                    <xsl:when test="./contentType[.='generic'][1]">
                        <h2><xsl:value-of select="./contentType"/></h2>
                    </xsl:when>
                    <xsl:when test="./contentType[.='directions'][1]">
                        <h2><xsl:value-of select="./contentType"/></h2>
                    </xsl:when>
                </xsl:choose>
                <ul>
                    <xsl:for-each select="listItems/item">
                        <li><xsl:value-of select="."/></li>
                    </xsl:for-each>
                </ul>
            </div>
        </xsl:for-each>       

    </xsl:template>
</xsl:stylesheet>
4

2 に答える 2

2

XSLTの楽しみをもっと知りたい場合は、「MuenchianGrouping」と呼ばれる手法を使用してこれを解決できることを知りたいと思うかもしれません。事実上、 contentType要素によってコンテンツ要素をグループ化し、グループの最初の要素に対して特別なアクションを実行します(つまり、h2見出しを付けます) 。

まず、グループを表すキーを定義します

<xsl:key name="content" match="content" use="contentType"/>

したがって、コンテンツ要素を探して、 contentTypeで配置します。

少し怖い部分があります。特定のコンテンツ要素がcontentTypeのグループの最初の要素であるかどうかを確認する方法があります

 <xsl:if test="generate-id() = generate-id(key('content', contentType)[1])">

これを分解するには、現在のcontentTypeのキーの最初のコンテンツkey('content', contentType)[1]要素を返します。次に、これを現在のコンテンツ要素と比較して、それらが同じであるかどうかを確認する必要があります。これを行うには、任意の要素の一意のIDを返すgenerate-idを使用します。

このXSLTを試してください

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:output method="xml" indent="yes"/>
   <xsl:key name="content" match="content" use="contentType"/>

   <xsl:template match="root/content">
      <div class="{contentType}">
         <xsl:if test="generate-id() = generate-id(key('content', contentType)[1])">
            <h2>
               <xsl:value-of select="contentType"/>
            </h2>
         </xsl:if>
         <xsl:apply-templates select="listItems"/>
      </div>
   </xsl:template>

   <xsl:template match="listItems">
      <ul>
         <xsl:apply-templates select="item"/>
      </ul>
   </xsl:template>

   <xsl:template match="item">
      <li>
         <xsl:value-of select="."/>
      </li>
   </xsl:template>
</xsl:stylesheet>

問題をグループ化する場合、MuenchianGroupingが問題を解決する最も効率的な方法です。

于 2013-01-10T08:42:50.170 に答える
0

これはどう:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:template match="/">

        <xsl:for-each select="root/content">
            <div class="{contentType}">
                <xsl:if test="not(preceding::content[contentType = current()/contentType])">
                        <h2><xsl:value-of select="contentType"/></h2>
                </xsl:if>
                <ul>
                    <xsl:for-each select="listItems/item">
                        <li><xsl:value-of select="."/></li>
                    </xsl:for-each>
                </ul>
            </div>
        </xsl:for-each>       

    </xsl:template>
</xsl:stylesheet>

これは少しきれいかもしれません:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:template match="content">
            <div class="{contentType}">
                <xsl:if test="not(preceding::content[contentType = current()/contentType])">
                        <h2><xsl:value-of select="contentType"/></h2>
                </xsl:if>
                <ul>
                   <xsl:apply-templates select="listItems" />
                </ul>
            </div>
    </xsl:template>
    <xsl:template match="listItem/item">
          <li><xsl:value-of select="."/></li>
    </xsl:template>
</xsl:stylesheet>

ここでの1つの不一致は、目的の出力のh2値が大文字になっていることですが、この場合は大文字になりません。あなたはそれを知っていましたか?

ソースXMLでクラスとタイトルを別々の値として使用することをお勧めしますが、両方の場所で同じ値を使用する場合は、次のようにして最初の文字を大文字にすることができます。

<h2><xsl:value-of select="concat(translate(substring(contentType, 1, 1), 
   'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'), 
   substring(contentType, 2))"/></h2>
于 2013-01-10T01:24:47.750 に答える