XSL:仅复制大型 XML 文件中具有重复属性值的节点

XSL: Only copy nodes which have a duplicate attribute value in a large XML file

这是我的输入类型:

<modifs>
   <test>
      <ref id="1"/>
      <ref id="2"/>
      <ref id="800"/>
      <ref id="5000"/>
      <ref id="10000"/>
      <ref id="40000"/>
   </test>
   <modif id="1">content1</modif>
   <modif id="2">content2</modif>
   <modif id="3">content3</modif>
   <modif id="4">content4</modif>
</modifs>

在这个输入中,第一个列表 "ref" 只是一个属性列表,第二个列表 "modif" 对我来说才是真正重要的。 我想要做的是仅显示 "ref" 列表中具有匹配 "id" 属性的 "modif" 节点:这里我会得到的是:

<modif>
    <modif id="1">content1</modif>
    <modif id="2">content2</modif>
</modifs>

我尝试处理这个问题,部分成功了。我所做的是检查 "modif" 节点的每个 @id 是否有前面匹配的 "ref"@id:

  <xsl:template match="modifs">
    <xsl:for-each select="./modif">
      <xsl:if test="./@id=preceding::ids/id">
        <xsl:element name="{local-name()}">
          <xsl:for-each select="attribute::*">
            <xsl:attribute name="{local-name()}">
              <xsl:value-of select="."/>
            </xsl:attribute>
          </xsl:for-each>
      <xsl:value-of select="."/>
      </xsl:element>
      </xsl:if>
    </xsl:for-each>
  </xsl:template>

但是,我目前正在处理一个非常大的 XML 文件(超过 200k 个 id),这种方法根本没有时间效率(适用于前一千个 id,需要 hours/days 在那之后)。 我很确定有办法解决它(使用 muenchian 分组?)但我真的不明白我应该做什么...

如果有人可以帮助我/解释我应该如何进行,那就太好了。

谢谢

这里不需要 muenchian 分组,尽管您可以使用键来查找 ref 元素是否存在

  <xsl:key name="ref" match="ref" use="@id" />

然后,与XSLT identity template结合使用,只需要一个模板来匹配modif没有对应ref元素的元素

<xsl:template match="modif[not(key('ref', @id))]"/>

试试这个 XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes" />
  <xsl:strip-space elements="*"/>
  <xsl:key name="ref" match="ref" use="@id" />

  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="modif[not(key('ref', @id))]"/>

  <xsl:template match="test" />
</xsl:stylesheet>