0

ブログ投稿を含むXMLがあります。各投稿にはdateノードが含まれています。

投稿が行われた年のリストを抽出して、派手な形式で印刷したいと思います。毎年、非常によく似た方法でアクティブな月のリストを印刷したいと思います。

外側の部分は私にとってはうまく機能しています。生のXSLT-1.0を使用してこれを実現する方法が見つからなかったため、EXSLTを使用して実装しました。投稿を繰り返し処理し、年を抽出して新しいyearノードに配置し、これを一時的なXMLツリーとして変数に格納します。次に、EXSLTを使用してこの変数からノードセットを作成し、それを繰り返し処理して重複を削除します。

ただし、毎年内部テンプレートを呼び出すとすぐに、最初のテンプレートから変数構築コードをコピーして貼り付けてダンプしても、出力は生成されません。同じノードセットを再度繰り返すことを拒否するだけです。

私はここで壁にぶつかっていて、正確に起こっていることに頭を包むことは絶対にできません。

これは私がスタイルシートを単純化することに成功したのと同じくらいです::

<xsl:param name="myparam" select="''" />

<xsl:template match="/">
    <ul>
        <xsl:call-template name="outer" />
    </ul>
</xsl:template>

<xsl:template name="outer">
    <xsl:variable name="years_tree">
        <xsl:for-each select="//post">
            <xsl:sort select="date" />
            <xsl:element name="year"><xsl:value-of select="substring(date, 1, 4)" /></xsl:element>
        </xsl:for-each>
    </xsl:variable>

    <xsl:comment>
        <xsl:copy-of select="$years_tree" />
    </xsl:comment>

    <xsl:for-each select="exsl:node-set($years_tree)/year[not(.=following::year)]">
        <li>
            <xsl:value-of select="." />
            <xsl:if test="starts-with($myparam, string(.))">
                <ul>
                    <xsl:call-template name="inner" />
                </ul>
            </xsl:if>
        </li>
    </xsl:for-each>
</xsl:template>

<xsl:template name="inner">
    <xsl:variable name="years_tree">
        <xsl:for-each select="//post">
            <xsl:sort select="date" />
            <xsl:element name="year"><xsl:value-of select="substring(date, 1, 4)" /></xsl:element>
        </xsl:for-each>
    </xsl:variable>

    <xsl:copy-of select="$years_tree" />
</xsl:template>

</xsl:stylesheet>

これは私のサンプル入力です::

<?xml version="1.0" encoding="UTF-8"?>
<blog>
    <post>
        <date>2011-10-22T22:50:26</date>
    </post>
    <post>
        <date>2011-10-02T17:25:14</date>
    </post>
    <post>
        <date>2011-10-14T11:58:58</date>
    </post>
    <post>
        <date>2011-11-21T11:58:58</date>
    </post>
    <post>
        <date>2010-10-14T11:58:58</date>
    </post>
    <post>
        <date>2011-09-14T11:58:58</date>
    </post>
</blog>

これが私が得ている出力です::

<?xml version="1.0"?>
<ul>
  <debug>
    <year>2010</year>
    <year>2011</year>
    <year>2011</year>
    <year>2011</year>
    <year>2011</year>
    <year>2011</year>
  </debug>
  <li>2010<ul><debug/></ul></li>
  <li>2011<ul><debug/></ul></li>
</ul>
4

1 に答える 1

1

パス/は現在のコンテキストノードのドキュメントノードを選択します。この場合、プライマリ入力ドキュメントと作成する一時ドキュメントの2つのドキュメントを操作します。他のテンプレートを呼び出すと、コンテキストノードはyear一時ドキュメント内の要素であるため、一時ドキュメント内の要素//postを検索しようとしますpostが、そのドキュメントには要素がありません。したがって、グローバルを格納していることを確認する必要があります。<xsl:variable name="main-doc" select="/"/>次にpost、プライマリ入力ドキュメントで要素を検索するときに、を使用できます$main-doc//post

于 2011-11-04T11:27:17.913 に答える