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="' 
 '"/>
<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,'
')"/>
</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.
精彩评论