我有一个XSLT文件,可以将XML文件转换为制表符分隔的文件。我还在文件中添加了列标题。
是否可以使用 XSLT 以某种方式将标题与列对齐?
这是我的 XSLT 文件:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:wd="wdexample.com" version="1.0">
<xsl:output method="text" encoding="utf-8" media-type="text/plain" />
<xsl:strip-space elements="*" />
<xsl:variable name="newline" select="'
'" />
<xsl:variable name="tab" select="'	'" />
<xsl:template match="/">
FAO
<xsl:value-of select="$tab" />
FAO_REFERENCE_ID
<xsl:value-of select="$tab" />
FAO_TYPE
<xsl:value-of select="$tab" />
COMPANY_OF_FAO_DESCRIPTOR
<xsl:value-of select="$tab" />
COMPANY_OF_FAO_Custom_Worktag_1_ID
<xsl:value-of select="$newline" />
<xsl:for-each select="/wd:Report_Data/wd:Report_Entry">
<xsl:value-of select="substring(concat(wd:FAO, ''), 1)" />
<xsl:value-of select="$tab" />
<xsl:value-of select="substring(concat(wd:FAO_REFERENCE_ID, ''), 1, 8)" />
<xsl:value-of select="$tab" />
<xsl:value-of select="substring(concat(wd:FAO_TYPE, ''), 1)" />
<xsl:value-of select="$tab" />
<xsl:value-of select="substring(concat(wd:COMPANY, ''), 1)" />
<xsl:value-of select="$tab" />
<xsl:value-of select="substring(concat(wd:COMPANY_TYPE, ''), 1)" />
<xsl:value-of select="$tab" />
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
下面是输入 XML。在 XML 文件中,不会始终有每个Report_Entry节点的值。
<?xml version="1.0" encoding="UTF-8"?>
<wd:Report_Data xmlns:wd="wdexample.com">
<wd:Report_Entry>
<wd:FAO>testFAO</wd:FAO>
<wd:FAO_REFERENCE_ID>testRefID</wd:FAO_REFERENCE_ID>
<wd:FAO_TYPE>testType</wd:FAO_TYPE>
<wd:COMPANY>testCompany</wd:COMPANY>
<wd:COMPANY_TYPE>testCompanyType</wd:COMPANY_TYPE>
</wd:Report_Entry>
<wd:Report_Entry>
<wd:FAO>testFAO</wd:FAO>
<wd:FAO_REFERENCE_ID>testRefID<</wd:FAO_REFERENCE_ID>
<wd:FAO_TYPE></wd:FAO_TYPE>
<wd:COMPANY></wd:COMPANY>
<wd:COMPANY_TYPE>testCompanyType</wd:COMPANY_TYPE>
</wd:Report_Entry>
...
</wd:Report_Data>
报表条目节点重复多次。如果您想知道,我有substring(concat())
函数,以防将来必须填充列。
我正在考虑使用填充为列提供与该列标题相同的宽度,以防列没有值。有没有更好的方法可以做到这一点?
只是我的问题的回顾:1)是否可以将列标题与列对齐?2)有没有更好的方法来排列列和标题以保持对齐?
~ no.以字符为单位的制表符大小不是标准。
看起来您的所有数据都是一致的,并且大小变化不大,否则不同行的列之间的定位不一致将与现在的数据和标题之间的定位不一致相同。
结果的目标用途是什么?它会被解析(需要特定的分隔符和结构)还是打印(应该看起来不错并且有对齐的列)?
如果您希望文件看起来漂亮,我建议您使用固定长度的记录文件,通过以下方式实现。
<xsl:template match="/" name="sp-padding">
<xsl:param name="count">0</xsl:param>
<xsl:if test="$count > 0">
<xsl:text> </xsl:text>
<xsl:call-template name="sp-padding">
<xsl:with-param name="count" select="$count - 1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:for-each select="nodesToBeConvertedToRow">
<!-- Col nr: 1 Length: 10-->
<xsl:call-template name="sp-padding">
<xsl:with-param name="count" select="10"/>
</xsl:call-template>
<!-- Col nr: 2 Length: 3-->
<xsl:value-of select="nodeWithText"/>
<xsl:call-template name="sp-padding">
<xsl:with-param name="count" select="3 - string-length(nodeWithText)"/>
</xsl:call-template>
...
<xsl:text> </xsl:text>
</xsl:for-each>
字段数据长度需要小于分配的记录大小,并且存在一些其他限制。它适用于我的情况,因为所有记录长度都大于相应的架构字段大小。
我决定为列标题创建带有足够空格的变量,如下所示:
<xsl:variable name="FAO" select="concat('FAO ', '')" />
<xsl:variable name="FAO1" select="concat('FAO REFERENCE ID', '')" />
然后,我将模板中的列标题显示在每个循环之前。
然后在循环中,我像以前一样输出值,但我使用列标题的长度,如下所示:
<xsl:value-of select="substring(concat(wd:FAO, ' '), 1, string-length($FAO))" /><xsl:value-of select="$tab"/>
<xsl:value-of select="substring(concat(wd:FAO_REFERENCE_ID, ' '), 1, string-length($FAO1))" /><xsl:value-of select="$tab"/>
这有点丑,但在我找到更好的解决方案之前它会起作用。