473,377 Members | 1,153 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,377 software developers and data experts.

File formating with XSLT

Hello,
>From the source file, I need to create with XSLT a result file with
the following constraints:

source:
<Source>
<Item>AAA</Item>
<Item>BBBBBBBBBBB</Item>
<Item>CCCCCCCCC</Item>
<Item>DDDDDDDDDDDDDDD</Item>
<Item>EEEEE</Item>
<Item>FF</Item>
<Item>G</Item>
</Source>

result: (text file with line length = 16, with spaces)
AAA BBBBBBBBBBB
CCCCCCCCC
DDDDDDDDDDDDDDD
EEEEE FF G

Each line of the output file is composed of Item texts separated by
one space.
If by adding a new item text on the line we have more than 16
characters then pad the current line with spaces and copy the item
text to a new line.

I do not know if it is possible to do that in XSLT.
Thanks for your help.

Olivier

Jan 31 '07 #1
10 2288
On 31 Jan, 14:02, "olivier.scalb...@algosyn.com"
<olivier.scalb...@algosyn.comwrote:
I do not know if it is possible to do that in XSLT.
Dead easy, just add <xsl:output method="text" /to the top of your
stylesheet.
http://www.w3.org/TR/xslt#section-Text-Output-Method

Jan 31 '07 #2
Use the FXSL stylesheet file:

strSplit-to-Lines.xsl

And modify it appropriately for your case.

This transformation (just modified the above stylesheet, calling the
template with lineLength=16):

<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://fxsl.sf.net/"
xmlns:str-split2lines-func="f:str-split2lines-func"
exclude-result-prefixes="f str-split2lines-func"
>
<xsl:import href="str-foldl.xsl"/>

<!-- to be applied on text.xml -->

<str-split2lines-func:str-split2lines-func/>

<xsl:output indent="yes" omit-xml-declaration="yes"/>

<xsl:template match="/">
<xsl:call-template name="str-split-to-lines">
<xsl:with-param name="pStr"
select="concat(normalize-space(/), ' ')"/>
<xsl:with-param name="pLineLength" select="16"/>
<xsl:with-param name="pDelimiters" select="' '"/>
</xsl:call-template>
</xsl:template>

<xsl:template name="str-split-to-lines">
<xsl:param name="pStr"/>
<xsl:param name="pLineLength" select="60"/>
<xsl:param name="pDelimiters" select="' '"/>

<xsl:variable name="vsplit2linesFun"
select="document('')/*/str-split2lines-func:*[1]"/>

<xsl:variable name="vrtfParams">
<delimiters><xsl:value-of select="$pDelimiters"/></delimiters>
<lineLength><xsl:copy-of select="$pLineLength"/></lineLength>
</xsl:variable>

<xsl:variable name="vResult">
<xsl:call-template name="str-foldl">
<xsl:with-param name="pFunc" select="$vsplit2linesFun"/>
<xsl:with-param name="pStr" select="$pStr"/>
<xsl:with-param name="pA0" select="$vrtfParams"/>
</xsl:call-template>
</xsl:variable>

<xsl:for-each select="$vResult/line">
<xsl:for-each select="word">
<xsl:value-of select="concat(., ' ')"/>
</xsl:for-each>
<xsl:value-of select="' '"/>
</xsl:for-each>
</xsl:template>

<xsl:template match="str-split2lines-func:*" mode="f:FXSL">
<xsl:param name="arg1" select="/.."/>
<xsl:param name="arg2"/>

<xsl:copy-of select="$arg1/*[position() &lt; 3]"/>
<xsl:copy-of select="$arg1/line[position() != last()]"/>

<xsl:choose>
<xsl:when test="contains($arg1/*[1], $arg2)">
<xsl:if test="string($arg1/word)">
<xsl:call-template name="fillLine">
<xsl:with-param name="pLine" select="$arg1/line[last()]"/>
<xsl:with-param name="pWord" select="$arg1/word"/>
<xsl:with-param name="pLineLength" select="$arg1/*[2]"/>
</xsl:call-template>
</xsl:if>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="$arg1/line[last()]"/>
<word><xsl:value-of select="concat($arg1/word, $arg2)"/></word>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

<!-- Test if the new word fits into the last line -->
<xsl:template name="fillLine">
<xsl:param name="pLine" select="/.."/>
<xsl:param name="pWord" select="/.."/>
<xsl:param name="pLineLength" />

<xsl:variable name="vnWordsInLine" select="count($pLine/word)"/>
<xsl:variable name="vLineLength" select="string-length($pLine) +
$vnWordsInLine"/>
<xsl:choose>
<xsl:when test="not($vLineLength + string-length($pWord) >
$pLineLength)">
<line>
<xsl:copy-of select="$pLine/*"/>
<xsl:copy-of select="$pWord"/>
</line>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="$pLine"/>
<line>
<xsl:copy-of select="$pWord"/>
</line>
<word/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>

</xsl:stylesheet>

Produces the wanted results (the lines are truncated but padding each line
to 16 chars width is left as an exercise to the reader :o) )

AAA BBBBBBBBBBB
CCCCCCCCC
DDDDDDDDDDDDDDD
EEEEE FF G

Cheers,
Dimitre Novatchev.
<ol**************@algosyn.comwrote in message
news:11**********************@v33g2000cwv.googlegr oups.com...
Hello,
>>From the source file, I need to create with XSLT a result file with
the following constraints:

source:
<Source>
<Item>AAA</Item>
<Item>BBBBBBBBBBB</Item>
<Item>CCCCCCCCC</Item>
<Item>DDDDDDDDDDDDDDD</Item>
<Item>EEEEE</Item>
<Item>FF</Item>
<Item>G</Item>
</Source>

result: (text file with line length = 16, with spaces)
AAA BBBBBBBBBBB
CCCCCCCCC
DDDDDDDDDDDDDDD
EEEEE FF G

Each line of the output file is composed of Item texts separated by
one space.
If by adding a new item text on the line we have more than 16
characters then pad the current line with spaces and copy the item
text to a new line.

I do not know if it is possible to do that in XSLT.
Thanks for your help.

Olivier

Jan 31 '07 #3
Dead easy, just add <xsl:output method="text" /to the top of your
stylesheet.http://www.w3.org/TR/xslt#section-Text-Output-Method
Thanks, but I do not understand your answer. How to limit the line
length to 16 chars ? How to group small item texts in one line ? How
to separate item text with space ?

Jan 31 '07 #4
On Jan 31, 4:02 pm, "olivier.scalb...@algosyn.com"
<olivier.scalb...@algosyn.comwrote:
<Source>
<Item>AAA</Item>
<Item>BBBBBBBBBBB</Item>
<Item>CCCCCCCCC</Item>
<Item>DDDDDDDDDDDDDDD</Item>
<Item>EEEEE</Item>
<Item>FF</Item>
<Item>G</Item>
</Source>

result: (text file with line length = 16, with spaces)
AAA BBBBBBBBBBB
CCCCCCCCC
DDDDDDDDDDDDDDD
EEEEE FF G

Each line of the output file is composed of Item texts
separated by one space.
If by adding a new item text on the line we have more
than 16 characters then pad the current line with spaces
and copy the item text to a new line.

I do not know if it is possible to do that in XSLT.
It certainly is possible, but fairly... perverse. XSLT is
not very good at stuff like that.

Just for the heck of it:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:param name="max-length" select="16"/>
<xsl:param name="pad-with" select="'.'"/>
<xsl:template match="Source">
<xsl:apply-templates select="Item[1]"/>
</xsl:template>
<xsl:template match="Item">
<xsl:param name="cur-position" select="0"/>
<xsl:variable name="cur-length"
select="string-length(.)"/>
<xsl:variable name="new-position">
<xsl:choose>
<xsl:when test="0 = $cur-position">
<xsl:value-of
select="$cur-position + $cur-length"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of
select="$cur-position + $cur-length + 1"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:if
test=
"
($max-length &lt; $cur-length) or
(0 = $cur-length)
">
<xsl:message
terminate="yes">Invalid entity.</xsl:message>
</xsl:if>
<xsl:choose>
<xsl:when test="$new-position &gt; $max-length">
<xsl:call-template name="pad-space">
<xsl:with-param name="position"
select="$cur-position"/>
</xsl:call-template>
<xsl:text>
</xsl:text>
<xsl:value-of select="."/>
<xsl:apply-templates
select="following-sibling::Item[1]">
<xsl:with-param name="cur-position"
select="$cur-length"/>
</xsl:apply-templates>
<xsl:if test="not(following-sibling::Item[1])">
<xsl:call-template name="pad-space">
<xsl:with-param name="position"
select="$cur-position"/>
</xsl:call-template>
<xsl:text>
</xsl:text>
</xsl:if>
</xsl:when>
<xsl:otherwise>
<xsl:if test="0 &lt; $cur-position">
<xsl:value-of select="$pad-with"/>
</xsl:if>
<xsl:value-of select="."/>
<xsl:apply-templates
select="following-sibling::Item[1]">
<xsl:with-param name="cur-position"
select="$new-position"/>
</xsl:apply-templates>
<xsl:if test="not(following-sibling::Item[1])">
<xsl:call-template name="pad-space">
<xsl:with-param name="position"
select="$new-position"/>
</xsl:call-template>
<xsl:text>
</xsl:text>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="pad-space">
<xsl:param name="position"/>
<xsl:variable name="left"
select="$max-length - $position"/>
<xsl:if test="0 &lt; $left">
<xsl:value-of select="$pad-with"/>
<xsl:call-template name="pad-space">
<xsl:with-param name="position"
select="$position + 1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>

Not tested on anything but the sample document provided by
the OP. Note that on large documents it is likely to barf
all over the stack and die horrible death. So I would
strongly advise against deploying it in production
environments without some serious tinkering beforehand
(preferrably the tinkering would involve rewriting the
transformation in a language more suitable for the task).

--
Pavel Lepin

Jan 31 '07 #5
Thank you very much for your help.
As the input source file is also generated by an XSLT transformation,
do you think I can hook your function inside this transformation, and
avoid the intermediary file ?

Olivier

Jan 31 '07 #6
Thanks Pavel!

Jan 31 '07 #7

<ol**************@algosyn.comwrote in message
news:11**********************@a34g2000cwb.googlegr oups.com...
Thank you very much for your help.
As the input source file is also generated by an XSLT transformation,
do you think I can hook your function inside this transformation, and
avoid the intermediary file ?

Olivier
Yes, this is a standard practice.

In XSLT 1.0 use the xxx:node-set() extension to convert the RTF results of
the first transformation to a regular tree.

In XSLT 2.0 this is not necessary.
Cheers,
Dimitre Novatchev
Feb 1 '07 #8
Note that on large documents it is likely to barf
all over the stack and die horrible death. So I would
strongly advise against deploying it in production

Not necessarily. One can use a DVC (Divide and Conquer) approach, which
requires as little as Log2(N) maximum stack depth.
Cheers,
Dimitre Novatchev

<p.*****@ctncorp.comwrote in message
news:11**********************@a34g2000cwb.googlegr oups.com...
On Jan 31, 4:02 pm, "olivier.scalb...@algosyn.com"
<olivier.scalb...@algosyn.comwrote:
><Source>
<Item>AAA</Item>
<Item>BBBBBBBBBBB</Item>
<Item>CCCCCCCCC</Item>
<Item>DDDDDDDDDDDDDDD</Item>
<Item>EEEEE</Item>
<Item>FF</Item>
<Item>G</Item>
</Source>

result: (text file with line length = 16, with spaces)
AAA BBBBBBBBBBB
CCCCCCCCC
DDDDDDDDDDDDDDD
EEEEE FF G

Each line of the output file is composed of Item texts
separated by one space.
If by adding a new item text on the line we have more
than 16 characters then pad the current line with spaces
and copy the item text to a new line.

I do not know if it is possible to do that in XSLT.

It certainly is possible, but fairly... perverse. XSLT is
not very good at stuff like that.

Just for the heck of it:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:param name="max-length" select="16"/>
<xsl:param name="pad-with" select="'.'"/>
<xsl:template match="Source">
<xsl:apply-templates select="Item[1]"/>
</xsl:template>
<xsl:template match="Item">
<xsl:param name="cur-position" select="0"/>
<xsl:variable name="cur-length"
select="string-length(.)"/>
<xsl:variable name="new-position">
<xsl:choose>
<xsl:when test="0 = $cur-position">
<xsl:value-of
select="$cur-position + $cur-length"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of
select="$cur-position + $cur-length + 1"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:if
test=
"
($max-length &lt; $cur-length) or
(0 = $cur-length)
">
<xsl:message
terminate="yes">Invalid entity.</xsl:message>
</xsl:if>
<xsl:choose>
<xsl:when test="$new-position &gt; $max-length">
<xsl:call-template name="pad-space">
<xsl:with-param name="position"
select="$cur-position"/>
</xsl:call-template>
<xsl:text>
</xsl:text>
<xsl:value-of select="."/>
<xsl:apply-templates
select="following-sibling::Item[1]">
<xsl:with-param name="cur-position"
select="$cur-length"/>
</xsl:apply-templates>
<xsl:if test="not(following-sibling::Item[1])">
<xsl:call-template name="pad-space">
<xsl:with-param name="position"
select="$cur-position"/>
</xsl:call-template>
<xsl:text>
</xsl:text>
</xsl:if>
</xsl:when>
<xsl:otherwise>
<xsl:if test="0 &lt; $cur-position">
<xsl:value-of select="$pad-with"/>
</xsl:if>
<xsl:value-of select="."/>
<xsl:apply-templates
select="following-sibling::Item[1]">
<xsl:with-param name="cur-position"
select="$new-position"/>
</xsl:apply-templates>
<xsl:if test="not(following-sibling::Item[1])">
<xsl:call-template name="pad-space">
<xsl:with-param name="position"
select="$new-position"/>
</xsl:call-template>
<xsl:text>
</xsl:text>
</xsl:if>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="pad-space">
<xsl:param name="position"/>
<xsl:variable name="left"
select="$max-length - $position"/>
<xsl:if test="0 &lt; $left">
<xsl:value-of select="$pad-with"/>
<xsl:call-template name="pad-space">
<xsl:with-param name="position"
select="$position + 1"/>
</xsl:call-template>
</xsl:if>
</xsl:template>
</xsl:stylesheet>

Not tested on anything but the sample document provided by
the OP. Note that on large documents it is likely to barf
all over the stack and die horrible death. So I would
strongly advise against deploying it in production
environments without some serious tinkering beforehand
(preferrably the tinkering would involve rewriting the
transformation in a language more suitable for the task).

--
Pavel Lepin

Feb 1 '07 #9
On Feb 1, 3:50 am, "Dimitre Novatchev"
<dimit...@tpg.com.auwrote:
Note that on large documents it is likely to barf
all over the stack and die horrible death. So I would
strongly advise against deploying it in production

Not necessarily.
I was talking specifically about the implementation I
provided.
One can use a DVC (Divide and Conquer) approach, which
requires as little as Log2(N) maximum stack depth.
Wouldn't there be certain problems with implementing DVC
for this task? The position of every Item depends on all
previous Items after all. Tail recursion would seem like a
better approach to me, but I not sure there are any XSLT
processors to date that can optimize it away. (Are there,
by the way?)

--
Pavel Lepin

Feb 1 '07 #10
Wouldn't there be certain problems with implementing DVC
for this task? The position of every Item depends on all
previous Items after all.
No, there's usually no problem with this. Look how the DVC version of
foldl() is implemented in FXSL:
<xsl:stylesheet version="2.0"
xmlns:f="http://fxsl.sf.net/"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
exclude-result-prefixes="f">

<xsl:import href="func-apply.xsl"/>
<xsl:import href="func-drop.xsl"/>

<xsl:function name="f:foldl">
<xsl:param name="pFunc" as="element()"/>
<xsl:param name="pA0"/>
<xsl:param name="pList" as="item()*"/>

<xsl:sequence select=
"if(empty($pList))
then
$pA0
else
for $vcntList in count($pList) return
if($vcntList = 1)
then
f:apply($pFunc, $pA0, $pList[1])
else
for $vHalfLen in ($vcntList idiv 2) return
f:foldl($pFunc,
f:foldl($pFunc, $pA0, $pList[position() le
$vHalfLen]),
f:drop($vHalfLen, $pList)
)"/>

</xsl:function>

</xsl:stylesheet>
Something similar is done in FXSL 1.x (For XSLT 1.0).
Tail recursion would seem like a
better approach to me, but I not sure there are any XSLT
processors to date that can optimize it away.
Some do (Net XslCompiledTransform, Saxon6.5, JD are all very good at
optimizing TR), some don't, and all 3 XSLT 2.0 processors have some
difficulties -- see more on this here:

http://dnovatchev.spaces.live.com/Blog/cns!44B0A32C2CCF7488!345.entry

Cheers,
Dimitre Novatchev

<p.*****@ctncorp.comwrote in message
news:11*********************@v45g2000cwv.googlegro ups.com...
On Feb 1, 3:50 am, "Dimitre Novatchev"
<dimit...@tpg.com.auwrote:
Note that on large documents it is likely to barf
all over the stack and die horrible death. So I would
strongly advise against deploying it in production

Not necessarily.

I was talking specifically about the implementation I
provided.
>One can use a DVC (Divide and Conquer) approach, which
requires as little as Log2(N) maximum stack depth.

Wouldn't there be certain problems with implementing DVC
for this task? The position of every Item depends on all
previous Items after all. Tail recursion would seem like a
better approach to me, but I not sure there are any XSLT
processors to date that can optimize it away. (Are there,
by the way?)

--
Pavel Lepin

Feb 1 '07 #11

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Fredrik Henricsson | last post by:
Hey, I'm building an ontology in Protégé and I want to transform parts of it (e.g. the instances) to HTML with XSL. When I was transforming another file with 'simple' XML-tags like <author> before,...
2
by: Marcelo | last post by:
Hi Guys, I have the following question. I have a Xerox DJDE File that I want to convert to PDF.
7
by: Cerebrus99 | last post by:
Hi all, I am confused about how to sort an XML file. I mean how to *actually* sort the data in the physical file, not how to display sorted data. I am using a large XML file as a back-end...
4
by: Philipp Reiss | last post by:
Hello group, I'm new in this topic and I run into problems where google can't help me. I have a XML-file, wich is bound to a XSLT-file, and this works fine in a browser. How do I show the same...
6
by: Lenny Wintfeld | last post by:
Hi I'm attempting additions/changes to a Java program that (among other things) uses XSLT to transform a large (96 Mb) XML file. It runs fine on small XML files but generates OutOfMemory...
1
by: Max Evans | last post by:
I have a XML file, which contains itemid-elements, e.g.: <itemid>3</itemid> <itemid>12</itemid> Now I want to convert these IDs to the corresponding name via XSLT. I thought I could do it this...
11
by: A.M | last post by:
Hi, I found print much more flexible that write method. Can I use print instead of file.write method? Thank you,
3
by: J055 | last post by:
Hi I'd like to get a populated datatable, create an in memory xml document (file shouldn't be more than a couple of meg), load an XSLT file, do a transform and stream it to a browser. What am I...
2
by: saritha2008 | last post by:
Hi, As part of transforming one form of xml to another form, i need to do the below mentioned transformation: My Input XML: <rss> <channel> <item> <assignee...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.