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 中不同值的数量。这假设我们已经在 Set 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 回答