Replace hithighlight tags

Discussion in 'XML' started by Peter van Schie, Oct 4, 2005.

  1. Hi all,

    Give an xml document that looks something like this:

    <?xml version="1.0" encoding="iso-8859-1"?>
    <?xml-stylesheet type="text/xsl"
    href="http://localhost/archiefassistent/xsl/fulldoc.xsl"?>
    <result>
    <currentpage>1</currentpage>
    <document id="5">
    <fulltext>This module is the <searchhit>third</searchhit> in the
    OPPS series. More text...</fulltext>
    </document>
    </result>

    I'm transforming this document to html to display in a browser. The xml
    document is a searchresult and the <searchhit></searchhit> tags
    surround the terms that were searched for. Now I'd like to transform
    the <searchhit> and </searchhit> tags into something like <span
    style="background: red;"> and </span>, to highlight the searchterms in
    the resultview.

    Is this possible? And if yes, could you give me some pointers as to
    how?
    Thanks.
     
    Peter van Schie, Oct 4, 2005
    #1
    1. Advertising

  2. Peter van Schie

    RobG Guest

    Peter van Schie wrote:
    > Hi all,
    >
    > Give an xml document that looks something like this:
    >
    > <?xml version="1.0" encoding="iso-8859-1"?>
    > <?xml-stylesheet type="text/xsl"
    > href="http://localhost/archiefassistent/xsl/fulldoc.xsl"?>
    > <result>
    > <currentpage>1</currentpage>
    > <document id="5">
    > <fulltext>This module is the <searchhit>third</searchhit> in the
    > OPPS series. More text...</fulltext>
    > </document>
    > </result>
    >
    > I'm transforming this document to html to display in a browser. The xml
    > document is a searchresult and the <searchhit></searchhit> tags
    > surround the terms that were searched for. Now I'd like to transform
    > the <searchhit> and </searchhit> tags into something like <span
    > style="background: red;"> and </span>, to highlight the searchterms in
    > the resultview.
    >
    > Is this possible? And if yes, could you give me some pointers as to
    > how?


    Yes, it's possible. Presumably you are parsing the XML to convert it to
    a DOM document fragment. When you get to a searchhit element, insert a
    span with the required attributes.

    If you show how you are parsing the XML, you may get more help...


    --
    Rob
     
    RobG, Oct 7, 2005
    #2
    1. Advertising

  3. Peter van Schie

    Andy Dingley Guest

    Peter van Schie wrote:

    > I'm transforming this document to html to display in a browser.


    Try some XSLT


    <xsl:template match="searchhit" mode="search-results-with-highlight" >
    <span style="background: red; padding: 0.125em 0.5em;"
    ><xsl:apply-templates mode="search-results-with-highlight" /></span>

    </xsl:template>

    <xsl:template match="*" mode="search-results-with-highlight" >
    <!--
    This is needed in case of more element structure within <fulltext>, so
    as to preserve the mode
    It might even copy some elements (embedded HTML?) to the output
    -->
    <xsl:apply-templates mode="search-results-with-highlight" />
    </xsl:template>


    [...]

    <xsl:apply-templates select="./document/fulltext"
    mode="search-results-with-highlight" />
     
    Andy Dingley, Oct 7, 2005
    #3
  4. Hi Rob and Andy,

    Thank you both for the reply.
    I tried Andy's template, but it won't do what I want still. The
    relevant part of my xslt looks like this:

    <?xml version="1.0" encoding="ISO-8859-1"?>

    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:eek:utput method="html" cdata-section-elements="fulltext" />
    <xsl:template match="/">

    [... html header stuff ...]

    <xsl:if test="/result/document/fulltext!=''">
    <tr>
    <td class="label">Text</td>
    <td class="label">:</td>
    <td class="fulldoccontent">
    <xsl:apply-templates select="/result/document/fulltext"
    mode="search-results-with-highlight" />

    </td>
    </tr>
    </xsl:if>

    [... html footer stuff ...]
    </xsl:template>

    <xsl:template match="searchhit" mode="search-results-with-highlight" >
    <span style="background: red; padding: 0.125em 0.5em;">
    <xsl:apply-templates mode="search-results-with-highlight" /></span>
    </xsl:template>

    <xsl:template match="*" mode="search-results-with-highlight" >
    <!--
    This is needed in case of more element structure within <fulltext>, so
    as to preserve the mode
    It might even copy some elements (embedded HTML?) to the output
    -->
    <xsl:apply-templates mode="search-results-with-highlight" />
    </xsl:template>

    </xsl:stylesheet>

    I think the problem is that I insert the <searchhit> and </searchhit>
    tags from PHP. So those tags are treated as CDATA within the fulltext
    element. Could this be the case?
    Thanks.

    Kind regards,
    Peter.
     
    Peter van Schie, Oct 7, 2005
    #4
  5. Edit: Sorry I forgot to mention what the output is and what I want it
    to be.
    In the output the <searchhit> tags are being output literally as text.
     
    Peter van Schie, Oct 7, 2005
    #5
  6. Peter van Schie

    Ixa Guest

    > I'm transforming this document to html to display in a browser.

    Maybe I've missed the point, but I think this should not be that hard
    with XSLT:

    > <xsl:apply-templates select="/result/document/fulltext"
    > mode="search-results-with-highlight" />


    Just apply without modes ...

    ---8<---8<---
    <xsl:apply-templates select="/result/document/fulltext"/>
    ---8<---8<---

    > <xsl:template match="searchhit" mode="search-results-with-highlight" >
    > <span style="background: red; padding: 0.125em 0.5em;">
    > <xsl:apply-templates mode="search-results-with-highlight" /></span>
    > </xsl:template>


    .... and wrap <searchhit> with <span> ...

    ---8<---8<---
    <xsl:template match="searchhit">
    <span style="background: red; padding: 0.125em 0.5em;">
    <xsl:apply-templates/>
    </span>
    </xsl:template>
    ---8<---8<---

    --
    Ixa
     
    Ixa, Oct 8, 2005
    #6
  7. Hi Ixa,

    Thanks for the suggestion.
    But I think: <xsl:template match="searchhit">
    won't work because of <searchhit> and </searchhit> being CDATA within
    the fulltext element.
    I think I need some sort of replacement template to replace the
    <searchhit> tags.
    I've already been experimenting with it, but didn't reach the goal yet.
    I can replace the opening <searchhit> tags now, but when I store the
    result of that replacement in a variable and then use that variable as
    the input of the replacement of the closing tags it won't work anymore.

    Here's what I tried:

    ========================================================
    <?xml version="1.0" encoding="ISO-8859-1"?>

    <xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:eek:utput method="html" />

    <xsl:template match="/result/document/fulltext">

    <xsl:variable name="openTags">
    <xsl:call-template name="replace">
    <xsl:with-param name="text" select="." />
    <xsl:with-param name="from" select="'&lt;searchhit&gt;'"/>
    <xsl:with-param name="with" select="'&lt;span
    style="background: red;"&gt;'"/>
    </xsl:call-template>
    </xsl:variable>

    <xsl:call-template name="replace">
    <xsl:with-param name="text"><xsl:copy-of
    select="$openTags"/></xsl:with-param>
    <xsl:with-param name="from" select="'&lt;/searchhit&gt;'"/>
    <xsl:with-param name="with" select="'&lt;/span&gt;'"/>
    </xsl:call-template>

    </xsl:template>

    <xsl:template name="replace">
    <xsl:param name="text"/>
    <xsl:param name="from"/>
    <xsl:param name="with"/>

    <xsl:choose>
    <xsl:when test="$from and contains($text,$from)">

    <xsl:value-of select="substring-before($text,$from)"/>
    <xsl:value-of disable-output-escaping="yes" select="$with"/>

    <xsl:call-template name="replace">
    <xsl:with-param name="text"
    select="substring-after($text,$from)"/>
    <xsl:with-param name="from" select="$from"/>
    <xsl:with-param name="with" select="$with"/>
    </xsl:call-template>

    </xsl:when>
    <xsl:eek:therwise>

    <xsl:value-of select="$text"/>

    </xsl:eek:therwise>
    </xsl:choose>
    </xsl:template>

    </xsl:stylesheet>

    ========================================================

    The output of this is that the <searchhit> tags get replaced by
    <span style="background: red;"> and the closing </searchhit> tags get
    replaced by: &lt;/searchhit&gt;
    So in the output I get: <span style="background:
    red;">mixing&lt;/searchhit&gt;

    However, when I leave out the second call to the replace template and
    just do this:
    ======================================================
    <xsl:variable name="openTags">
    <xsl:call-template name="replace">
    <xsl:with-param name="text" select="." />
    <xsl:with-param name="from" select="'&lt;searchhit&gt;'"/>
    <xsl:with-param name="with" select="'&lt;span
    style="background: red;"&gt;'"/>
    </xsl:call-template>
    </xsl:variable>

    <xsl:copy-of select="$openTags"/>
    ======================================================

    The <span background: "red";> tags are being parsed by the browser and
    everything after it gets a red background.

    Any ideas?
    Thanks.

    Kind regards,
    Peter.
     
    Peter van Schie, Oct 8, 2005
    #7
  8. Peter van Schie

    Ixa Guest

    > But I think: <xsl:template match="searchhit"> won't work because of
    > <searchhit> and </searchhit> being CDATA within the fulltext element.


    Right, so you have something like:

    ---8<---8<---
    <fulltext><![CDATA[This module is the <searchhit>third</searchhit> in the
    OPPS series. More text...]]></fulltext>
    ---8<---8<---

    > I think I need some sort of replacement template to replace the
    > <searchhit> tags.


    Would this kind of template do the trick?

    ---8<---8<---
    <xsl:template name="wrapper">
    <xsl:param name="content"/>
    <xsl:choose>
    <xsl:when test="contains($content, '&lt;searchhit&gt;')">
    <xsl:value-of select="substring-before($content,
    '&lt;searchhit&gt;')"/>
    <span style="background: red; padding: 0.125em 0.5em;">
    <xsl:value-of
    select="substring-before(substring-after($content,
    '&lt;searchhit&gt;'), '&lt;/searchhit&gt;')"/>
    </span>
    <xsl:call-template name="wrapper">
    <xsl:with-param name="content"><xsl:value-of
    select="substring-after($content,
    '&lt;/searchhit&gt;')"/></xsl:with-param>
    </xsl:call-template>
    </xsl:when>
    <xsl:eek:therwise>
    <xsl:value-of select="$content"/>
    </xsl:eek:therwise>
    </xsl:choose>
    </xsl:template>

    <xsl:template match="/result/document/fulltext">
    <xsl:call-template name="wrapper">
    <xsl:with-param name="content"><xsl:value-of
    select="text()"/></xsl:with-param>
    </xsl:call-template>
    </xsl:template>
    ---8<---8<---

    --
    Ixa
     
    Ixa, Oct 8, 2005
    #8
  9. Hi Ixa,

    Your template works indeed! You have no idea how grateful I am. This
    took me hours of hairpulling to solve.
    Thanks a lot!

    Kind regards,
    Peter.
     
    Peter van Schie, Oct 8, 2005
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Dean H. Saxe
    Replies:
    0
    Views:
    1,069
    Dean H. Saxe
    Jan 3, 2004
  2. Rob Nicholson
    Replies:
    3
    Views:
    811
    Rob Nicholson
    May 28, 2005
  3. Ranganath

    Custom Tags within Custom Tags.

    Ranganath, Oct 17, 2003, in forum: Java
    Replies:
    2
    Views:
    478
    Ranganath
    Oct 21, 2003
  4. Mike
    Replies:
    3
    Views:
    896
    Michael Borgwardt
    Jan 9, 2004
  5. A. Brinkmann
    Replies:
    2
    Views:
    1,111
    A. Brinkmann
    Apr 16, 2004
Loading...

Share This Page