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

能否通过XSLT转换将交叉表结构XML转为列表形式XML?

需求说明

我在应用中有如下中间XML文档:

示例源XML数据

<?xml version="1.0" standalone="yes"?>
<DocumentElement>
  <Car>
    <COL1>Name</COL1>
    <COL2>White</COL2>
    <COL3>Black</COL3>
    <COL4>Red</COL4>
  </Car>
  <Car>
    <COL1>BMW</COL1>
    <COL2>20</COL2>
    <COL3>10</COL3>
    <COL4>10</COL4>
  </Car>
  <Car>
    <COL1>TOYOTA</COL1>
    <COL2>15</COL2>
    <COL3>18</COL3>
    <COL4>22</COL4>
  </Car>
  <Car>
    <COL1>MERCEDES</COL1>
    <COL2>20</COL2>
    <COL3>*</COL3>
    <COL4>12</COL4>
  </Car>
</DocumentElement>

其表格形式如下:

| Name     | White | Black | Blue |
| -------- | ----- | ----- | ---- |
| BMW      | 15    | 18    | 22   |
| TOYOTA   | 15    | 18    | 22   |
| MERCEDES | 20    | -     | 12   |

我希望将该XML文档转换为包含Name、Colour、Quantity的简单列表,表格形式如下:

| Name     | Colour | Quantity |
| -------- | ------ | -------- |
| BMW      | White  | 20       |
| BMW      | Black  | 10       |
| BMW      | Blue   | 10       |
| TOYOTA   | White  | 15       |
| TOYOTA   | Black  | 18       |
| TOYOTA   | Blue   | 22       |
| MERCEDES | White  | 20       |
| MERCEDES | Blue   | 12       |

转换后的XML应如下所示:

示例转换后XML数据

<?xml version="1.0" encoding="UTF-8"?>
<DocumentElement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                 xmlns:my="put-your-namespace-uri-here">
   <Car>
      <Name>BMW</Name>
      <Colour>White</Colour>
      <Quantity>20</Quantity>
   </Car>
   <Car>
      <Name>BMW</Name>
      <Colour>Black</Colour>
      <Quantity>10</Quantity>
   </Car>
   <Car>
      <Name>BMW</Name>
      <Colour>Blue</Colour>
      <Quantity>10</Quantity>
   </Car>
   <Car>
      <Name>TOYOTA</Name>
      <Colour>White</Colour>
      <Quantity>15</Quantity>
   </Car>
   <Car>
      <Name>TOYOTA</Name>
      <Colour>Black</Colour>
      <Quantity>18</Quantity>
   </Car>
   <Car>
      <Name>TOYOTA</Name>
      <Colour>Blue</Colour>
      <Quantity>22</Quantity>
   </Car>
   <Car>
      <Name>MERCEDES</Name>
      <Colour>White</Colour>
      <Quantity>20</Quantity>
   </Car>
   <Car>
      <Name>MERCEDES</Name>
      <Colour>Blue</Colour>
      <Quantity>12</Quantity>
   </Car>
</DocumentElement>

请问能否通过XSLT转换实现该需求?恳请指导。

谢谢,
Amit


XSLT实现方案

可以通过XSLT完全实现该转换需求,以下是对应的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="xml" indent="yes" encoding="UTF-8"/>
    
    <!-- 捕获第一行Car节点作为颜色表头 -->
    <xsl:variable name="headers" select="/DocumentElement/Car[1]/*"/>
    
    <xsl:template match="/">
        <DocumentElement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                        xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                        xmlns:my="put-your-namespace-uri-here">
            <!-- 遍历除第一行外的所有Car节点(对应各品牌数据) -->
            <xsl:for-each select="/DocumentElement/Car[position() > 1]">
                <xsl:variable name="currentBrand" select="COL1"/>
                <!-- 遍历当前品牌下除名称外的所有颜色数量节点 -->
                <xsl:for-each select="*[position() > 1]">
                    <xsl:variable name="colPos" select="position()"/>
                    <!-- 获取对应表头的颜色名称 -->
                    <xsl:variable name="colourName" select="$headers[$colPos + 1]"/>
                    <!-- 过滤掉值为*的无效条目 -->
                    <xsl:if test="normalize-space(.) != '*'">
                        <Car>
                            <Name><xsl:value-of select="$currentBrand"/></Name>
                            <Colour><xsl:value-of select="$colourName"/></Colour>
                            <Quantity><xsl:value-of select="."/></Quantity>
                        </Car>
                    </xsl:if>
                </xsl:for-each>
            </xsl:for-each>
        </DocumentElement>
    </xsl:template>
</xsl:stylesheet>

代码说明

  1. 先通过headers变量提取第一个Car节点的所有子元素,作为颜色名称的表头;
  2. 遍历从第二个开始的Car节点,每个节点对应一个汽车品牌;
  3. 对每个品牌节点,遍历除COL1(名称列)外的子元素,将子元素值作为数量,对应表头的内容作为颜色字段;
  4. 用xsl:if过滤掉值为*的条目,不生成无效的Car节点;
  5. 输出的XML结构完全匹配需求,包含指定的命名空间。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 20:35:03