2011-06-01 18 views
3

XSLが初めてで、問題を解決するためにこれを最初から選択するプロセスです。テンプレートを使用してネストされたXML構造をトラバースする方法

<root> 
    <Header> 

    </Header> 

    <DetailRecord> 
    <CustomerNumber>1</CustomerNumber> 
    <DetailSubRecord> 
     <Address>London</Address> 
    </DetailSubRecord> 
    <DetailSubRecord> 
     <Address>Hull</Address> 
    </DetailSubRecord> 

    </DetailRecord> 

    <DetailRecord> 
    <CustomerNumber>2</CustomerNumber> 
    <DetailSubRecord> 
     <Address>Birmingham</Address> 
    </DetailSubRecord> 
    <DetailSubRecord> 
     <Address>Manchester</Address> 
    </DetailSubRecord> 

    </DetailRecord> 
    <Footer> 

    </Footer> 

</root> 

が複数の<DetailSubRecord>秒でみとめ<DetailRecord>のそれぞれがある - :

は、私は次の構造を含むソースXMLファイルを持っています。

複数のDetailRecordsの1つのネストされたセットをフラットファイルに出力するXSLをまとめましたが、XSLの2番目のネストされたレベルのレコードを参照する方法を解明できませんでした。 ...ここで

は、これまでのところ、私のXSLです:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:strip-space elements="*"/> 
    <xsl:output method="text"/> 
    <xsl:variable name="spaces" select="' '"/> 
    <xsl:variable name="newline"> 
    <xsl:text>&#10;</xsl:text> 
    </xsl:variable> 
    <xsl:template match="/"> 
    <xsl:value-of select="root/Header/HeaderField"/> 
    <xsl:copy-of select="$newline"/> 
    <xsl:for-each select="root/DetailRecord"> 
     <xsl:value-of select="CustomerNumber"/> 
     <xsl:copy-of select="$newline"/> 
    </xsl:for-each> 
    Trailer - recordCount - <xsl:value-of select="count(root/DetailRecord)"/> 
    </xsl:template> 
</xsl:stylesheet> 
+0

は、これまでのところ、私のXSLです... – Dom

+0

ます。 \tます。 \t \tます。 \t <のxsl:変数名= "改行"> \t \t \t ます。 ます。 // xsl:value-of select = "count(root =" CustomerNumber "/> ) /DetailRecord) "/> Dom

+0

ターゲット出力の例を投稿できますか?指導的な答えは –

答えて

4

XSLTは関数型言語ではなく、手続き型です。 XSLTの新人が気付いていないのは、XSLTプロセッサがツリー内の各ノードをソースに表示されている順序で自動的に処理することです。ただし、各ノードで何を行うかを定義するテンプレートがなければ、何も出力されません。

ほとんどの場合、子要素を処理するために単に<xsl:for-each>を使用する必要はありません。これは既に実行されています。各要素の出力方法を記述したテンプレートを定義するだけです。このように:

<xsl:template match="root"> 
    <xsl:apply-templates /> 
    <xsl:text>Trailer - recordCount - </xsl:text> 
    <xsl:value-of select="count(DetailRecord)" /> 
</xsl:template> 

<xsl:template match="HeaderField | CustomerNumber | Address"> 
    <xsl:value-of select="concat(.,$newline)" /> 
</xsl:template> 

<xsl:template match="DetailSubRecord"> 
    <!-- do something with subrecord here --> 
    <xsl:apply-templates /> 
</xsl:template> 

最初のテンプレートで<xsl:apply-templates />はちょうどそれがレコード数に追加した後、子要素に対処するXSLTプロセッサに指示します。

2番目のテンプレートでは、3つの名前の要素がすべてmatch atrtibuteで処理され、いずれの場合も新しい行で連結されたコンテンツ(.)が出力されます。

現在のフォームの3番目のテンプレートは実際には余計ですが、プロセッサはそれをやりなおしますが、そのコメントをもっと便利なものに置き換えることができます。

これは、DetailRecord要素の処理方法に関する情報を提供していません。あなたがしたいことは、それが子供であることを処理することなので、何も指定する必要はありません。

+0

+1です。 –

3

あなたの状況に(文字通り)テンプレートを適用する方法の簡単な例があります。あなたは必要な出力についてあまり明確ではなかったので、私はそれを発明しました。


サクソン6.5.5 下でテストXSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:strip-space elements="*"/> 
    <xsl:output method="text"/> 

    <xsl:variable name="spaces" select="' '"/> 
    <xsl:variable name="nl"> 
     <xsl:text>&#10;</xsl:text> 
    </xsl:variable> 

    <xsl:template match="/root"> 
     <xsl:apply-templates select="DetailRecord"/> 
     <xsl:apply-templates select="Footer"/> 
    </xsl:template> 

    <xsl:template match="DetailRecord"> 
     <xsl:value-of select="concat(
      'Customer ', 
      CustomerNumber, $nl)" 
      /> 
     <xsl:apply-templates select="DetailSubRecord"/> 
     <xsl:value-of select="concat(
      'Address Count:', 
      count(DetailSubRecord),$nl,$nl 
      )" 
      /> 
    </xsl:template> 

    <xsl:template match="DetailSubRecord"> 
     <xsl:value-of select="concat('-',Address,$nl)"/> 
    </xsl:template> 

    <xsl:template match="Footer"> 
     <xsl:value-of select="concat(
      'Customer Count:', 
      count(preceding-sibling::DetailRecord),$nl 
      )" 
      /> 
    </xsl:template> 

</xsl:stylesheet> 

応用あなたの入力になります:ここで

Customer 1 
-London 
-Hull 
Address Count:2 

Customer 2 
-Birmingham 
-Manchester 
Address Count:2 

Customer Count:2 
関連する問題