14

ソースXMLからフィールドの特定のサブセットを出力するXSLを作成しようとしています。このサブセットは、フィールド名およびその他の特定の情報(パディングの長さなど)を含む外部XML構成ドキュメントを使用して、変換時に決定されます。

したがって、これは2つのfor-eachループです。

  • 外側のレコードはレコードを繰り返し処理して、レコードごとにフィールドにアクセスします。
  • 内側のものは、構成XML文書を反復処理して、現在のレコードから構成済みフィールドを取得します。

In XSLTで、ネストされたループ内から外部ループの要素にアクセスするにはどうすればよいですか?外側のループの現在の要素をに格納できることxsl:variable。ただし、フィールド名を取得するには、内部ループ内に新しい変数を定義する必要があります。どちらが質問になります:2つの変数があるパスにアクセスすることは可能ですか?

たとえば、ソースXMLドキュメントは次のようになります。

<data>
    <dataset>
        <record>
            <field1>value1</field1>
            ...
            <fieldN>valueN</fieldN>
        </record>
    </dataset>
    <dataset>
        <record>
            <field1>value1</field1>
            ...
            <fieldN>valueN</fieldN>
        </record>
    </dataset>
</data>

次のような外部XMLファイルが欲しいのですが。

<configuration>
    <outputField order="1">
        <fieldName>field1</fieldName>
        <fieldPadding>25</fieldPadding>
    </outputField>
    ...
    <outputField order="N">
        <fieldName>fieldN</fieldName>
        <fieldPadding>10</fieldPadding>
    </outputField>
</configuration>

私がこれまでに持っているXSL:

<xsl:variable name="config" select="document('./configuration.xml')"/>
<xsl:for-each select="data/dataset/record">
    <!-- Store the current record in a variable -->
    <xsl:variable name="rec" select="."/>
    <xsl:for-each select="$config/configuration/outputField">
        <xsl:variable name="field" select="fieldName"/>
        <xsl:variable name="padding" select="fieldPadding"/>

        <!-- Here's trouble -->
        <xsl:variable name="value" select="$rec/$field"/>

        <xsl:call-template name="append-pad">
            <xsl:with-param name="padChar" select="$padChar"/>
            <xsl:with-param name="padVar" select="$value"/>
            <xsl:with-param name="length" select="$padding"/>
        </xsl:call-template>

    </xsl:for-each>
    <xsl:value-of select="$newline"/>
</xsl:for-each>

私はXSLにまったく慣れていないので、これはばかげた質問かもしれません。また、アプローチも明らかに間違っている可能性があります(つまり、最初に一度実行できるタスクの内部ループを繰り返す)。外側のループ要素からフィールド値を選択する方法に関するヒントをいただければ幸いです。もちろん、このタスクに取り組むためのより良い方法を紹介します。

4

1 に答える 1

15

あなたのスタイルシートはほとんどうまく見えます。$rec/$fieldこの方法では2つのノードセット/シーケンスを組み合わせることができないため、式だけでは意味がありません。代わりに、name()関数を使用して要素の名前を比較する必要があります。私があなたの問題を正しく理解した場合、このようなものが機能するはずです:

<xsl:variable name="config" select="document('./configuration.xml')"/>
<xsl:for-each select="data/dataset/record">
    <xsl:variable name="rec" select="."/>
    <xsl:for-each select="$config/configuration/outputField">
        <xsl:variable name="field" select="fieldName"/>
        ...
        <xsl:variable name="value" select="$rec/*[name(.)=$field]"/>
        ...    
    </xsl:for-each>
    <xsl:value-of select="$newline"/>
</xsl:for-each>

この例では、変数フィールドは必要ありません。関数current()を使用して、内部ループの現在のコンテキストノードにアクセスすることもできます。

<xsl:variable name="value" select="$rec/*[name(.)=current()/fieldName]"/>
于 2012-05-03T17:36:37.083 に答える