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

如何用XSL将XML转换为通用垂直表格?

解决动态生成垂直XML到HTML表格的问题

你的问题在于原XSL是逐个遍历每个Book的子元素,导致每个元素会随着Book重复出现,而我们需要的是按元素名分组,每个元素名对应一行,然后将所有Book的对应值作为列展示。

在XSLT 1.0中,我们可以用Muenchian分组来获取所有唯一的元素名,然后为每个元素名生成一行,再遍历所有Book提取对应的值。下面是完整的解决方案:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <!-- 定义键:按元素的本地名称分组 -->
    <xsl:key name="element-names" match="Book/*" use="local-name()" />

    <xsl:template match="/Library">
        <table border="1">
            <!-- 遍历所有唯一的元素名:取每个分组的第一个节点 -->
            <xsl:for-each select="Book/*[generate-id() = generate-id(key('element-names', local-name())[1])]">
                <tr>
                    <!-- 第一列:元素名称 -->
                    <td><xsl:value-of select="local-name()" /></td>
                    <!-- 遍历所有Book,提取当前元素名对应的值 -->
                    <xsl:for-each select="/Library/Book">
                        <td><xsl:value-of select="*[local-name() = current()/local-name()]" /></td>
                    </xsl:for-each>
                </tr>
            </xsl:for-each>
        </table>
    </xsl:template>
</xsl:stylesheet>

代码解释:

  • Muenchian分组:通过<xsl:key>定义了一个基于元素本地名称的分组,这样我们可以快速找到所有同名的元素。
  • 获取唯一元素名:Book/*[generate-id() = generate-id(key('element-names', local-name())[1])] 这个选择器会筛选出每个元素名称对应的第一个节点,从而得到所有不重复的元素名。
  • 生成每行数据:对于每个唯一元素名,先输出元素名作为第一列,然后遍历所有Book节点,找到当前元素名对应的子元素并输出其值作为后续列。

测试你的输入XML,输出的HTML表格结构如下:

<table border="1">
    <tr>
        <td>Title</td>
        <td>Foo</td>
        <td>Bar</td>
    </tr>
    <tr>
        <td>ThisMaybeHere</td>
        <td>Some Value</td>
        <td>Some Value</td>
    </tr>
    <tr>
        <td>DontKnowAboutThis</td>
        <td>Also Value</td>
        <td>Also Value</td>
    </tr>
</table>

这个结果完全符合你期望的垂直表格布局,而且即使后续新增了IBAN这类所有Book都包含的元素,代码也会自动将其作为新的一行加入表格,不需要修改XSL代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:57:51