5

次の XML があります。

<?xml version="1.0" encoding="UTF-8"?>
<XmlTest>
    <Pictures attr="Pic1">Picture 1</Pictures>
    <Pictures attr="Pic2">Picture 2</Pictures>
    <Pictures attr="Pic3">Picture 3</Pictures>
</XmlTest>

この XSL は期待どおりの動作をします (最初の画像の属性を出力します)。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/XmlTest">
        <xsl:variable name="FirstPicture" select="Pictures[1]">
        </xsl:variable>
        <xsl:value-of select="$FirstPicture/@attr"/>
    </xsl:template>
</xsl:stylesheet>

xsl:copy-of: を使用して変数宣言内で同じことを行うことはできないようです。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >
    <xsl:template match="/XmlTest">
        <xsl:variable name="FirstPicture">
            <xsl:copy-of select="Pictures[1]"/>
        </xsl:variable>
        <xsl:value-of select="$FirstPicture/@attr"/>
    </xsl:template>
</xsl:stylesheet>

興味深い: 2 番目の例で "$FirstPicture/@attr" の代わりに "$FirstPicture" を選択すると、Picture 1 のテキスト ノードが期待どおりに出力されます...

コードを書き直すよう皆さんに提案する前に: これは単純化されたテストにすぎません。私の本当の目的は、名前付きテンプレートを使用してノードを変数 FirstPicture に選択し、それを再利用してさらに選択することです。

誰かが動作を理解するのを手伝ってくれるか、簡単に再利用できるコードでノードを選択する適切な方法を提案してくれることを願っています (私の実際のアプリケーションでは、どのノードが最初のノードであるかの決定は複雑です)。ありがとう。

編集 (Martin Honnen に感謝): これは、MS XSLT プロセッサを使用した私の実用的なソリューションの例です (別のテンプレートを使用して、要求された画像ノードを選択します):

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt"
    version="1.0">
    <xsl:template match="/XmlTest">
        <xsl:variable name="FirstPictureResultTreeFragment">
            <xsl:call-template name="SelectFirstPicture">
                <xsl:with-param name="Pictures" select="Pictures" />
            </xsl:call-template>
        </xsl:variable>
        <xsl:variable name="FirstPicture" select="msxsl:node-set($FirstPictureResultTreeFragment)/*"/>
        <xsl:value-of select="$FirstPicture/@attr"/>
        <!-- further operations on the $FirstPicture node -->
    </xsl:template>

    <xsl:template name="SelectFirstPicture">
        <xsl:param name="Pictures"/>
        <xsl:copy-of select="$Pictures[1]"/>
    </xsl:template>
</xsl:stylesheet>

XSLT 1.0 ではノードをテンプレートから直接出力することはできませんが、余分な変数を使用すると、少なくとも不可能ではありません。

4

1 に答える 1

4

XSLT 1.0 プロセッサを使用する場合は、

    <xsl:variable name="FirstPicture">
        <xsl:copy-of select="Pictures[1]"/>
    </xsl:variable>

変数は結果ツリーのフラグメントであり、純粋な XSLT 1.0 でそれを使用してできることは、copy-of(またはvalue-of) を使用して出力することだけです。XPath を適用する場合は、最初に結果ツリー フラグメントをノード セットに変換する必要があります。ほとんどの XSLT 1.0 プロセッサはそのための拡張機能をサポートしているので、試してみてください。

    <xsl:variable name="FirstPictureRtf">
        <xsl:copy-of select="Pictures[1]"/>
    </xsl:variable>
    <xsl:variable name="FirstPicture" select="exsl:node-set(FirstPictureRtf)/Pictures/@attr">

xmlns:exsl="http://exslt.org/common"スタイルシートで定義する場所。

お使いの XSLT 1.0 プロセッサが EXSLT 拡張関数または別の名前空間の同様の関数をサポートしているかどうかを確認する必要があることに注意してください (たとえば、さまざまな MSXML バージョンがサポートしています)。

于 2012-12-13T17:23:30.380 に答える