3

いくつかの要素を組み合わせてXMLからテキストに変換したいのですが、出力の重複は避けたいです。XMLは次のようになります。

<A>
  <B>
    <param1>value0</param1>
    <param2>value1</param2>
  </B>
  <B>
    <param1>value2</param1>
    <param2>value3</param2>
  </B>
  <C>
    <param3>valueC1</param3>
    <D>
      <param4>value0</param4>
      <param5>value4</param5>
    </D>
    <D>
      <param4>value0</param4>
      <param5>value5</param5>
    </D>
    <D>
      <param4>value2</param4>
      <param5>value6</param5>
    </D>
  </C>
  <C>
    <param3>valueC2</param3>
    <D>
      <param4>value0</param4>
      <param5>value5</param5>
    </D>
  </C>
</A>

そして出力:

OBJECT: param1=value0, param2=value1, param3=valueC1, param4=value0;
OBJECT: param1=value2, param2=value3, param3=valueC1, param4=value2;
OBJECT: param1=value0, param2=value1, param3=valueC2, param4=value0;

ノート:

  • すべてのDオブジェクトについて、D.param4=B.param1を使用してBオブジェクトとの一致を探します。
  • 同じCに2つ以上のDオブジェクトがあり、同じBと一致する場合は、そのうちの1つだけを印刷します(この例では、最初のオブジェクトと同じ行が生成されるため、2番目のDオブジェクトでは何も行われません)。
  • 同じBと一致するが異なるCに一致する2つのDオブジェクトがある場合は、両方を印刷します(出力例の3行目)

似たような質問を探しましたが、同じ場合は見つかりませんでした。

キーを使ってできると思いますが、複雑すぎます。

ありがとう!

よろしく、エール。

PS:私の英語でごめんなさい。

4

2 に答える 2

3

出力で何も使用していないことを考えるとparam5、問題を単純化して次のようにすることが可能であるように思われます。

  • Cごとに
    • 含まれているDのいずれかに一致するすべての異なるB要素を検索しますparam1param4
    • それらのそれぞれのために
      • B / param1、B / param2、currentC / param3、B / param1を再度抽出します(ただし、param4とラベル付けされています)

これは、テンプレートを使用してそれを実現する1つの方法です。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:output method="text" />
  <xsl:key name="BbyParam1" match="B" use="param1" />

  <xsl:template match="/">
    <xsl:apply-templates select="A/C" />
  </xsl:template>

  <xsl:template match="C">
    <xsl:apply-templates select="key('BbyParam1', D/param4)">
      <xsl:with-param name="currentC" select="." />
    </xsl:apply-templates>
  </xsl:template>

  <xsl:template match="B">
    <xsl:param name="currentC" />
    <xsl:text>OBJECT: param1=</xsl:text>
    <xsl:value-of select="param1" />
    <xsl:text>, param2=</xsl:text>
    <xsl:value-of select="param2" />
    <xsl:text>, param3=</xsl:text>
    <xsl:value-of select="$currentC/param3" />
    <xsl:text>, param4=</xsl:text>
    <xsl:value-of select="param1" />
    <xsl:text>&#10;</xsl:text>
  </xsl:template>
</xsl:stylesheet>

「含まれているDのいずれかに一致するすべての個別のB要素を見つける」は、関数の2番目の引数としてノードセットを渡すと、正確にこれを実行するため、実際には非常に簡単です。つまり、すべてのノードのセットが返されます。そのキー値は引数ノードセット内の任意のノードの文字列値であり、返されたノードセット(セットである)には重複が含まれていないことが保証されます。param1param4key

于 2013-02-13T11:25:52.883 に答える
0

これでうまくいくはずです:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" indent="yes"/>
  <xsl:key name="kB" match="B" use="param1" />
  <xsl:key name="kD" match="D" 
           use="concat(param4, '+', generate-id(..))"/>

  <xsl:template match="/">
    <xsl:apply-templates select="A/C" />
  </xsl:template>

  <xsl:template match="C">
    <xsl:apply-templates select="D[key('kB', param4) and 
                                    generate-id() = 
                                    generate-id(key('kD', 
                                       concat(
                                          param4, 
                                          '+', 
                                          generate-id(..)
                                       )
                                    )[1])]" />
  </xsl:template>

  <xsl:template match="D">
    <xsl:value-of 
      select="concat('OBJECT: param1=', 
                     key('kB', param4)/param1, 
                     ', param2=', 
                     key('kB', param4)/param2,
                     ', param3=',
                     ../param3,
                     ', param4=',
                     param4,
                     '&#xA;')"/>
  </xsl:template>
</xsl:stylesheet>

サンプルで実行した場合の出力:

OBJECT: param1=value0, param2=value1, param3=valueC1, param4=value0
OBJECT: param1=value2, param2=value3, param3=valueC1, param4=value2
OBJECT: param1=value0, param2=value1, param3=valueC2, param4=value0
于 2013-02-13T11:39:09.070 に答える