开发者

How to convert XML into formated text file whith XSlt

I have XML file which is looks like:

<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"     fi开发者_如何学GoeldValue="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>

I have to convert it with XSLT into formated text file:

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

The only fieldValue attribute must be used and all fields in the text file have fixed length. Please help me. Thanks.


This stylesheet:

<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>

Output:

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

Note: Fine grained traversal, a padding mask, inline map with value starting position.

EDIT: Strip space just in case...


Alejandro, I tested your solution. Its produced correct result. The only problem I see here is that the first line doesn't started from the beginning of the file and there is an empty line after every two records. This file should well formatted. Here is the result:

        1 100  101810
tester  Menu       Permission X

        2 100  121510
user1   Control    Permission E

        3 15   100210
user2   Run        Permission R

Thanks again for your respond.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜