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

使用XSLT将XML转CSV时处理传递依赖的技术求助

用XSLT实现XML到CSV转换并筛选特定关联Party

首先先确认下你提供的XML里relation节点的hid属性可能存在笔误(比如H100应该是H_100,才能和hold的id对应上),我先修正后展示你的源XML:

<root>
  <hold id="H_100">
    <value1>A</value1>
  </hold>
  <hold id="H_200">
    <value1>B</value1>
  </hold>
  <hold id="H_300">
    <value1>C</value1>
  </hold>
  <party id="C_100">
    <value2>D</value2>
  </party>
  <party id="C_200">
    <value2>E</value2>
  </party>
  <party id="C_300">
    <value2>F</value2>
  </party>
  <party id="A_100">
    <value2>G</value2>
  </party>
  <party id="A_300">
    <value2>H</value2>
  </party>
  <relation hid="H_100" pid="C_100"/>
  <relation hid="H_100" pid="A_100"/>
  <relation hid="H_200" pid="C_200"/>
  <relation hid="H_300" pid="A_300"/>
</root>

你的期望CSV输出是:

Hold,Party
A,G
B,
C,H

下面是实现这个需求的XSLT代码,我会一步步解释它的逻辑:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" encoding="UTF-8"/>
  
  <!-- 建立索引:通过party的id快速定位对应的节点,避免重复遍历 -->
  <xsl:key name="party-by-id" match="party" use="@id"/>
  
  <!-- 建立索引:通过hold的id快速找到所有关联的relation -->
  <xsl:key name="relations-by-hid" match="relation" use="@hid"/>

  <xsl:template match="/root">
    <!-- 先输出CSV表头 -->
    <xsl:text>Hold,Party&#10;</xsl:text>
    
    <!-- 遍历每个hold节点,生成一行CSV记录 -->
    <xsl:for-each select="hold">
      <!-- 输出当前hold的value1值 -->
      <xsl:value-of select="value1"/>
      <xsl:text>,</xsl:text>
      
      <!-- 筛选当前hold关联的、pid以A_开头的relation -->
      <xsl:variable name="matching-a-relations" select="key('relations-by-hid', @id)[starts-with(@pid, 'A_')]"/>
      
      <!-- 如果找到匹配的relation,取出对应的party的value2;否则输出空 -->
      <xsl:choose>
        <xsl:when test="$matching-a-relations">
          <xsl:value-of select="key('party-by-id', $matching-a-relations/@pid)/value2"/>
        </xsl:when>
        <xsl:otherwise>
          <xsl:text></xsl:text>
        </xsl:otherwise>
      </xsl:choose>
      
      <!-- 换行,生成下一条记录 -->
      <xsl:text>&#10;</xsl:text>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>

代码逻辑说明:

  1. 索引优化:用xsl:key建立两个索引,分别用来快速查找party和关联的relation,这样比嵌套循环遍历要高效得多,尤其是当XML数据量较大时。
  2. 表头输出:先输出CSV的第一行表头,用&#10;表示换行(兼容大多数操作系统的换行格式)。
  3. 遍历hold节点:逐个处理每个hold,先输出它的value1,然后输出逗号分隔符。
  4. 筛选特定Party:通过key('relations-by-hid', @id)找到当前hold的所有关联relation,再用starts-with(@pid, 'A_')过滤出pid以A_开头的那些。
  5. 处理空值场景:如果当前hold没有匹配的A类Party,就输出空字符串,保证CSV的格式不会混乱。
  6. 换行处理:每个hold处理完成后输出换行符,确保每条记录单独占一行。

如果你的实际XML里relation的hid属性本来就是正确的(和hold的id一致),直接用这段代码就可以得到你想要的CSV输出啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:42:42