[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: Split one line to multiple lines

Subject: Re: Split one line to multiple lines
From: "Wendell Piez wapiez@xxxxxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Tue, 14 Oct 2014 14:10:19 -0000
Re:  Split one line to multiple lines
Sudeshna,

Um, so, something like this.

<xsl:template match="Line">
    <xsl:call-template name="make-lines"/>
  </xsl:template>

 <xsl:template name="make-lines">
    <xsl:param name="line" select="."/>
    <xsl:param name="product-str" select="string(Product)"/>
    <xsl:variable name="prd" select="substring-before($product-str,';')"/>
    <xsl:choose>
      <xsl:when test="contains($product-str,';')">
        <Line>
          <xsl:copy-of select="$line/LineId"/>
          <Product>
            <xsl:value-of select="$prd"/>
          </Product>
          <xsl:copy-of select="$line/Amount"/>
        </Line>
        <xsl:call-template name="make-lines">
          <xsl:with-param name="line" select="$line"/>
          <xsl:with-param name="product-str"
select="substring-after($product-str,concat($prd,';'))"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:variable name="prd" select="$product-str"/>
        <xsl:if test="normalize-space($prd)">
        <Line>
          <xsl:copy-of select="$line/LineId"/>
          <Product>
            <xsl:value-of select="$prd"/>
          </Product>
          <xsl:copy-of select="$line/Amount"/>
        </Line>
        </xsl:if>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

No pipelining is necessary here.

I apologize if I sounded cross earlier. I do wish, however, that
XSL-List were a bit more reflective and less of a "code-writing
service". Earlier in this thread Graydon provided you - freely
offering his service - a perfectly elegant solution and only when you
came back and said "XSLT 1.0 only" was it even clear what the problem
actually was. :-(

XSLT 1.0 is definitely in scope for this list, however (as I
understand it), and I don't wish to discourage questions about it.
They just need to be identified as such up front.

Cheers, Wendell



On Sat, Oct 11, 2014 at 1:53 PM, Wendell Piez wapiez@xxxxxxxxxxxxxxx
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:
> Hi,
>
> Take a look at http://www.dpawson.co.uk/xsl/sect2/N7240.html
>
> Or read the section on string processing in Jeni Tennison's XSLT and
> XPath On the Edge (isbn 0764547763). If you are stuck with XSLT 1.0,
> this is an essential in your library.
>
> Generally speaking, in XSLT 1.0 one can process a string as a
> parameter through a recursive template, which works by "chopping" the
> string until it's gone.
>
> Partly it's cumbersome because you are limited to just a few
> string-manipulation functions. You have to operate on the strings
> using substring-before(), starts-with() and a few others.
>
> Since, in XSLT 1.0, one cannot pipeline (unless one can, because
> making result trees readable is a common extension in 1.0 processors),
> this is especially difficult to demonstrate. A decent solution must
> also be highly tuned to your own specific and particular requirements.
> It is also likely to be relatively verbose, even for XSLT. Code like
> this makes many people impatient especially when they know it is not
> necessary.
>
> Arguably a better solution than pure XSLT 1.0 in one pass: hack the
> tags themselves by hand (Perl, sed, awk) as a pre-process.
>
> If you at least have a node-set() extension function, this is slightly
> less crazy in XSLT 1.0.
>
> Good luck, Wendell
>
>
>
>
>
>
>
> On Fri, Oct 10, 2014 at 11:06 PM, sudheshna iyer
> sudheshnaiyer@xxxxxxxxx <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
> wrote:
>> I am using oracle bpel transformation and it doesn't support xslt2.0. Can I
>> have the solution in xslt 1.0?
>>
>> Thank you very much for your help.
>>
>>
>>
>>
>> On Thursday, October 9, 2014 5:02 PM, "sudheshna iyer
>> sudheshnaiyer@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:
>>
>>
>> Thank you very much, Graydon. Let me try that over.
>>
>>
>>
>>
>> On Thursday, October 9, 2014 4:23 PM, "Graydon graydon@xxxxxxxxx"
>> <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:
>>
>>
>> On Thu, Oct 09, 2014 at 07:59:09PM -0000, sudheshna iyer
>> sudheshnaiyer@xxxxxxxxx scripsit:
>>> I want to split the values in "Product" to multiple lines. For eg: for
>>> LineId = 222, there are 3 values (BBB;CCC;DDD;). So I need to create 3 lines
>>> along with the first line. How can I do that?
>>> Eg:
>>> <ns1:Lines>
>>> <ns1:Line>
>>> <ns1:LineId>111</ns1:LineId>
>>> <ns1:Product>AA</ns1:Product>
>>> <ns1:Amount>100</ns1:Amount>
>>> </ns1:Line>
>>> <ns1:Line>
>>> <ns1:LineId>222</ns1:LineId>
>>> <ns1:Product>BBB;CCC;DDD;</ns1:Product>
>>> <ns1:Amount>200</ns1:Amount>
>>> </ns1:Line>
>>> </ns1:Lines>
>>>
>>> Output
>>> <ns1:Lines>
>>> <ns1:Line>
>>> <ns1:LineId>111</ns1:LineId>
>>> <ns1:Product>AAA</ns1:Product>
>>> <ns1:Amount>100</ns1:Amount>
>>> </ns1:Line>
>>> <ns1:Line>
>>> <ns1:LineId>222</ns1:LineId>
>>> <ns1:Product>BBB</ns1:Product>
>>> <ns1:Amount>100</ns1:Amount>
>>> </ns1:Line>
>>> <ns1:Line>
>>> <ns1:LineId>222</ns1:LineId>
>>> <ns1:Product>CCC</ns1:Product>
>>> <ns1:Amount>100</ns1:Amount>
>>> </ns1:Line>
>>> <ns1:Line>
>>> <ns1:LineId>222</ns1:LineId>
>>> <ns1:Product>DDD</ns1:Product>
>>> <ns1:Amount>100</ns1:Amount>
>>> </ns1:Line>
>>> </ns1:Lines>
>>>
>>> I know there is a tokenize function. But how do I copy other values?
>>
>> <xsl:template match="node()|@*">
>>     <xsl:copy>
>>         <xsl:apply-templates select="node()|@*" />
>>     </xsl:copy>
>> </xsl:template>
>>
>> <xsl:template match="ns1:Line">
>>     <xsl:variable name="original" select="." />
>>     <xsl:for-each
>> select="tokenize(normalize-space(ns1:Product),';\p{Zs}*')[normalize-space()]">
>>         <ns1:Line>
>>             <xsl:apply-templates select="$original/ns1:LineId" />
>>             <ns1:Product>
>>                 <xsl:value-of select="." />
>>             </ns1:Product>
>>             <xsl:apply-templates select="$original/ns1:Amount" />
>>         </ns1:Line>
>>     </xsl:for-each>
>> </xsl:template>
>>
>>
>> You notice that what you're doing is relative to the ns1:Line elements, and
>> that while you could select only those ns1:Line elements were you need to
>> split
>> things
>>
>> <xsl:template match="ns1:Line[matches(ns1:Product,';')]">
>>
>> you don't need to; tokenizing where there aren't any semi-colons just
>> returns
>> whatever was there.
>>
>> You watch out for the trailing semi-colons by excluding the null string from
>> the sequence produced by tokenize -- that's what [normalize-space()] does --
>> and you use a variable to hang on to the original element context, which you
>> lose inside the for-each.
>>
>> -- Graydon
>>
>>
>>
>> XSL-List info and archive
>> EasyUnsubscribe (by email)
>>
>>
>> XSL-List info and archive
>> EasyUnsubscribe (by email)
>
>
>
> --
> Wendell Piez | http://www.wendellpiez.com
> XML | XSLT | electronic publishing
> Eat Your Vegetables
> _____oo_________o_o___ooooo____ooooooo_^
> 



-- 
Wendell Piez | http://www.wendellpiez.com
XML | XSLT | electronic publishing
Eat Your Vegetables
_____oo_________o_o___ooooo____ooooooo_^

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.