我不是开发人员,但是我在技术行业工作,并且具有xslt的基本知识。 在下面的情况下,我将非常感谢您的帮助。也许一旦有了一个例子,我就可以推断出其他用例。
在csv中,我具有以下列: 名称 位置 工作1 工作2 职位3
工作1具有其他属性,例如开始时间,结束时间和薪酬 工作2有轮班,奖金 职位3有销售,操作
csv中的示例值:
Name, Location,Job_Type,Start_time, End_time,Pay, Shift, Bonus,Sales, Ops
john, london,Job_1,800,1900,400, , , , ,
john, london,Job_2, , , ,evening,20000, , ,
john, london,Job_3, , , , , , 200,500
如何确保csv中的这3个单独的行可以转换为一个xml结构:
<name>john</name>
<location>london</location>
<Job_1>
<Start_time>800</Start_time>
<End_time>1900</End_time>
<Pay>400</Pay>
</Job_1>
<Job_2>
<Shift>evening</Shift>
<Bonus>20000</Bonus>
</Job_2>
<Job_3>
<Sales>200</Sales>
<Ops>500</Ops>
</Job_3>
我当时正在考虑设置一个变量,该变量首先是名称和位置。 然后为每个做一个。不知道如果每个元素的名称都是this.name,我将如何创建一个语句。
我非常感谢您的帮助。
答案 0 :(得分:0)
使用XSLT 3(受开源Saxon 9.8和更高版本的HE软件以及Altova 2017和更高版本的支持),您可以使用CSV将输入字符串分解为一系列字符串数组,然后在第一个字符串数组中进行分组数组项如下:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:array="http://www.w3.org/2005/xpath-functions/array"
exclude-result-prefixes="xs array"
version="3.0">
<xsl:param name="csv-input" as="xs:string">Name, Location,Job_Type,Start_time, End_time,Pay, Shift, Bonus,Sales, Ops
john, london,Job_1,800,1900,400, , , , ,
john, london,Job_2, , , ,evening,20000, , ,
john, london,Job_3, , , , , , 200,500</xsl:param>
<xsl:param name="lines" as="xs:string*" select="tokenize($csv-input, '\r?\n')"/>
<xsl:param name="headers" as="xs:string*" select="tokenize(head($lines), '\s*,\s*')"/>
<xsl:param name="data" as="array(xs:string)*" select="tail($lines)!array{ tokenize(., '\s*,\s*') }"/>
<xsl:output method="xml" indent="yes" />
<xsl:template match="/" name="xsl:initial-template" expand-text="yes">
<root>
<xsl:for-each-group select="$data" group-by=".(1)">
<record>
<xsl:for-each select="subsequence($headers, 1, 2)">
<xsl:element name="{.}">{head(current-group())(position())}</xsl:element>
</xsl:for-each>
<xsl:for-each select="current-group()">
<xsl:element name="{.(3)}">
<xsl:variable name="values" select="."/>
<xsl:for-each select="(4 to count($headers))">
<xsl:if test="normalize-space($values(position() + 3))">
<xsl:element name="{$headers[current()]}">{$values(position() + 3)}</xsl:element>
</xsl:if>
</xsl:for-each>
</xsl:element>
</xsl:for-each>
</record>
</xsl:for-each-group>
</root>
</xsl:template>
</xsl:stylesheet>
https://xsltfiddle.liberty-development.net/3NJ38Zn/2
对于示例的自包含性,其中的CSV数据作为字符串参数传入,但是您当然可以使用<xsl:param name="csv-input" as="xs:string" select="unparsed-text('file.csv')"/>
来从CSV文件中加载数据。
当然,XSLT 3并不是必需的,而使用XSLT 2,通常的方法是将CSV转换为XML,然后根据需要进行分组。