By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,190 Members | 1,056 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,190 IT Pros & Developers. It's quick & easy.

URL parsing and replacing

P: n/a
Dear XMLers,
Please guide me...
I have a simple xml file...
<URLTest>
<text1>My favorite news site is http://www.yahoo.com</text1>
<text2>My favorite software site is
http://www.microsoft.com</text2>
</URLTest>
Using this XML, how do I extract the url using XSLT so that the
resulting html contains the following...

My favorite news site is <a
href="http://www.yahoo.com">http://www.yahoo.com</a>

My favorite software site is <a
href="http://www.yahoo.com">http://www.microsoft.com</a>

The text entered is free form so I won't know ahead of time if a URL
exists in the input text field or not. It's not required but it would
be nice to create the link for them if it is there.

It is essentially replacing the http://... with the href code.

Netman

Jul 20 '05 #1
Share this Question
Share on Google+
8 Replies


P: n/a
ja******@yahoo.com <ja******@yahoo.com> wrote:
Dear XMLers,
Please guide me...
I have a simple xml file...
<URLTest>
<text1>My favorite news site is http://www.yahoo.com</text1>
<text2>My favorite software site is
http://www.microsoft.com</text2>
</URLTest>
Using this XML, how do I extract the url using XSLT so that the
resulting html contains the following...

My favorite news site is <a
href="http://www.yahoo.com">http://www.yahoo.com</a>

My favorite software site is <a
href="http://www.yahoo.com">http://www.microsoft.com</a>

The text entered is free form so I won't know ahead of time if a URL
exists in the input text field or not. It's not required but it would
be nice to create the link for them if it is there.

It is essentially replacing the http://... with the href code.


<xsl:template match='text()'>
<xsl:call-template name='grab-url'>
<xsl:with-param name='s' select='.' />
</xsl:call-template>
</xsl:template>

<xsl:template name='grab-url'>
<xsl:param name='s' />
<xsl:variable name='pre' select='string-before($s,"http://")' />
<xsl:variable name='test' select='string-after($s,"http://")' />
<xsl:variable name='addr' select='string-before($test," ")' />
<xsl:variable name='post' select='string-after($test," ")' />
<xsl:variable name='url'>
<xsl:choose>
<xsl:when test='$addr'>http://<xsl:value-of select='$addr'
/></xsl:when>
<xsl:when test='$test'>http://<xsl:value-of select='$test'
/></xsl:when>
</xsl:choose>
</xsl:variable>
<xsl:choose>
<xsl:when test='$pre'>
<xsl:value-of select='$pre'>
<a href='{$url}'><xsl:value-of select='$url' /></a>
<xsl:if test='$post'><xsl:call-template name='grab-url'>
<xsl:with-param name='s' select='concat(" ",$post)' />
</xsl:call-template></xsl:if>
</xsl:when>
<xsl:otherwise><xsl:value-of select='$s' /></xsl:otherwise>
</xsl:choose>
</xsl:template>
Should do it. I've expanded the elements a bit to make it more
readable; it may be necessary to collapse things and remove whitespace
to ensure you don't get bogus spaces in the output text.
Keith
--
Keith Davies "Trying to sway him from his current kook-
ke**********@kjdavies.org rant with facts is like trying to create
ke**********@gmail.com a vacuum in a room by pushing the air
http://www.kjdavies.org/ out with your hands." -- Matt Frisch
Jul 20 '05 #2

P: n/a
Thanks for the code!

Using my existing xslt, how do I integrate this code? The @result in
my code below has the original string to display with the possible URL
embedded in it.

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<html>
<body>
<div align="center">
<p><img src="logo.gif"></img></p>
<p><font size="+1" face="Verdana, Arial, Helvetica,
sans-serif"></font></p>
</div>
<table border="0" align="center">
<tr>
<td align="left" bgcolor="638EC3">
<div align="center">
<font color="#FFFFFF" size="-1" face="Verdana, Arial,
Helvetica, sans-serif">Step</font>
</div>
</td>
<td align="left" bgcolor="638EC3">
<font color="#FFFFFF" size="-1" face="Verdana, Arial, Helvetica,
sans-serif">Test Results</font>
</td>
</tr>
<xsl:for-each select="application/steps/step">
<xsl:choose>
<xsl:when test="(@pass='PASS')">
<tr >
<td bgcolor="638EC3">
<div align="center"><font color="#FFFFFF" size="-1"
face="Verdana, Arial, Helvetica, sans-serif">
<xsl:value-of select="@id"/>
</font>
</div>
</td>
<td bgcolor="#80FF80">
<div align="{@align}">
<font size="-1" face="Verdana, Arial, Helvetica,
sans-serif">
<xsl:value-of select="@result"
disable-output-escaping="yes"/>
</font>
</div>
</td>
</tr>
</xsl:when>
<xsl:when test="(@pass='Pass')">
<tr >
<td bgcolor="638EC3">
<div align="center"><font color="#FFFFFF" size="-1"
face="Verdana, Arial, Helvetica, sans-serif">
<xsl:value-of select="@id"/>
</font>
</div>
</td>
<td bgcolor="#FFFF80">
<div align="{@align}">
<font size="-1" face="Verdana, Arial, Helvetica, sans-serif">
<xsl:value-of select="@result"/>
</font>
</div>
</td>
</tr>
</xsl:when>
<xsl:when test="(@pass='Fail')">
<tr >
<td bgcolor="638EC3">
<div align="center"><font color="#FFFFFF" size="-1"
face="Verdana, Arial, Helvetica, sans-serif">
<xsl:value-of select="@id"/>
</font>
</div>
</td>
<td bgcolor="#FF8080">
<div align="{@align}">
<font size="-1" face="Verdana, Arial, Helvetica, sans-serif">
<xsl:value-of select="@result"/>
</font>
</div>
</td>
</tr>
</xsl:when>
<xsl:otherwise>
<tr>
<td>
<div align="center"> <font size="-1" face="Verdana,
Arial, Helvetica, sans-serif">
<xsl:value-of select="@id"/>
</font>
</div>
</td>
<td bgcolor="#FFFF80">
<div align="{@align}">
<font size="-1" face="Verdana, Arial, Helvetica, sans-serif">
<xsl:value-of select="@result"/>
</font>
</div>
</td>
</tr>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>

Jul 20 '05 #3

P: n/a
ja******@yahoo.com <ja******@yahoo.com> wrote:
Thanks for the code!

Using my existing xslt, how do I integrate this code? The @result in
my code below has the original string to display with the possible URL
embedded in it.


Oh? If that's the case, just call grab-url. What I wrote should work
on *all* text() in the document (but not attribute values).

Where you process @result, do:

<xsl:call-template name='grab-url'>
<xsl:with-param name='s' select='@result' />
</xsl:call-template>

instead of

<xsl:value-of select='@result' />

You could instead do

<xsl:template match='@result'>
<xsl:call-template name='grab-url'>
<xsl:with-param name='s' select='.' />
</xsl:call-template>
</xsl:template>

then change

<xsl:value-of select='@result' />

to

<xsl:apply-templates select='@result' />
It all depends what you're doing.
Keith
--
Keith Davies "Trying to sway him from his current kook-
ke**********@kjdavies.org rant with facts is like trying to create
ke**********@gmail.com a vacuum in a room by pushing the air
http://www.kjdavies.org/ out with your hands." -- Matt Frisch
Jul 20 '05 #4

P: n/a
Getting close!

I'm now getting an 'xsl-value-of may not contain a.' error. Is the
'url' parameter being set or used?

If I remove this section of code, it generates okay.

<xsl:choose>
<xsl:when test='$pre'>
<xsl:value-of select='$pre'>

<a href='{$url}'> <xsl:value-of select='$url' /> </a>
<xsl:if test='$post'>
<xsl:call-template name='grab-url'>
<xsl:with-param name='s' select='concat(" ",$post)' />
</xsl:call-template>
</xsl:if>

</xsl:value-of>
</xsl:when>
<xsl:otherwise><xsl:value-of select='$s' /></xsl:otherwise>
</xsl:choose>

Jul 20 '05 #5

P: n/a
ja******@yahoo.com <ja******@yahoo.com> wrote:
Getting close!

I'm now getting an 'xsl-value-of may not contain a.' error. Is the
'url' parameter being set or used?
Typo on my part.
<xsl:choose>
<xsl:when test='$pre'>
<xsl:value-of select='$pre'>
should be
<xsl:choose>
<xsl:when test='$pre'>
<xsl:value-of select='$pre' />

Keith
--
Keith Davies "Trying to sway him from his current kook-
ke**********@kjdavies.org rant with facts is like trying to create
ke**********@gmail.com a vacuum in a room by pushing the air
http://www.kjdavies.org/ out with your hands." -- Matt Frisch
Jul 20 '05 #6

P: n/a
That fixed it and it works like a champ!

Thanks so much!

Jul 20 '05 #7

P: n/a
I did notice that there must be a space in front of the http://... to
work even if it's the first thing on a line of text. Anyway of getting
around this limitation?

Thanks!

Jul 20 '05 #8

P: n/a
ja******@yahoo.com <ja******@yahoo.com> wrote:
I did notice that there must be a space in front of the http://... to
work even if it's the first thing on a line of text. Anyway of getting
around this limitation?


Actually, it doesn't need a space before the http://, it just has to
have *something*.

Look for "test='$pre'". You'll see the instruction to output the $url
value. Move that instruction (and everything after it, to the end of
the "test='$pre'" condition) to immediately following the condition.

That is, it should do

<xsl:if test='$pre'><!-- do $pre stuff --></xsl:if>
<xsl:if test='$url'><!-- do $url stuff --></xsl:if>
<xsl:if test='$post'><!-- do $post stuff --></xsl:if>

rather than

<xsl:if test='$pre'>
<!-- do $pre stuff -->
<!-- do $url stuff -->
<!-- do $post stuff -->
</xsl:if>

(though I think I used xsl:when there; don't remember and you didn't
quote)
Keith
--
Keith Davies "Trying to sway him from his current kook-
ke**********@kjdavies.org rant with facts is like trying to create
ke**********@gmail.com a vacuum in a room by pushing the air
http://www.kjdavies.org/ out with your hands." -- Matt Frisch
Jul 20 '05 #9

This discussion thread is closed

Replies have been disabled for this discussion.