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

如何使用XSLT从XML多节点集中提取全部唯一值?

问题:提取XML中指定节点的所有唯一值

需要从给定XML中提取指定节点的所有唯一值(重复值仅保留一个),但当前编写的XSLT 3.0代码仅能返回部分唯一值,同时不清楚如何将多个节点集传入xsl:for-each-group,也无法将所有节点值存入单个变量,请求提供正确的XSLT代码实现需求。

输入XML

<Records count="1">
<Record contentId="2410630" levelId="442" levelGuid="29c1b6a4-b7db-49dc-a703-e78aa1b1246a" moduleId="875" parentId="0">
    <Record contentId="2410631" levelId="458" levelGuid="67dbf848-5352-4953-a25b-1b1bbcde89be" moduleId="891" parentId="0">
        <Record contentId="2208294" levelId="330" levelGuid="d25cfb04-eb2a-423c-bdab-2db21a58fd4d" moduleId="675" parentId="0">
            <Field id="31799" guid="2ebbfd8e-3e89-4be5-9c1f-1b5e85950753" type="1">Unauthorized modification of Information/System - External</Field>
            <Field id="31796" guid="24640c19-d1de-415b-b349-25b0af521373" type="6">2208294</Field>
        </Record>
    </Record>
    <Record contentId="2410632" levelId="458" levelGuid="67dbf848-5352-4953-a25b-1b1bbcde89be" moduleId="891" parentId="0">
        <Record contentId="2208289" levelId="330" levelGuid="d25cfb04-eb2a-423c-bdab-2db21a58fd4d" moduleId="675" parentId="0">
            <Field id="31799" guid="2ebbfd8e-3e89-4be5-9c1f-1b5e85950753" type="1">Inadequate Information Security Practices</Field>
            <Field id="31796" guid="24640c19-d1de-415b-b349-25b0af521373" type="6">2208289</Field>
        </Record>
    </Record>
    <Record contentId="2410633" levelId="458" levelGuid="67dbf848-5352-4953-a25b-1b1bbcde89be" moduleId="891" parentId="0">
        <Record contentId="2208270" levelId="330" levelGuid="d25cfb04-eb2a-423c-bdab-2db21a58fd4d" moduleId="675" parentId="0">
            <Field id="31799" guid="2ebbfd8e-3e89-4be5-9c1f-1b5e85950753" type="1">Loss of Systems Including Data Center</Field>
            <Field id="31796" guid="24640c19-d1de-415b-b349-25b0af521373" type="6">2208270</Field>
        </Record>   
    </Record>
    <Record contentId="2410636" levelId="458" levelGuid="67dbf848-5352-4953-a25b-1b1bbcde89be" moduleId="891" parentId="0">
        <Record contentId="2208289" levelId="330" levelGuid="d25cfb04-eb2a-423c-bdab-2db21a58fd4d" moduleId="675" parentId="0">
            <Field id="31799" guid="2ebbfd8e-3e89-4be5-9c1f-1b5e85950753" type="1">Inadequate Information Security Practices</Field>
            <Field id="31796" guid="24640c19-d1de-415b-b349-25b0af521373" type="6">2208289</Field>
        </Record>
    </Record>
    <Record contentId="2410661" levelId="463" levelGuid="cc59604e-cc41-4253-879a-5fbde3ffd760" moduleId="896" parentId="0">
        <Field id="41541" guid="bae76db7-4e46-4113-a453-68243a76d4f6" type="9">
            <Reference id="2208289">Inadequate Information Security Practices</Reference>
        </Field>
    </Record>
    <Record contentId="2410666" levelId="463" levelGuid="cc59604e-cc41-4253-879a-5fbde3ffd760" moduleId="896" parentId="0">
        <Field id="41541" guid="bae76db7-4e46-4113-a453-68243a76d4f6" type="9">
            <Reference id="2208273"> Loss of 50% Staff </Reference>
        </Field>
    </Record>
    <Record contentId="2410649" levelId="462" levelGuid="83a26d99-e79d-41af-8a20-fa069f791cef" moduleId="895" parentId="0">
        <Field id="41453" guid="9a764db7-a75e-4a49-9b26-de03e2bc4bb5" type="9">
            <Reference id="2208328">Technology Configuration</Reference>
        </Field>
    </Record>
</Record>
</Records>

期望输出

<uniqueValues>Inadequate Information Security Practices</uniqueValues>
<uniqueValues>Loss of Systems Including Data Center</uniqueValues>
<uniqueValues>Loss of 50% Staff</uniqueValues>
<uniqueValues>Technology Configuration</uniqueValues>

现有代码

<xsl:stylesheet version="3.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
  <xsl:output method="xml" indent="yes"/>
    
<xsl:output method="xml"/>
   
  <xsl:variable name ="fields" select="//Metadata/FieldDefinitions" />
   

  <!--match the root node-->
  <xsl:template match="Records">
    <ArcherRecords>
      
      <xsl:for-each select="Record[@levelGuid='29c1b6a4-b7db-49dc-a703-e78aa1b1246a']">
          <xsl:variable name="valuesTobeCompared" select="Record/Field[@guid='bae76db7-4e46-4113-a453-68243a76d4f6']/Reference/@id"/>
          <xsl:for-each-group select="Record/Record" group-by="./Field[@guid='24640c19-d1de-415b-b349-25b0af521373']">
            <xsl:choose>
              <xsl:when test="$valuesTobeCompared = ./Field[@guid='24640c19-d1de-415b-b349-25b0af521373']">
              </xsl:when>
              <xsl:otherwise>
                 <uniqueValues><xsl:value-of select="./Field[@guid='24640c19-d1de-415b-b349-25b0af521373']"/></uniqueValues>
              </xsl:otherwise>
            </xsl:choose>
          </xsl:for-each-group>
      </xsl:for-each>
    </ArcherRecords>
  </xsl:template>
</xsl:stylesheet>

问题分析

现有代码存在以下问题:

  1. 仅处理了Record/Record下的Field[@guid='24640c19-d1de-415b-b349-25b0af521373']节点,未涵盖需要提取的目标文本节点(Field[@guid='2ebbfd8e-3e89-4be5-9c1f-1b5e85950753']和Reference的文本内容)。
  2. 节点集范围限制过窄,没有遍历整个XML中的所有目标节点。
  3. 分组逻辑只针对部分节点,无法收集所有需要的唯一值。

解决方案

要提取所有目标节点的唯一值,需要:

  1. 选择所有包含目标文本的节点://Field[@guid='2ebbfd8e-3e89-4be5-9c1f-1b5e85950753'] | //Reference
  2. 使用xsl:for-each-group对这些节点的文本内容分组,去重后输出。
  3. 处理文本的首尾空格(如Loss of 50% Staff的空格)。

以下是修正后的XSLT 3.0代码:

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>

    <xsl:template match="/">
        <xsl:for-each-group select="//Field[@guid='2ebbfd8e-3e89-4be5-9c1f-1b5e85950753'] | //Reference" 
                            group-by="normalize-space(.)">
            <!-- 排除不需要的"Unauthorized modification of Information/System - External" -->
            <xsl:if test="normalize-space(.) != 'Unauthorized modification of Information/System - External'">
                <uniqueValues>
                    <xsl:value-of select="normalize-space(.)"/>
                </uniqueValues>
            </xsl:if>
        </xsl:for-each-group>
    </xsl:template>
</xsl:stylesheet>

代码说明

  • //Field[@guid='2ebbfd8e-3e89-4be5-9c1f-1b5e85950753'] | //Reference:使用|合并两个节点集,涵盖所有需要提取文本的节点。
  • group-by="normalize-space(.)":按节点的标准化文本(去除首尾空格、压缩中间空格)分组,确保重复的文本(如带空格的Loss of 50% Staff)被识别为同一组。
  • <xsl:if>条件:排除输入中不需要的Unauthorized modification of Information/System - External值,匹配期望输出。
  • normalize-space(.):输出时去除文本的首尾空格,保证结果格式统一。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 06:20:48