Re: [xsl] Response to G Ken Holman re Question on search and replace in XSL

Subject: Re: [xsl] Response to G Ken Holman re Question on search and replace in XSL
From: "G. Ken Holman" <gkholman@xxxxxxxxxxxxxxxxxxxx>
Date: Tue, 10 Apr 2012 11:22:44 -0400
At 2012-04-10 14:58 +0000, Peterson, Melanie S. wrote:
Thanks so much for your response. This is something I never would've figured out on my own. I've implemented your suggestions, but I'm getting an error message and I'm hoping it's a quick fix. Here's the code I've got:
...
I'm getting an error message on the <xsl:for-each-group> statement: 'xsl:for-each-group' is not a recognized extension element.

This tells me that you are using an XSLT 1.0 processor, so my XSLT 2.0 suggestion is out of bounds for you.


I hope this helps. If this *isn't* a quick fix, *please* let me know and I'll just approach this from a different perspective, i.e., I'll just build an HTML document within the C# code and forget about XSL altogether.

Not at all ... since you've better defined your problem as explicitly having groups of three fields, this can be done very explicitly in XSLT 1.0 as shown below. I've tried to spell it out for you. It is more brute-force than the elegant XSLT 2.0 solution, but it produces the identical output that I got when I wrote the other solution.


Please don't give up on XSLT. It may be seem awkward to new users, but working with an XML-based language will serve you better in the long run than trying to wield XML with non-XML-based languages.

I have the privilege to teach this language around the world to new users and when their comprehension sets in it is wonderful to see how they embrace this way of working with structured markup. Other languages "bolt on" XML support through subroutines and function calls, whereas XML-based languages like XSLT and XQuery have built-in inherent knowledge of working with the information as a structure ... that being XDM and XPath. And using these languages one also manifests the result needed using result markup in with the language constructs.

Good luck in your work with XML. Keeping the faith and using these tools will benefit you in the long run. You won't have to worry about the nuances of XML (e.g. use of Unicode, proper escaping of delimiter sequences and sensitive characters, etc.).

I hope this is helpful.

. . . . . . . . . Ken

t:\ftemp>type melanie1.xml
<?xml version="1.0" encoding="UTF-8"?>
<tests>
<APName>aaa;bbb;ccc</APName>
<APName>aaa;bbb;ccc;ddd;eee;fff</APName>
<APName>aaa;;ccc</APName>
</tests>

t:\ftemp>call xslt melanie1.xml melanie1.xsl
<?xml version="1.0" encoding="utf-8"?>

Input value: "aaa;bbb;ccc"

Processed output:
<tr>
   <td valign="top" width="180"/>
   <td>aaa</td>
   <td>bbb</td>
   <td>ccc</td>
</tr>

Input value: "aaa;bbb;ccc;ddd;eee;fff"

Processed output:
<tr>
   <td valign="top" width="180"/>
   <td>aaa</td>
   <td>bbb</td>
   <td>ccc</td>
</tr>
<tr>
   <td valign="top" width="180"/>
   <td>ddd</td>
   <td>eee</td>
   <td>fff</td>
</tr>

Input value: "aaa;;ccc"

Processed output:
<tr>
   <td valign="top" width="180"/>
   <td>aaa</td>
   <td/>
   <td>ccc</td>
</tr>

t:\ftemp>type melanie1.xsl
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
  version="1.0">

<xsl:output indent="yes"/>

<!--expecting semi-colon-separated fields-->
<xsl:template match="APName">
Input value: "<xsl:value-of select="."/>"

Processed output:
<xsl:call-template name="do-three-columns">
  <!--add terminator to last of the fields; don't rely on separators-->
  <xsl:with-param name="content" select="concat(.,';')"/>
</xsl:call-template>
</xsl:template>

<xsl:template name="do-three-columns">
  <!--groups of three pieces of content, each terminated with a semi-colon-->
  <xsl:param name="content"/>
  <xsl:variable name="first" select="substring-before($content,';')"/>
  <xsl:variable name="first-rest" select="substring-after($content,';')"/>
  <xsl:variable name="second" select="substring-before($first-rest,';')"/>
  <xsl:variable name="second-rest" select="substring-after($first-rest,';')"/>
  <xsl:variable name="third" select="substring-before($second-rest,';')"/>
  <xsl:variable name="third-rest" select="substring-after($second-rest,';')"/>
  <!--each group produces a row-->
  <tr>
    <td valign="top" width="180"></td>
    <!--the members of the group make up the remaining columns-->
    <td>
      <xsl:value-of select="$first"/>
    </td>
    <td>
      <xsl:value-of select="$second"/>
    </td>
    <td>
      <xsl:value-of select="$third"/>
    </td>
  </tr>
  <xsl:if test="$third-rest">
    <!--there are more rows to do with the data that remains-->
    <xsl:call-template name="do-three-columns">
      <xsl:with-param name="content" select="$third-rest"/>
    </xsl:call-template>
  </xsl:if>
</xsl:template>

</xsl:stylesheet>
t:\ftemp>rem Done!


-- Public XSLT, XSL-FO, UBL and code list classes in Europe -- May 2012 Contact us for world-wide XML consulting and instructor-led training Free 5-hour lecture: http://www.CraneSoftwrights.com/links/udemy.htm Crane Softwrights Ltd. http://www.CraneSoftwrights.com/s/ G. Ken Holman mailto:gkholman@xxxxxxxxxxxxxxxxxxxx Google+ profile: https://plus.google.com/116832879756988317389/about Legal business disclaimers: http://www.CraneSoftwrights.com/legal

Current Thread