Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Westi on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Replace text with xsl:value-of ? 1

Status
Not open for further replies.

markdmac

MIS
Dec 20, 2003
12,340
US
I have created a page that is using RSS to pull weather information. The XSL file has a line:

<xsl:value-of select="current_observation/wind_string"/>

Within the returned results for that node the text will start with <b>From the...Northwest, Northeast, Southwest, Southeast</b>

I would like to be able to manipulate this and have it simply say NW,NE,SW,SE accordingly. Can anyone point me in the right direction?

Many thanks,

Mark
 
If you don't have XPath 2.0 available, you would typically use the XPath function contains() to to detect the string you wish to replace, then a combination of XPath functions concat(), substring-before(), and sunstring-after(). It is not pretty, but it works.

I am not an expert on XPath 2.0 but I seem to recall a function replace().

Tom Morrison
 
Thanks Tom, I will try Googling xpath.

I hope you find this post helpful.

Regards,

Mark

Check out my scripting solutions at
Work SMARTER not HARDER. The Spider's Parlor's Admin Script Pack is a collection of Administrative scripts designed to make IT Administration easier! Save time, get more work done, get the Admin Script Pack.
 
In xslt 1.0, it looks pretty clumsy for those uninitiated.

[1] The basic replace workhorse of a single replacement (such as Northeast by NE) is a recursive named template. It is the named template [blue]r_sab[/blue] below. As it is quite instructive, and hence it is flooded with similar construction, some claim undue credit. I make this "credit-neutral", and don't claim any credit, form and have a little personal touch not seen elsewhere.

[2] And then the multiple replacement is again put into another named template ([blue]do-replace[/blue]) of no particular general interest.

Here would be the general constructions for this kind of task.
[tt]
<xsl:template name="do-replace">
<xsl:param name="input" />
<xsl:variable name="w">
<xsl:call-template name="r_sab">
<xsl:with-param name="s" select="$input" />
<xsl:with-param name="a" select="'Northwest'" />
<xsl:with-param name="b" select="'NW'" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="x">
<xsl:call-template name="r_sab">
<xsl:with-param name="s" select="$w" />
<xsl:with-param name="a" select="'Northeast'" />
<xsl:with-param name="b" select="'NE'" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="y">
<xsl:call-template name="r_sab">
<xsl:with-param name="s" select="$x" />
<xsl:with-param name="a" select="'Southwest'" />
<xsl:with-param name="b" select="'SW'" />
</xsl:call-template>
</xsl:variable>
<xsl:variable name="z">
<xsl:call-template name="r_sab">
<xsl:with-param name="s" select="$y" />
<xsl:with-param name="a" select="'Southeast'" />
<xsl:with-param name="b" select="'SE'" />
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="$z" />
</xsl:template>

<xsl:template name="r_sab">
<!-- replace substring common named template: credit neutral -->
<!--
param $s : input string
param $a : substring particle to be replace (globally)
param $b : substring particle to replace $a (globally)
-->
<xsl:param name="s"/>
<xsl:param name="a"/>
<xsl:param name="b"/>
<xsl:choose>
<xsl:when test="contains($s, $a) and not($b = $a)">
<xsl:variable name="_a" select="substring-before($s, $a)" />
<xsl:variable name="a_" select="substring-after($s, $a)" />
<!-- packing result step-by-step -->
<xsl:value-of select="concat($_a,$b)" />
<xsl:call-template name="r_sab">
<xsl:with-param name="s" select="$a_" />
<xsl:with-param name="a" select="$a" />
<xsl:with-param name="b" select="$b" />
</xsl:call-template>
</xsl:when>
<xsl:eek:therwise>
<!-- packing the last bit of substring -->
<xsl:value-of select="$s" />
</xsl:eek:therwise>
</xsl:choose>
</xsl:template>
[/tt]
[3] When in the proper context node, you trigger the replacement mechanism like this.
[tt]
[red]<!--[/red] <xsl:value-of select="current_observation/wind_string"/> [red]-->[/red]
[blue]<xsl:variable name="output">
<xsl:call-template name="do-replace">
<xsl:with-param name="input" select="current_observation/wind_string/text()" />
</xsl:call-template>
</xsl:variable>
<xsl:value-of select="$output" />[/blue]
[/tt]
 
Wow, thanks tsuji! I'm going to need some time to digest that so I understand it.

In the mean time, I acted on Tom's suggestion and realized I may have been overthinking things. My XML is being dumped to an ASP:Literal. So I was able to use the .Text property of that control and use a regular vbscript Replace command on it.

No XPath or XML manipulation was actually needed in this case but I am learning a ton thanks to this site conversion I am doing and my fellow TT members.

As I come to understand XML more I will revisit your solution tsuji and compare performance over what I am doing now.

Thank you both.

Mark
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top