 |
| XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead. |
Welcome to the p2p.wrox.com Forums.
You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
|
|
|
|

October 11th, 2017, 11:09 AM
|
|
Authorized User
|
|
Join Date: Nov 2016
Posts: 15
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Split value and insert some character value in particular node values
Hi,
I need your help,
Input:
<root>
<Para0 id="335-100" refid="[335-100]">
<con>Corrections Act 1986 </con>
<sec>Pt 9E, 30G, 30H, 30I, ss 47M, 79H, 104ZC, 104ZD</sec>
</Para0>
</root>
Requited output:
<para0>
<sec>Pt 9E, Pt 30G, Pt 30H, Pt 30I, ss 47M, ss 79H, ss 104ZC, ss 104ZD</sec>
</para0>
This is my code:
<?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="2.0">
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Para0">
<xsl:for-each select="//sec">
<sec>
<xsl:for-each select="tokenize(.,',')">
<xsl:variable name="ddd">
<xsl:choose>
<xsl:when test="matches(.,'\s+[A-z]+\s+')">
<xsl:message select="."></xsl:message>
<xsl:analyze-string select="current()" regex="\s+([A-z]+)\s+">
<xsl:matching-substring>
<xsl:value-of select="regex-group(1)"/>
</xsl:matching-substring>
</xsl:analyze-string>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="substring-before(.,' ')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:message select="$ddd"></xsl:message>
<xsl:value-of select="concat($ddd, .)"/><xsl:text>, </xsl:text>
</xsl:for-each>
</sec>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
My output:
<root>
<sec>PtPt 9E, 30G, 30H, 30I, ss ss 47M, 79H, 104ZC, 104ZD, </sec>
</root>
Thanks,
Bharathi
|
|

October 11th, 2017, 11:33 AM
|
|
Friend of Wrox
|
|
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
|
|
If you use Saxon 9.8 then I think you can solve that with XSLT 3.0 and for-each-group group-starting-with:
Code:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math" exclude-result-prefixes="xs math"
version="3.0">
<xsl:template match="sec">
<xsl:copy>
<xsl:value-of separator=", ">
<xsl:for-each-group select="tokenize(., '\s*,\s*')"
group-starting-with=".[. instance of xs:string and matches(., '^[a-z]+', 'i')]">
<xsl:sequence
select="., tail(current-group()) ! (replace(current-group()[1], '[0-9].*$', '') || .)"
/>
</xsl:for-each-group>
</xsl:value-of>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Result for input
Code:
<sec>Pt 9E, 30G, 30H, 30I, ss 47M, 79H, 104ZC, 104ZD</sec>
is
Code:
<sec>Pt 9E, Pt 30G, Pt 30H, Pt 30I, ss 47M, ss 79H, ss 104ZC, ss 104ZD</sec>
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
|
|

October 11th, 2017, 11:49 PM
|
|
Authorized User
|
|
Join Date: Nov 2016
Posts: 15
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Thank you very much Martin.. Actually i have used in XSLT 2.0. Is possible to done in 2.0.
|
|

October 12th, 2017, 04:22 AM
|
|
Friend of Wrox
|
|
Join Date: Nov 2007
Posts: 1,243
Thanks: 0
Thanked 245 Times in 244 Posts
|
|
With XSLT 2.0 you can use the same grouping approach but not directly on string values, instead you first have to convert the data to XML and then you can use the for-each-group group-starting-with on the XML:
Code:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math" exclude-result-prefixes="xs math"
version="2.0">
<xsl:template match="sec">
<xsl:copy>
<xsl:variable name="tokens" as="element(token)*">
<xsl:for-each select="tokenize(., '\s*,\s*')">
<token>
<xsl:value-of select="."/>
</token>
</xsl:for-each>
</xsl:variable>
<xsl:value-of separator=", ">
<xsl:for-each-group select="$tokens"
group-starting-with="token[matches(., '^[a-z]+', 'i')]">
<xsl:sequence
select="string(), for $t in current-group()[position() gt 1]
return concat(replace(current-group()[1], '[0-9].*$', ''), $t)"
/>
</xsl:for-each-group>
</xsl:value-of>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
__________________
Martin Honnen
Microsoft MVP (XML, Data Platform Development) 2005/04 - 2013/03
My blog
|
|

October 13th, 2017, 01:05 AM
|
|
Authorized User
|
|
Join Date: Nov 2016
Posts: 15
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Thank you very much Martin. It is very useful and I learnt new concept from this one. once again thank you so much..  
|
|
 |