2011-11-09 7 views
0

ここ数日間、私を悩ませている問題があります。それはかなり簡単ですが、XSLTはデバッグするのに苦労します。私たちは、可変要素名を使用してXSLTにノード値を出力しようとしています

<?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

1.6のJava上でのXalan 1.0を使用している私たちは、各rfb2_itemの値のコンマ区切りのリストにXMLを変換する必要があるので、スタイルシートは常にrfb2_itemノードを反復します。私たちは、出力されるrfb2_itemの要素(valdate、fund_id、sec_id)を制御するために、スタイルシートでパラメータを使用して、どのような順序で、$ outputElementsは*」であれば例えば

<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 

特殊なケースです彼らは、入力XMLだから、

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

..outputs... 

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

に表示される順番で」、ちょうど出力要素は、私の質問はどのように我々は$ outputElementsパラメータに基づいて所望の出力を作成するためのテンプレートを書くのですか?実例は素晴らしいでしょう...

+0

質問をするのを忘れました。あなたが誰かにあなたのために完全なxsltを書くことを望んでいない限り - それは彼らが行います。 – FailedDev

答えて

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は、ローカル名がoutputElementsパラメータに含まれているか、またはoutputElementsパラメータが*である現在のrfb2_itemの各要素を選択します(この場合、常にtrueになります)。そのローカル名の前にある部分文字列の長さに基づいてそれらを並べ替えます。outputElements。この値は、その名前の後に発生すると高くなります。これは、パラメータに基づいて順序付けされます。

例:要素VALDATEは、substring-before関数の場合はFUND_ID,SEC_IDとなり、文字列長として14が得られます。これはSEC_IDの8よりも高く、VALDATEの値はSEC_IDの後に表示されます。

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

xsl:textを使用して挿入した改行は、Windows/DOSの規約を前提としています。キャリッジリターン+改行ではなく、ファイルで改行文字のみを使用する場合は、&#13;を削除します。

これは、CSV出力でコンマをエスケープしないことに注意してください。私はそれをあなたに任せます。 extension functionsを使用してこのタスクをJavaに委譲することは、XSLT/XPathで非常に難しいと判明した場合には面白いかもしれません。

+0

ちょっとG_H、これは素晴らしいですし、それは動作します。あなたはストレスを大いに和らげました、ありがとう。すべての空白を削除するために、スタイルシートの上部にを追加しました。私はいくつか質問がありました。並べ替えは必要ですか?また、文字列の長さに関するコメントで私の心配がありますが、rfb2_item/E1とrfb2_item/E2のように、2つ以上の要素の長さが同じであると考える必要がありますか? – raffian

+0

@RaffiM並べ替えは、出力フィールドがパラメータによって決定された順序であることを確認するためのものです。チェックされる文字列の長さは、出力される要素の内容ではなく、**パラメーター**の部分文字列の長さです。要素がパラメータで指定された順序で出力されていることを確認するのは難しいことです。基本的には、出力しなければならない各要素の名前( 'FUND_ID'、' VALDATE' ...)は異なる番号を生成します。これらの数値は、与えられたパラメータに基づいて順序付けを行います。 –

+0

@G_H ...それは意味があります...最後の質問では、あなたのコードをより大きなスタイルシートに統合しようとしています。私たちはそれがスタンドアロンで動作することを知っていますが、問題は私たちがそれを呼び出す方法です。既に "/ *"でマッチしている別のテンプレートから(xsl:call-templateを使用して)テンプレートを呼び出すと、同じ出力を生成するためにテンプレートコードが変更されますか? – raffian

0

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

関連する問題