I have a back end system that passed data to me in tabular XML format so
that it can be easily loaded into a Data Dynamics SharpGrid. The native
format for data in SharpGrid is like the following:
<Data count=1>
<row col1="My Data" col2="More Data" col3="Even more data" />
</Data>
The problem with this format is that the only way xml can be sent in one of
these attributes is to replace all < with < and > with >. This is
what is done for one of the columns and now I need to get the data back into
XML (see below for example of the data). My plan was to use an xml template
to do a search and replace to put back in the < and >. With the data stored
in a variable, I can then turn the variable into a node-set and do any
x-path off of it that I want. Unfortunately, I can't get my replace to
work. I know I can do this using a script tag, but I'd rather not do that
if I don't have to. Here's my approach. When I run through the xsl parser
it complains on the select="string(<)" (same for > version) saying
that string(<) isn't a valid X-Path. Let me know if there is a better
way to do this. Preferably, one that works, since this doesn't. =)
<xsl:variable name="LongFieldData">
<xsl:call-template name="globalReplace">
<xsl:with-param name="outputString" select="LongFieldData"/>
<!-- **************************************
The one below is fine since there are the single
quotes. It's treated as a string
**************************************-->>
<xsl:with-param name="lookfor" select="'<'"/>
<!-- **************************************
This one fails saying it is an invalid X-Path
**************************************-->>
<xsl:with-param name="replacewith" select="string(<)" />
<xsl:call-template name="globalReplace">
<!-- with no selection on outputString, it will use the
output from last iteration as input -->
<xsl:with-param name="outputString" />
<xsl:with-param name="lookfor" select="'>'"/>
<xsl:with-param name="replacewith" select="string(>)" />
</xsl:call-template>
</xsl:call-template>
</xsl:variable>
<table>
<xsl:for-each select="msxsl:node-set($LongFieldData)/item" />
<tr><td>
<xsl:value-of select="xmldata" />
</tr></td>
<xsl:for-each>
</table>
<xsl:template name="globalReplace">
<xsl:param name="outputString"/>
<xsl:param name="lookfor"/>
<xsl:param name="replacewith"/>
<xsl:choose>
<xsl:when test="contains($outputString,$lookfor)">
<xsl:value-of select="concat(substring-before($outputString,$lookfor),
$replacewith)"/>
<xsl:call-template name="globalReplace">
<xsl:with-param name="outputString"
select="substring-after($outputString,$lookfor)"/>
<xsl:with-param name="lookfor" select="$lookfor"/>
<xsl:with-param name="replacewith" select="$replacewith"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$outputString"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
Here's the embedded xml:
------------------------------
<item> <xmltag> Some data that I need to get </xmltag>
</item> <item> <xmltag> Some more that I need to get
</xmltag> </item>
Here's what I want it to look like so I can turn it into a nodeset.
---------------------------------------------------------------
<item>
<xmltag>Some data that I need to get</xmltag>
</item>
<item>
<xmltag>Some more data that I need to get</xmltag>
</item>