xsl-list
[Top] [All Lists]

[xsl] Re: Search and Replace to add HTML tags

2009-07-06 10:27:11
Hi,

Thank you again for your explanation. I definitely have a much better
understanding. Your solution worked perfectly!

I am trying to achieve the same result using XSLT-FO. Unfortunately I am
not getting the desired results. What is happening is that the entire
output for the node is displayed in bold instead of the specific words and
then the string is repeated but without the bold, and the urls are not
active hyperlinks.

Here is the code I am using:

XSLT-FO excerpt:

<xsl:template match="Release_Notes_Documentation">
            <xsl:param name="string" select="string(.)"/>
            <fo:table-cell xsl:use-attribute-sets="TableCell">
                  <fo:block xsl:use-attribute-sets="
HyphenateUseZeroWidthSpace">
                        <xsl:analyze-string select="." regex="Before:|
Enhancement:|Informational:|Note:|Now:">
                              <xsl:matching-substring>
                                    <fo:inline xsl:use-attribute-sets="
TextBold">
                                          <xsl:value-of select="."/>
                                    </fo:inline>
                              </xsl:matching-substring>
                              <xsl:non-matching-substring>
                                    <xsl:call-template name="hyperlink"/>
                              </xsl:non-matching-substring>
                        </xsl:analyze-string>
                  </fo:block>
            </fo:table-cell>
      </xsl:template>
      <xsl:template name="hyperlink">
            <xsl:param name="string" select="string(.)"/>
            <xsl:analyze-string select="$string" regex="http://[^ ]+">
                  <xsl:matching-substring>
                        <fo:basic-link xsl:use-attribute-sets="Hyperlink">
                              <xsl:attribute name="external-destination"><
xsl:value-of select="."/></xsl:attribute>
                        </fo:basic-link>
                  </xsl:matching-substring>
                  <xsl:non-matching-substring>
                        <xsl:value-of select="."/>
                  </xsl:non-matching-substring>
            </xsl:analyze-string>
      </xsl:template>


XML excerpt:

   <Row>
   <ReleaseNote>Before: The application did this. Now: The application does
   this. Here is a link: http://myurl.com Note: The application may also do
   this.</ReleaseNote>
   </Row>
   <Row>
   <ReleaseNote>Before: The application did not do this. Now: The
   application does this.</ReleaseNote>
   </Row>


Thanks for your help!
_______________________________
Sharon Goldner Harris
Knowledge Management Evangelist
Ultimate Software Group
704-660-6482

Confidentiality Note: This e-mail message and any attachments to it are
intended only for the named recipients and may contain legally privileged
and/or confidential information. If you are not one of the intended
recipients, do not duplicate or forward this e-mail message.

*********************************************
*****************************************************
From: G. Ken Holman <gkholman(_at_)cranesoftwrights(_dot_)com>
Date: Wed, Jul 1, 2009 at 10:04 AM
Subject: Re: [xsl] Re: Search and Replace to add HTML tags
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com


At 2009-07-01 09:10 -0400, Sharon_Harris(_at_)ultimatesoftware(_dot_)com wrote:
  One more thing I am trying to do within the same node is to search for
  any
  text that starts w/ "http://"; and take that and the text that follows it
  and turn it into an active hyperlink.

Sounds good.  Another role for <xsl:analyze-string/>


  This is the code I was using to
  perform this action and now understand that I need to combine this along
  w/
  the action for searching for specific words and wrapping tags around them
  within the same template definition (ReleaseNote).  Unfortunately, I have
  not been successful and do not understand how to perform 2 different
  search
  and replace functions within the same node.

Indeed ... you need to know that template rules are mutually exclusive and
for every node that arrives only one template gets matched.  Therefore, you
need to approach this a similar way to how you approached the nested
replace functions ... there you were acting on the second replace with the
results of the third, and the first replace with the results of the second.
Now you need to nest the string analysis.


  Here is the original code which obviously does not work as the
  ReleaseNote
  template definition overwrites the changes made from the text template
  definition. But I do not understand how to combine both actions within
  the
  ReleaseNote template definition.

You can take advantage of the template rule you've written, or you could
write the analysis inline.  For my example below, I've re-used what you've
created.  I'm assuming you've parameterized the template in order to take
advantage of it elsewhere ... otherwise your assignment provides no
benefit.

Oh, one thing you missed is that my use of <xsl:copy> was to preserve
<ReleaseNotes> for your example ... since you are now creating pure HTML,
you shouldn't be preserving that input element.

I hope this helps.  You've moved quickly in understanding what needs to be
done.

. . . . . . . . . Ken

p.s. Happy Canada day holiday to all Canadian readers!


t:\>type sharon.xml

<test>
  <Row>
  <ReleaseNote>Before: The application did this. Now: The application does
  this. Here is a link: http://myurl.com Note: The application may also do
  this.</ReleaseNote>
  </Row>
  <Row>
  <ReleaseNote>Before: The application did not do this. Now: The
  application does this.</ReleaseNote>
  </Row>
</test>

t:\>xslt2 sharon.xml sharon.xsl

<?xml version="1.0" encoding="UTF-8"?><test>
  <Row>
  <td><b>Before:</b> The application did this. <b>Now:</b> The application
does
  this. Here is a link: <a href="http://myurl.com"; target="new">
http://myurl.com</a> <b>Note:</b> The application may also do
  this.</td>
  </Row>
  <Row>
  <td><b>Before:</b> The application did not do this. <b>Now:</b> The
  application does this.</td>
  </Row>
</test>
t:\>type sharon.xsl

<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                version="2.0">

<xsl:template match="ReleaseNote">
 <td>

   <xsl:analyze-string select="."
              regex="Before:|Enhancement:|Informational:|Note:|Now:">
     <xsl:matching-substring>
       <b><xsl:value-of select="."/></b>
     </xsl:matching-substring>
     <xsl:non-matching-substring>
       <xsl:call-template name="hyperlink"/>
     </xsl:non-matching-substring>
   </xsl:analyze-string>
 </td>

</xsl:template>

<xsl:template name="hyperlink">
 <xsl:param name="string" select="string(.)"/>
 <xsl:analyze-string select="$string" regex="http://[^ ]+">
   <xsl:matching-substring>
     <a href="{.}" target="new">
       <xsl:value-of select="."/>
     </a>
   </xsl:matching-substring>
   <xsl:non-matching-substring>
     <xsl:value-of select="."/>
   </xsl:non-matching-substring>
 </xsl:analyze-string>
</xsl:template>

<xsl:template match="@*|node()"><!--identity for all other nodes-->
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>

t:\>


--
Possible July/August XSLT/XQuery/XSL-FO training in Oakland/CA/USA
Crane Softwrights Ltd.          http://www.CraneSoftwrights.com/s/
Training tools: Comprehensive interactive XSLT/XPath 1.0/2.0 video
Video lesson:    http://www.youtube.com/watch?v=PrNjJCh7Ppg&fmt=18
Video overview:  http://www.youtube.com/watch?v=VTiodiij6gE&fmt=18
G. Ken Holman                 mailto:gkholman(_at_)CraneSoftwrights(_dot_)com
Male Cancer Awareness Nov'07  http://www.CraneSoftwrights.com/s/bc
Legal business disclaimers:  http://www.CraneSoftwrights.com/legal



--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
**************************************************************************************


                                                                       
             Sharon Harris/USG                                         
                                                                       
             07/01/2009 09:10                                           To
             AM                        
xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com 
                                                                        cc
                                                                       
                                                                   Subject
                                       Re: Search and Replace to add HTML
                                       tags(Document link: Sharon Harris)
                                                                       
                                                                       
                                                                       
                                                                       
                                                                       
                                                                       



Thank you very much for your solution and explanation re: replace function.
Your solution worked perfectly and I now understand better when and how to
use the replace function.

One more thing I am trying to do within the same node is to search for any
text that starts w/ "http://"; and take that and the text that follows it
and turn it into an active hyperlink. This is the code I was using to
perform this action and now understand that I need to combine this along w/
the action for searching for specific words and wrapping tags around them
within the same template definition (ReleaseNote).  Unfortunately, I have
not been successful and do not understand how to perform 2 different search
and replace functions within the same node.

Here is the original code which obviously does not work as the ReleaseNote
template definition overwrites the changes made from the text template
definition. But I do not understand how to combine both actions within the
ReleaseNote template definition.

XSL excerpt:
<!--Converts string that starts w/ "http://"; to an active hyperlink-->
      <xsl:template match="text()">
            <xsl:call-template name="hyperlink"/>
      </xsl:template>
      <xsl:template name="hyperlink">
            <xsl:param name="string" select="string(.)"/>
            <xsl:analyze-string select="$string" regex="http://[^ ]+">
                  <xsl:matching-substring>
                        <a href="{.}" target="new">
                              <xsl:value-of select="."/>
                        </a>
                  </xsl:matching-substring>
                  <xsl:non-matching-substring>
                        <xsl:value-of select="."/>
                  </xsl:non-matching-substring>
            </xsl:analyze-string>
      </xsl:template>

<xsl:template match="ReleaseNote">
            <td class="info">
                  <xsl:copy>
                        <xsl:analyze-string select="." regex="Before:|
Enhancement:|Informational:|Note:|Now:">
                              <xsl:matching-substring>
                                    <b><xsl:value-of select="."/></b>
                              </xsl:matching-substring>
                              <xsl:non-matching-substring>
                                    <xsl:value-of select="."/>
                           </xsl:non-matching-substring>
                        </xsl:analyze-string>
                  </xsl:copy>
            </td>
      </xsl:template>

XML excerpt:

   <Row>
   <ReleaseNote>Before: The application did this. Now: The application does
   this. Here is a link: http://myurl.com Note: The application may also do
   this.</ReleaseNote>
   </Row>
   <Row>
   <ReleaseNote>Before: The application did not do this. Now: The
   application does this.</ReleaseNote>
   </Row>

Desired HTML output:

      <td><b>Before:</b> The application did this. <b>Now:</b> the
application does this. Here is a link: <a href="http://myurl.com
">http://myurl.com</a> <b>Note:</b> The application may also do this.
      </td>






**************************************************************************************************************************
Date: Tue, 30 Jun 2009 13:38:08 -0400
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
From: "G. Ken Holman" <gkholman(_at_)CraneSoftwrights(_dot_)com>
Subject: Re: [xsl] Search and Replace to add HTML tags
Message-Id: 
<7(_dot_)0(_dot_)1(_dot_)0(_dot_)2(_dot_)20090630133320(_dot_)026f1768(_at_)wheresmymailserver(_dot_)com>

At 2009-06-30 13:30 -0400, Sharon_Harris(_at_)ultimatesoftware(_dot_)com wrote:
I am trying to wrap specific text in a string within HTML tags. For
example, if a strings contains the word "Note:", then I want to enclose
this word within a set of bold tags (<b>Note:</b>). I do not have control
over the XML data source and cannot modify the structure/schema.

I have tried using the replace function to search for the specific text
and
then replace it with a defined variable.

The replace() function only works with strings, not with nodes.

The variable contains the text
wrapped within the HTML tags. Unfortunately, only the content within the
variable is getting pulled and the HTML tags are being ignored.

Correct ... because the arguments to replace() are cast to strings.

Can anyone
tell me how to get the tags added as well during the search and replace?

By analyzing the string rather than using replace.

XML excerpt:
   <Row>
   <ReleaseNote>Before: The application did this. Now: The application
does
   this. Note: The application may also do this.</ReleaseNote>
   </Row>
   <Row>
   <ReleaseNote>Before: The application did not do this. Now: The
   application does this.</ReleaseNote>
   </Row>

XSLT excerpt:
   <xsl:variable name="NoteBold"><b>Note:</b></xsl:variable>
   <xsl:variable name="BeforeBold"><b>Before:</b></xsl:variable>
   <xsl:variable name="NowBold"><b>Now:</b></xsl:variable>

   <xsl:template match="text()">
      <xsl:value-of select="replace(replace(replace(.,'Note:',$NoteBold),
   'Before:',$BeforeBold), 'Now:', $NowBold)"/>
   </xsl:template>

This is an incorrect approach because you are matching *all* text
nodes in the *entire* document and doing the replace on *every* piece
of text you have.

I hope the example below helps ... you have a very straightforward
requirement because you are only wrapping text with a bold element
node, not massaging the text.

. . . . . . . . . . . Ken

T:\ftemp>type sharon.xml
<test>
    <Row>
    <ReleaseNote>Before: The application did this. Now: The application
does
    this. Note: The application may also do this.</ReleaseNote>
    </Row>
    <Row>
    <ReleaseNote>Before: The application did not do this. Now: The
    application does this.</ReleaseNote>
    </Row>
</test>

T:\ftemp>call xslt2 sharon.xml sharon.xsl
<?xml version="1.0" encoding="UTF-8"?><test>
    <Row>
    <ReleaseNote><b>Before:</b> The application did this. <b>Now:</b>
The applica
tion does
    this. <b>Note:</b> The application may also do this.</ReleaseNote>
    </Row>
    <Row>
    <ReleaseNote><b>Before:</b> The application did not do this.
<b>Now:</b> The
    application does this.</ReleaseNote>
    </Row>
</test>
T:\ftemp>type sharon.xsl
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
                 version="2.0">

<xsl:template match="ReleaseNote">
   <xsl:copy>
     <xsl:analyze-string select="." regex="Before:|Note:|Now:">
       <xsl:matching-substring>
         <b><xsl:value-of select="."/></b>
       </xsl:matching-substring>
       <xsl:non-matching-substring>
         <xsl:value-of select="."/>
       </xsl:non-matching-substring>
     </xsl:analyze-string>
   </xsl:copy>
</xsl:template>

<xsl:template match="@*|node()"><!--identity for all other nodes-->
   <xsl:copy>
     <xsl:apply-templates select="@*|node()"/>
   </xsl:copy>
</xsl:template>

</xsl:stylesheet>

T:\ftemp>
**************************************************************************************************************************


                                                                       
             Sharon Harris/USG                                         
                                                                       
             06/30/2009 01:30                                           To
             PM                        
xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com 
                                                                        cc
                                                                       
                                                                   Subject
                                       Search and Replace to add HTML tags
                                                                       
                                                                       
                                                                       
                                                                       
                                                                       
                                                                       



I am trying to wrap specific text in a string within HTML tags. For
example, if a strings contains the word "Note:", then I want to enclose
this word within a set of bold tags (<b>Note:</b>). I do not have control
over the XML data source and cannot modify the structure/schema.

I have tried using the replace function to search for the specific text and
then replace it with a defined variable. The variable contains the text
wrapped within the HTML tags. Unfortunately, only the content within the
variable is getting pulled and the HTML tags are being ignored. Can anyone
tell me how to get the tags added as well during the search and replace?

XML excerpt:
   <Row>
   <ReleaseNote>Before: The application did this. Now: The application does
   this. Note: The application may also do this.</ReleaseNote>
   </Row>
   <Row>
   <ReleaseNote>Before: The application did not do this. Now: The
   application does this.</ReleaseNote>
   </Row>

XSLT excerpt:
   <xsl:variable name="NoteBold"><b>Note:</b></xsl:variable>
   <xsl:variable name="BeforeBold"><b>Before:</b></xsl:variable>
   <xsl:variable name="NowBold"><b>Now:</b></xsl:variable>

   <xsl:template match="text()">
      <xsl:value-of select="replace(replace(replace(.,'Note:',$NoteBold),
   'Before:',$BeforeBold), 'Now:', $NowBold)"/>
   </xsl:template>



Thanks for your help!
_______________________________
Sharon Goldner Harris
Knowledge Management Evangelist
Ultimate Software Group
704-660-6482

Confidentiality Note: This e-mail message and any attachments to it are
intended only for the named recipients and may contain legally privileged
and/or confidential information. If you are not one of the intended
recipients, do not duplicate or forward this e-mail message.



--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--

<Prev in Thread] Current Thread [Next in Thread>