0

次の xml サンプル ドキュメントがあるとします。

<?xml version="1.0"?>
<Brown1>
   <Transaction>
    <Acct_Id>7801177</Acct_Id>
    <Acct_Nm>Name1</Acct_Nm>
    <Trans_Num>116902</Trans_Num>
    <Trans_Desc>Buy</Trans_Desc>
    <Trans_Result>Closed</Trans_Result>
   </Transaction> 
   <Transaction>
    <Acct_Id>7801177</Acct_Id>
    <Acct_Nm>Name1</Acct_Nm>
    <Trans_Num>116903</Trans_Num>
    <Trans_Desc>Sell</Trans_Desc>
    <Trans_Result>Closed</Trans_Result>
   </Transaction> 
   <Transaction>
    <Acct_Id>7801177</Acct_Id>
    <Acct_Nm>Name1</Acct_Nm>
    <Trans_Num>116904</Trans_Num>
    <Trans_Desc>Buy</Trans_Desc>
    <Trans_Result>Open</Trans_Result>
   </Transaction> 
   <Transaction>
    <Acct_Id>8692031</Acct_Id>
    <Acct_Nm>Name2</Acct_Nm>
    <Trans_Num>116932</Trans_Num>
    <Trans_Desc>Buy</Trans_Desc>
    <Trans_Result>Open</Trans_Result>
   </Transaction> 
    <Transaction>
    <Acct_Id>8692031</Acct_Id>
    <Acct_Nm>Name2</Acct_Nm>
    <Trans_Num>116999</Trans_Num>
    <Trans_Desc>Sell</Trans_Desc>
    <Trans_Result>Closed</Trans_Result>
   </Transaction> 
</Brown1>

出したいのはこれ

7801177 Name1

116902 Buy Closed
116903 Sell Closed
116904 Buy Open

8692031 Name2
116932 Buy Open
116999 Sell Closed

基本的にアカウントと名前を一度だけ印刷する

テンプレートを次のように設定します。

<xsl:template name="header">
  <xsl:value-of select="Acct_Id"/>
  <xsl:value-of select="Acct_Nm"/>

  <xsl:call-template name="report_data">
</xsl:template>

<xsl:template name="report_data">
  <xsl:for-each select=".">
    <xsl:value-of select="Trans_Num"/>
    <xsl:value-of select="Trans_Desc"/>
    <xsl:value-of select="Trans_Result"/>
  </xsl:for-each>
 </xsl:template>

これにより、毎回Acct_Id&が生成されます。Acct_Nm次のノードの処理時にそれらが同じである場合、どうすればそれらを除外できますか?

ヘッダー テンプレートで想定していますが、解決策を得ることができませんでした。

やることは単純に思えますか?...

Acct_Idをヘッダー テンプレートに保存して次のテンプレートと比較し、Acct_Id異なる場合のみ印刷することはできますか?

4

1 に答える 1

0

この変換

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:key name="kTransByAcct" match="Transaction" use="Acct_Id"/>

 <xsl:template match=
  "Transaction[generate-id()
              =generate-id(key('kTransByAcct',Acct_Id)[1])]">
    <xsl:value-of select="concat('&#xA;',Acct_Id, ' ', Acct_Nm, '&#xA;')"/>
    <xsl:apply-templates select="key('kTransByAcct',Acct_Id)" mode="group"/>
 </xsl:template>

 <xsl:template match="*" mode="group">
  <xsl:value-of select="concat('&#9;',Trans_Num,' ',Trans_Desc,' ',Trans_Result,'&#xA;')"/>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>

提供されたXMLドキュメントに適用した場合:

<Brown1>
   <Transaction>
    <Acct_Id>7801177</Acct_Id>
    <Acct_Nm>Name1</Acct_Nm>
    <Trans_Num>116902</Trans_Num>
    <Trans_Desc>Buy</Trans_Desc>
    <Trans_Result>Closed</Trans_Result>
   </Transaction>
   <Transaction>
    <Acct_Id>7801177</Acct_Id>
    <Acct_Nm>Name1</Acct_Nm>
    <Trans_Num>116903</Trans_Num>
    <Trans_Desc>Sell</Trans_Desc>
    <Trans_Result>Closed</Trans_Result>
   </Transaction>
   <Transaction>
    <Acct_Id>7801177</Acct_Id>
    <Acct_Nm>Name1</Acct_Nm>
    <Trans_Num>116904</Trans_Num>
    <Trans_Desc>Buy</Trans_Desc>
    <Trans_Result>Open</Trans_Result>
   </Transaction>
   <Transaction>
    <Acct_Id>8692031</Acct_Id>
    <Acct_Nm>Name2</Acct_Nm>
    <Trans_Num>116932</Trans_Num>
    <Trans_Desc>Buy</Trans_Desc>
    <Trans_Result>Open</Trans_Result>
   </Transaction>
    <Transaction>
    <Acct_Id>8692031</Acct_Id>
    <Acct_Nm>Name2</Acct_Nm>
    <Trans_Num>116999</Trans_Num>
    <Trans_Desc>Sell</Trans_Desc>
    <Trans_Result>Closed</Trans_Result>
   </Transaction>
</Brown1>

必要な正しい結果を生成します。

7801177 Name1
    116902 Buy Closed
    116903 Sell Closed
    116904 Buy Open

8692031 Name2
    116932 Buy Open
    116999 Sell Closed

説明

Muenchianグループ化方法の適切な使用。

更新

OPは劇的に「重要でない解決策」を要求しました。

非キーソリューションは2次の時間計算量(O(N ^ 2))を持ち、キーベースのソリューションはO(1)に近いことに注意してください。前者は後者よりも何桁も遅くなる可能性があります。

キーベースではないXSLT1.0ソリューションを実用的な目的で使用しないことを強くお勧めします。

要求された非キーベースのグループ化ソリューションは次のとおりです。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="Transaction[not(Acct_Id=preceding-sibling::*/Acct_Id)]">
    <xsl:value-of select="concat('&#xA;',Acct_Id, ' ', Acct_Nm, '&#xA;')"/>
    <xsl:apply-templates mode="group" select=
    ". | following-sibling::*[current()/Acct_Id = Acct_Id]"/>
 </xsl:template>

 <xsl:template match="*" mode="group">
  <xsl:value-of select="concat('&#9;',Trans_Num,' ',Trans_Desc,' ',Trans_Result,'&#xA;')"/>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>

この変換が同じXMLドキュメント(上記)に適用されると、同じ必要な正しい結果が生成されます。

7801177 Name1
    116902 Buy Closed
    116903 Sell Closed
    116904 Buy Open

8692031 Name2
    116932 Buy Open
    116999 Sell Closed
于 2013-01-06T21:09:26.547 に答える