根据 XML 个属性对 XML 个值进行分组 (XSLT)

Grouping XML Values Based On XML Attributes (XSLT)

下面是要使用 XSLT 转换成 XML 的三行数据(制表符分隔)。

Column_1     Column_2     Column_3     Column_4
A            B            C            D
A            B            A            F
C            B            D            C

预期输出如下

<firstTag Column_1 ='A' Column_2='B'>
   <secondTag Column_3='C'  Column_4='D'/>
   <secondTag Column_3='A'  Column_4='F'/>
</firstTag>
<firstTag Column_1 ='C' Column_2='B'>
   <secondTag Column_3='D'  Column_4='C'/>
</firstTag>

如何使用 XSLT

根据一个或多个属性值(Column_1 和 Column_2)对这些行进行分组

您可以使用 unparsed-text 或(在 Saxon 9.8 及更高版本自 2017 年以来支持的 XSLT 3 中)unparsed-text-lines 来处理非 XML 文本文件,就像您似乎拥有的那样,然后你有 tokenize 函数加上 xsl:analyze-string 元素或在 XSLT 3 中 analyze-string 函数来处理和构建你的制表符分隔数据,使其成为你可以提供给 xsl:for-each-group 的东西,即 XSLT 3.XML 中的一些 XML 或一些数组和字符串序列的混合。

XSLT 2 和 3 中的分组在 https://whosebug.com/tags/xslt-grouping/info 中介绍。

Here is an example using XSLT 3for-each-group 在一组字符串数组序列上:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
    xmlns:map="http://www.w3.org/2005/xpath-functions/map"
    xmlns:array="http://www.w3.org/2005/xpath-functions/array"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:param name="text" as="xs:string">Column_1     Column_2     Column_3     Column_4
A            B            C            D
A            B            A            F
C            B            D            C</xsl:param>


  <xsl:param name="el1" as="xs:string">firstElement</xsl:param>
  <xsl:param name="el2" as="xs:string">secondElement</xsl:param>

  <xsl:variable name="rows" as="array(xs:string)*" select="($text => tokenize('\r?\n')) ! array { tokenize(., '\s+') }"/>
  
  <xsl:variable name="data-rows" select="$rows => tail()"/>
  
  <xsl:variable name="column-names" select="$rows[1]?*"/>

  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/" name="xsl:initial-template">
    <result>
        <xsl:for-each-group select="$data-rows" composite="yes" group-by="?1, ?2">
            <xsl:element name="{$el1}">
                <xsl:attribute name="{$column-names[1]}" select="current-grouping-key()[1]"/>
                <xsl:attribute name="{$column-names[2]}" select="current-grouping-key()[2]"/>
                <xsl:apply-templates select="current-group()"/>
            </xsl:element>
        </xsl:for-each-group>
    </result>
  </xsl:template>
  
  <xsl:template match=".[. instance of array(xs:string)]">
      <xsl:element name="{$el2}">
          <xsl:for-each select="?(3 to array:size(current()))">
              <xsl:attribute name="{subsequence($column-names, position() + 2, 1)}" select="."/>
          </xsl:for-each>
      </xsl:element>
  </xsl:template>
  
</xsl:stylesheet>

当我从你的问题中复制输入样本时,它似乎不包含制表符,所以我改为用空格标记。