0

それで、ここ数日間私を悩ませてきた問題があります。かなり簡単なはずですが、XSLTはデバッグするのがとても面倒です。Java1.6でXalan1.0を使用しています

入力XML

<?xml version="1.0" encoding="UTF-8"?>
<rfb2>
    <rfb2_item>
        <VALDATE>2011-10-23</VALDATE>
        <FUND_ID>300</FUND_ID>
        <SEC_ID>34567</SEC_ID>
    </rfb2_item>
    <rfb2_item>
        <VALDATE>2011-1-09</VALDATE>
        <FUND_ID>700</FUND_ID>
        <SEC_ID>13587</SEC_ID>
    </rfb2_item>
    <rfb2_item>
        <VALDATE>2011-3-09</VALDATE>
        <FUND_ID>200</FUND_ID>
        <SEC_ID>999334</SEC_ID>
    </rfb2_item>
<rfb2>

XMLを各rfb2_itemの値のコンマ区切りリストに変換する必要があるため、スタイルシートは常にrfb2_itemノードを繰り返します。スタイルシートのパラメーターを使用して、出力されるrfb2_item(valdate、fund_id、sec_id)の要素とその順序を制御しています。

<xsl:param name="$outputElements" select="'VALDATE,FUND_ID'"/>
..outputs...

2011-10-23,300
2011-1-09,700
2011-3-09,200



<xsl:param name="$outputElements" select="'SEC_ID'"/>    
..outputs...

34567
13587
999334

$outputElementsが'*'の場合、入力xmlに表示される順序で要素を出力するだけの特殊なケース

<xsl:param name="$outputElements" select="'*'"/>

..outputs...

2011-10-23,300,34567
2011-1-09,700,13587
2011-3-09,200,999334

だから、私の質問は、$outputElementsパラメーターに基づいて目的の出力を作成するためのテンプレートをどのように作成するかです。実用的な例は素晴らしいでしょう...

4

2 に答える 2

1

うん、FailedDev は正しい。誰かがあなたのためにそれを書くでしょう:

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

    <xsl:output method="text" />

    <xsl:param name="outputElements" select=" 'FUND_ID,SEC_ID,VALDATE' " />

    <xsl:template match="rfb2_item">

        <xsl:for-each select="*[contains($outputElements, local-name()) or $outputElements = '*']">
            <xsl:sort select="string-length(substring-before($outputElements, local-name(.)))" />
            <xsl:value-of select="text()" />
            <xsl:if test="position() != last()">
                <xsl:text>,</xsl:text>
            </xsl:if>
        </xsl:for-each>
        <xsl:text>&#13;&#10;</xsl:text>

    </xsl:template>

</xsl:stylesheet>

ちょっと説明。ローカル名がパラメーターに含まれている、またはパラメーターが含まれxsl:for-eachている現在の各要素を選択します (その場合は常に true になります)。次に、そのローカル名の前にある部分文字列の長さに基づいてそれらを並べ替えます。この値は、名前がそのパラメーターの後半にあるほど大きくなるため、パラメーターに基づいて順序付けされます。rfb2_itemoutputElementsoutputElements*outputElements

例: elementは関数に対してVALDATE生成され、文字列の長さとして 14 が生成されます。これは、 で得られる 8 よりも大きく、値が の後に並べられることを意味します。FUND_ID,SEC_IDsubstring-beforeSEC_IDVALDATESEC_ID

の後は、単に要素の値を出力するためにxsl:sort使用しています。xsl:value-ofそこに余分な空白を削除したい場合があります。xsl:for-each 最後に、位置が現在のコンテキスト (並べ替え後の位置) の最後のノードの位置と等しくないかどうかをテストし、そうである場合はカンマを出力します。これにより、最後の値の後にコンマが出力されるのを回避できます。

使用して挿入した改行xsl:textは、Windows/DOS 規則を想定しています。&#13;ファイルが改行にキャリッジ リターン + 改行の代わりに改行文字のみを使用する必要がある場合は、を削除します。

これは CSV 出力のコンマをエスケープしないことに注意してください! それはあなたに任せます。XSLT/XPath では難しすぎることが判明した場合は、このタスクを Java に委譲するために拡張関数を使用することを検討することは興味深いかもしれません。

于 2011-11-09T19:04:41.743 に答える
0

この種の状況では、XSLT を使用して XSLT コードを生成または変更する可能性を検討する価値がある場合があります。この方法でパラメータ化をさらに進めることができます。たとえば、どのフィールドを出力するか、どのようにソートするか、グループ化するかどうか、行を選択する選択基準などを制御できます。

于 2011-11-09T22:25:06.347 に答える