问题
<?xml version="1.0" encoding="UTF-8"?>
<Root>
<Destination>acme.com</Destination>
<Record>
<FirstField length="10">AAAA</FirstField>
<SecondField length="15">BBBB</SecondField>
<SubRecord>
<ThirdField length="20">CCCC</ThirdField>
<FourthField length="8">DDDD</FourthField>
</SubRecord>
</Record>
</Root>
Hi, I have a requirement to take this xml example where the elements inside the node will be dynamic & can be several layers deep, and create a fixed length string of text where each value is padded out to the left, using some xslt transformation that can process the xml until complete. The length of each value is defined in the constant length attribute value So the above example after transformation would be (inside the quotes so you can see the full length string:
" AAAA BBBB CCCC DDDD"
I've tried several attempts to create the required xslt to transform this, but haven't had much luck, as I don't know enough about xslt.
Is someone able to provide something that might work. Needs to be in xsl 1.0.
Thanks.
回答1:
Try this:
<xsl:variable name="spaces" select="' '"/>
<xsl:template match="/">
<xsl:text>"</xsl:text>
<xsl:for-each select="//*[@length]">
<xsl:variable name="spacelenght" select="@length - string-length(.)"/>
<xsl:value-of select="concat(substring($spaces, 1, $spacelenght), .)"/>
</xsl:for-each>
<xsl:text>"</xsl:text>
</xsl:template>
Output
" AAAA BBBB CCCC DDDD"
See transformation at https://xsltfiddle.liberty-development.net/6q1S8AC
For your updated question
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="1.0">
<xsl:output method="text"/>
<xsl:variable name="spaces" select="' '"/>
<xsl:template match="/">
<xsl:text>"</xsl:text>
<xsl:apply-templates/>
<xsl:text>"</xsl:text>
</xsl:template>
<xsl:template match="node()" priority="-1">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="*[@Occurs]">
<xsl:variable name="data">
<xsl:apply-templates/>
</xsl:variable>
<xsl:call-template name="copy">
<xsl:with-param name="data" select="$data"/>
<xsl:with-param name="seq" select="0"/>
<xsl:with-param name="lastseq" select="number(@Occurs)"/>
</xsl:call-template>
</xsl:template>
<xsl:template name="copy">
<xsl:param name="data"/>
<xsl:param name="seq"/>
<xsl:param name="lastseq"/>
<xsl:copy-of select="$data"></xsl:copy-of>
<xsl:if test="$seq < $lastseq">
<xsl:call-template name="copy">
<xsl:with-param name="data" select="$data"/>
<xsl:with-param name="seq" select="$seq + 1"/>
<xsl:with-param name="lastseq" select="$lastseq"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
<xsl:template match="*[@length]">
<xsl:variable name="spacelenght" select="@length - string-length(.)"/>
<xsl:value-of select="concat(substring($spaces, 1, $spacelenght), .)"/>
</xsl:template>
</xsl:stylesheet>
Output
" AAAA BBBB CCCC DDDD CCCC DDDD CCCC DDDD CCCC DDDD CCCC DDDD CCCC DDDD CCCC DDDD CCCC DDDD CCCC DDDD CCCC DDDD"
See Transformation at https://xsltfiddle.liberty-development.net/6q1S8AC/2
来源:https://stackoverflow.com/questions/64274662/how-can-i-transform-some-xml-into-a-fixed-length-string-using-element-attributes