1

次の構造の XML ファイルがあります。

<block1>
 <node>
  <name>A<name/>
 <node/>
 <node>
  <name>B<name/>
 <node/>
 ...
</block1>

<block2>
 <node>
  <name>B<name/>
 <node/>
 <node>
  <name>D<name/>
 <node/>
 ...
</block2>

各ブロックのメインディッシュは、名前に基づいてソートされます。

block1 と block2 に属するすべての名前を保持するテーブルを作成したいと考えています。これを効率的に行うにはどうすればよいですか (ノードがソートされているという事実を使用して)。

4

2 に答える 2

1

キーを使用したソリューション:

<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="kB1NodeByVal" match="block1/node" use="name"/>
 <xsl:key name="kB2NodeByVal" match="block2/node" use="name"/>

 <xsl:variable name="vDistinctB1Nodes" select=
 "/*/block1/node
      [generate-id()
      =
       generate-id(key('kB1NodeByVal',name)[1])
       ]"/>

 <xsl:template match="/">
     <xsl:copy-of select="$vDistinctB1Nodes[key('kB2NodeByVal', name)]"/>
 </xsl:template>
</xsl:stylesheet>

この変換が提供された XML ドキュメント (重大な不正から修正された) に適用されると、次のようになります。

<t>
    <block1>
        <node>
            <name>A</name>
        </node>
        <node>
            <name>B</name>
        </node>
 ...
    </block1>
    <block2>
        <node>
            <name>B</name>
        </node>
        <node>
            <name>D</name>
        </node>
 ...
    </block2>
</t>

必要な正しい結果が生成されます。

<node>
   <name>B</name>
</node>

このソリューションの効率は O(k) です。ここkで、 は Set 1 の個別の値の数です。これは、セット 1 でキー (インデックス) と個別の値のセットが既に構築されていることを前提としています。

于 2012-12-26T15:07:19.213 に答える
0

Jeni Tennison は EXSLT でこれに対する解決策を書きました:

<xsl:template name="set:intersection">
   <xsl:param name="nodes1" select="/.." />
   <xsl:param name="nodes2"select="/.." />
   <xsl:apply-templates select="$nodes1[count(.|$nodes2) = count($nodes2)]" mode="set:intersection" />
</xsl:template>

<xsl:template match="node()|@*" mode="set:intersection">
   <xsl:copy-of select="." />
</xsl:template>
于 2012-12-26T13:43:52.930 に答える