如何使用XSlt将XML转换为格式化文本文件

时间:2010-12-03 17:49:39

标签: xml xslt

我有XML文件,如下所示:

<Report>
<Total>
    <RecordValues>
        <Record>
        <FieldValue fieldName="index"       fieldValue="1" />
        <FieldValue fieldName="version"     fieldValue="100" />
        <FieldValue fieldName="user"        fieldValue="tester" />
        <FieldValue fieldName="date_modified"   fieldValue="2010-10-18 12:18:12" />
        <FieldValue fieldName="object_name"     fieldValue="Menu" />
        <FieldValue fieldName="permission"  fieldValue="Permission X" />
        </Record>
        <Record>
        <FieldValue fieldName="index"       fieldValue="2" />
        <FieldValue fieldName="version"     fieldValue="100" />
        <FieldValue fieldName="user"        fieldValue="user1" />
        <FieldValue fieldName="date_modified"   fieldValue="2010-12-15 12:18:12" />
        <FieldValue fieldName="object_name"     fieldValue="Control" />
        <FieldValue fieldName="permission"  fieldValue="Permission E" />
        </Record>
        <Record>
        <FieldValue fieldName="index"       fieldValue="3" />
        <FieldValue fieldName="version"     fieldValue="15" />
        <FieldValue fieldName="user"        fieldValue="user2" />
        <FieldValue fieldName="date_modified"   fieldValue="2010-10-02 12:18:12" />
        <FieldValue fieldName="object_name"     fieldValue="Run" />
        <FieldValue fieldName="permission"  fieldValue="Permission R" />
        </Record>
    </RecordValues>
</Total>

我必须将它与XSLT一起转换为格式化文本文件:

1 100  101810
tester  Menu       Permission X
2 100  121510
user1   Control    Permission E
3 15   100210
user2   Run        Permission R 

必须使用唯一的 fieldValue 属性,并且文本文件中的所有字段都具有固定长度。 请帮我。 感谢。

2 个答案:

答案 0 :(得分:5)

此样式表:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:m="map">
    <xsl:output method="text"/>
    <xsl:strip-space elements="*"/>
    <xsl:variable name="vPadding"
         select="'             &#xA;                               '"/>
    <m:m n="index" p="1"/>
    <m:m n="version" p="3"/>
    <m:m n="user" p="15"/>
    <m:m n="date_modified" p="8"/>
    <m:m n="object_name" p="23"/>
    <m:m n="permission" p="34"/>
    <xsl:template match="Record">
        <xsl:apply-templates select="*[1]"/>
    </xsl:template>
    <xsl:template match="FieldValue">
        <xsl:param name="pOutput" select="$vPadding"/>
        <xsl:variable name="vValue">
            <xsl:apply-templates select="@fieldValue"/>
        </xsl:variable>
        <xsl:variable name="vPos"
                      select="document('')/*/m:m
                                 [@n=current()/@fieldName]/@p"/>
        <xsl:variable name="vOutput"
             select="concat(substring($pOutput,1,$vPos -1),
                            $vValue,
                            substring($pOutput,$vPos+string-length($vValue)))"/>
        <xsl:variable name="vNext" select="following-sibling::*[1]"/>
        <xsl:apply-templates select="$vNext">
            <xsl:with-param name="pOutput" select="$vOutput"/>
        </xsl:apply-templates>
        <xsl:if test="not($vNext)">
            <xsl:value-of select="concat($vOutput,'&#xA;')"/>
        </xsl:if>
    </xsl:template>
    <xsl:template match="@*[../@fieldName='date_modified']">
        <xsl:value-of select="concat(substring(translate(.,'-',''),5,4),
                                     substring(.,3,2))"/>
    </xsl:template>
</xsl:stylesheet>

输出:

1 100  101810
tester  Menu       Permission X
2 100  121510
user1   Control    Permission E
3 15   100210
user2   Run        Permission R

注意:细粒度遍历,填充掩码,带值起始位置的内联映射。

编辑:剥离空间以防万一...

答案 1 :(得分:0)

亚历杭德罗,我测试了你的解决方案。它产生了正确的结果。我在这里看到的唯一问题是第一行不是从文件的开头开始的,并且每两个记录后面都有一个空行。这个文件应该格式化。 结果如下:

        1 100  101810
tester  Menu       Permission X

        2 100  121510
user1   Control    Permission E

        3 15   100210
user2   Run        Permission R

再次感谢您的回复。