You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在XML文件中全局保留指定codes.head标签的首个实例

全局保留指定属性的首个XML标签实例的XSLT解决方案

需求说明

需要在整个XML文档中,仅保留codes.head标签里md.mnem属性值为ht1或ht1c的首个出现实例,所有后续符合条件的同属性标签都要剔除,完全不受父节点层级的限制。当前使用的XSLT只能在每个父块内保留对应实例,达不到全局筛选的要求。

示例XML

<root>
  <block1>
    <codes>
      <head md.mnem="ht1">First HT1</head>
    </codes>
  </block1>
  <block2>
    <codes>
      <head md.mnem="ht1c">First HT1C</head>
    </codes>
    <subblock>
      <codes>
        <head md.mnem="ht1">Second HT1 (需剔除)</head>
        <head md.mnem="ht1c">Second HT1C (需剔除)</head>
      </codes>
    </subblock>
  </block2>
  <block3>
    <codes>
      <head md.mnem="other">Other content</head>
    </codes>
  </block3>
</root>

当前使用的XSLT脚本

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="codes/head[@md.mnem='ht1' or @md.mnem='ht1c']">
    <xsl:if test="not(preceding-sibling::codes/head[@md.mnem=current()/@md.mnem])">
      <xsl:copy-of select="."/>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

当前输出结果

<root>
  <block1>
    <codes>
      <head md.mnem="ht1">First HT1</head>
    </codes>
  </block1>
  <block2>
    <codes>
      <head md.mnem="ht1c">First HT1C</head>
    </codes>
    <subblock>
      <codes>
        <head md.mnem="ht1">Second HT1 (需剔除)</head>
        <head md.mnem="ht1c">Second HT1C (需剔除)</head>
      </codes>
    </subblock>
  </block2>
  <block3>
    <codes>
      <head md.mnem="other">Other content</head>
    </codes>
  </block3>
</root>

期望输出结果

<root>
  <block1>
    <codes>
      <head md.mnem="ht1">First HT1</head>
    </codes>
  </block1>
  <block2>
    <codes>
      <head md.mnem="ht1c">First HT1C</head>
    </codes>
    <subblock>
      <codes>
        <!-- 后续符合条件的实例已被剔除 -->
      </codes>
    </subblock>
  </block2>
  <block3>
    <codes>
      <head md.mnem="other">Other content</head>
    </codes>
  </block3>
</root>

正确的XSLT实现方案

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <!-- 全局索引符合条件的codes.head节点,按md.mnem属性分组 -->
  <xsl:key name="head-by-mnem" match="codes/head[@md.mnem='ht1' or @md.mnem='ht1c']" use="@md.mnem"/>

  <!-- 身份模板:复制所有未被特殊处理的节点和属性 -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <!-- 处理符合条件的codes.head节点:仅输出每组的第一个实例 -->
  <xsl:template match="codes/head[@md.mnem='ht1' or @md.mnem='ht1c']">
    <xsl:if test="generate-id() = generate-id(key('head-by-mnem', @md.mnem)[1])">
      <xsl:copy-of select="."/>
    </xsl:if>
  </xsl:template>
</xsl:stylesheet>

关键逻辑说明

  1. 全局索引:通过<xsl:key>定义全局索引,把所有codes.head中md.mnem为ht1或ht1c的节点按属性值分组,确保跨层级访问所有符合条件的节点。
  2. 身份模板:保留原XML的所有结构,只对目标节点做特殊处理。
  3. 首个实例判断:用generate-id()比较当前节点和对应分组的第一个节点的ID,只有ID相同(即该节点是全局第一个符合该属性值的实例)时才输出,其他符合条件的节点直接跳过。

内容的提问来源于stack exchange,提问作者Asha Choudhary

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 10:00:24