具有各种长度的列数据的固定格式输出
Fixed Format Output w/ Column Data of Various Lengths
XSLT 版本 1.0
来源 XML
<Vehicle>
<Parts>
<Part SN="1234567" PartNumber="223232" Build="2W345" Manuf="K3E4" Mater="12312">
<Inspections ManufI="K3F4"/>
<Recalls ID="1223-4" Status="02"/>
<Recalls ID="1987-9" Status="07" />
<Recalls ID="1211-10" Status="17" />
<Recalls ID="4545-1" Status="07" />
<Recalls ID="2291-7" Status="01" />
<Recalls ID="2322-4" Status="04" />
</Part>
<Part SN="1255" PartNumber="87666" Build="3ED55" Manuf="98772" Mater="8YT76">
<Inspections />
<Recalls ID="5676-4" Status="01"/>
<Recalls ID="13347-9" Status="01" />
<Part> SN="1256" PartNumber="76554" Build="3R453" Manuf="7U7Yt"
Mater="9I123">
<Inspections />
<Recalls />
</Part>
</Part>
</Parts>
</Vehicle>
我正在尝试生成以下固定格式文件。 'recalls' 列表只是序列号 (SN) 的召回列表,与其左侧的类型和代码列无关。如示例所示,它可能比类型和代码列表更长或更短。
SN PartNumber Type Code Recall Status
1234567 223232 Manuf K3E4 1223-4 02
ManufI K3F4 1987-9 07
Mater 12312 1211-10 17
Build 2W345 4545-1 07
2291-7 01
2322-4 01
1255 87666 Manuf 98772 5676-4 01
Mater 8YT76 13347-9 01
Build 3ED55
1256 76554 Manuf 7U7Yt
Mater 9I123
Build 3R453
这是您可以用作起点的示例。为简单起见,它生成 CSV 输出而不是固定宽度的文件。
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/Vehicle">
<xsl:text>SN, PartNumber, Type, Code, Recall, Status </xsl:text>
<xsl:for-each select="Parts/Part">
<xsl:call-template name="generate-rows">
<xsl:with-param name="types" select="@Manuf | @Build | @Mater | Inspections/@ManufI" />
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:template name="generate-rows">
<xsl:param name="types"/>
<xsl:param name="i" select="1"/>
<!-- part columns -->
<xsl:value-of select="@SN[$i]"/>
<xsl:text>, </xsl:text>
<xsl:value-of select="@PartNumber[$i]"/>
<xsl:text>, </xsl:text>
<!-- type columns -->
<xsl:value-of select="name($types[$i])"/>
<xsl:text>, </xsl:text>
<xsl:value-of select="$types[$i]"/>
<xsl:text>, </xsl:text>
<!-- recall columns -->
<xsl:value-of select="Recalls[$i]/@ID"/>
<xsl:text>, </xsl:text>
<xsl:value-of select="Recalls[$i]/@Status"/>
<xsl:text> </xsl:text>
<!-- recursive call -->
<xsl:if test="$i < count($types) or $i < count(Recalls)">
<xsl:call-template name="generate-rows">
<xsl:with-param name="types" select="$types"/>
<xsl:with-param name="i" select="$i + 1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
应用于您的输入示例,这将产生:
结果
SN, PartNumber, Type, Code, Recall, Status
1234567, 223232, Build, 2W345, 1223-4, 02
, , Manuf, K3E4, 1987-9, 07
, , Mater, 12312, 1211-10, 17
, , ManufI, K3F4, 4545-1, 07
, , , , 2291-7, 01
, , , , 2322-4, 04
1255, 87666, Build, 3ED55, 5676-4, 01
, , Manuf, 98772, 13347-9, 01
, , Mater, 8YT76, ,
对应于:
XSLT 版本 1.0 来源 XML
<Vehicle>
<Parts>
<Part SN="1234567" PartNumber="223232" Build="2W345" Manuf="K3E4" Mater="12312">
<Inspections ManufI="K3F4"/>
<Recalls ID="1223-4" Status="02"/>
<Recalls ID="1987-9" Status="07" />
<Recalls ID="1211-10" Status="17" />
<Recalls ID="4545-1" Status="07" />
<Recalls ID="2291-7" Status="01" />
<Recalls ID="2322-4" Status="04" />
</Part>
<Part SN="1255" PartNumber="87666" Build="3ED55" Manuf="98772" Mater="8YT76">
<Inspections />
<Recalls ID="5676-4" Status="01"/>
<Recalls ID="13347-9" Status="01" />
<Part> SN="1256" PartNumber="76554" Build="3R453" Manuf="7U7Yt"
Mater="9I123">
<Inspections />
<Recalls />
</Part>
</Part>
</Parts>
</Vehicle>
我正在尝试生成以下固定格式文件。 'recalls' 列表只是序列号 (SN) 的召回列表,与其左侧的类型和代码列无关。如示例所示,它可能比类型和代码列表更长或更短。
SN PartNumber Type Code Recall Status
1234567 223232 Manuf K3E4 1223-4 02
ManufI K3F4 1987-9 07
Mater 12312 1211-10 17
Build 2W345 4545-1 07
2291-7 01
2322-4 01
1255 87666 Manuf 98772 5676-4 01
Mater 8YT76 13347-9 01
Build 3ED55
1256 76554 Manuf 7U7Yt
Mater 9I123
Build 3R453
这是您可以用作起点的示例。为简单起见,它生成 CSV 输出而不是固定宽度的文件。
XSLT 1.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="/Vehicle">
<xsl:text>SN, PartNumber, Type, Code, Recall, Status </xsl:text>
<xsl:for-each select="Parts/Part">
<xsl:call-template name="generate-rows">
<xsl:with-param name="types" select="@Manuf | @Build | @Mater | Inspections/@ManufI" />
</xsl:call-template>
</xsl:for-each>
</xsl:template>
<xsl:template name="generate-rows">
<xsl:param name="types"/>
<xsl:param name="i" select="1"/>
<!-- part columns -->
<xsl:value-of select="@SN[$i]"/>
<xsl:text>, </xsl:text>
<xsl:value-of select="@PartNumber[$i]"/>
<xsl:text>, </xsl:text>
<!-- type columns -->
<xsl:value-of select="name($types[$i])"/>
<xsl:text>, </xsl:text>
<xsl:value-of select="$types[$i]"/>
<xsl:text>, </xsl:text>
<!-- recall columns -->
<xsl:value-of select="Recalls[$i]/@ID"/>
<xsl:text>, </xsl:text>
<xsl:value-of select="Recalls[$i]/@Status"/>
<xsl:text> </xsl:text>
<!-- recursive call -->
<xsl:if test="$i < count($types) or $i < count(Recalls)">
<xsl:call-template name="generate-rows">
<xsl:with-param name="types" select="$types"/>
<xsl:with-param name="i" select="$i + 1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>
应用于您的输入示例,这将产生:
结果
SN, PartNumber, Type, Code, Recall, Status
1234567, 223232, Build, 2W345, 1223-4, 02
, , Manuf, K3E4, 1987-9, 07
, , Mater, 12312, 1211-10, 17
, , ManufI, K3F4, 4545-1, 07
, , , , 2291-7, 01
, , , , 2322-4, 04
1255, 87666, Build, 3ED55, 5676-4, 01
, , Manuf, 98772, 13347-9, 01
, , Mater, 8YT76, ,
对应于: