您可以使用unparsed-textor (在自 2017 年以来由 Saxon 9.8 及更高版本支持的 XSLT 3 中)unparsed-text-lines处理非 XML 文本文件,就像您似乎拥有的那样,然后您拥有tokenize函数加上xsl:analyze-string元素或在 XSLT 3analyze-string中处理和构造函数您的制表符将数据分隔成您可以提供给的东西xsl:for-each-group,即 XSLT 3 中的一些 XML 或一些数组和字符串序列的混合。
XSLT 2 和 3 中的分组包含在https://stackoverflow.com/tags/xslt-grouping/info中。
下面是一个使用 XSLT 3 的示例,并for-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>
当我从您的问题中复制输入样本时,它似乎不包含制表符,所以我改为使用空格进行标记。