Hi
-----Original Message-----
From: owner-xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
[mailto:owner-xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com] On Behalf Of
Karr, David
Sent: Thursday, July 24, 2003 6:27 PM
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: [xsl] Techniques for transforming content like
"<tag>content</tag>" to "<tag>content</tag>"
I have a requirement to write XSLT transformers for XML
documents, some of whose element contents can consist of
"encoded" XML, like this:
<other>
<key>stuff</key> <value><userid>98765</userid></value>
</other>
We need to transform this to this:
<other>
<key>stuff_userid</key>
<value>98765</value>
</other>
There's no avoiding that this will be messy, so I'm only
aiming to clean up the worst part of this process: how I
parse the "encoded" XML. A POC for this is just using
"substring-after" and "substring-before" to set the pieces
into variables. Is there a better way to parse content like this?
You could use this stylesheet. This isn't a xml parser, it doesn't report
xml errors, just transform <node>text</node> into
<node>text</node>
Just
<xsl:include href="taggifier.xsl"/>
<xsl:template match="...">
...
<xsl:call-template name="parse">
<xsl:with-param name="str" select="some node or attribute to parse"/>
</xsl:call-template>
...
</xsl:template>
Hope this helps you
Regards,
Américo Albuquerque
taggifier.xsl:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template name="parse">
<xsl:param name="str" select="."/>
<xsl:choose>
<xsl:when test="contains($str,'<')">
<xsl:variable name="tag"
select="substring-before(substring-after($str,'<'),'>')"/>
<xsl:variable name="endTag">
<xsl:choose>
<xsl:when test="contains($tag,' ')">
<xsl:value-of select="substring-before($tag,' ')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$tag"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<xsl:call-template name="parse">
<xsl:with-param name="str"
select="substring-before($str,concat('<',$tag,'>'))"/>
</xsl:call-template>
<xsl:call-template name="parseTag">
<xsl:with-param name="tag" select="$tag"/>
<xsl:with-param name="endTag" select="normalize-space($endTag)"/>
<xsl:with-param name="value"
select="substring-before(substring-after($str,concat('<',$tag,'>')),co
ncat('</',normalize-space($endTag),'>'))"/>
</xsl:call-template>
<xsl:choose>
<xsl:when test="substring($tag,string-length($tag))='/'">
<xsl:call-template name="parse">
<xsl:with-param name="str"
select="substring-after($str,concat('<',$tag,'>'))"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:call-template name="parse">
<xsl:with-param name="str"
select="substring-after($str,concat('</',normalize-space($endTag),'>')
)"/>
</xsl:call-template>
</xsl:otherwise>
</xsl:choose>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="$str"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="parseTag">
<xsl:param name="tag" select="''"/>
<xsl:param name="endTag" select="''"/>
<xsl:param name="value" select="''"/>
<xsl:element name="{translate($endTag,'/','')}">
<xsl:call-template name="attribs">
<xsl:with-param name="attrlist"
select="substring-after(normalize-space($tag),' ')"/>
</xsl:call-template>
<xsl:call-template name="parse">
<xsl:with-param name="str" select="$value"/>
</xsl:call-template>
</xsl:element>
</xsl:template>
<xsl:template name="attribs">
<xsl:param name="attrlist" select="''"/>
<xsl:variable name="name"
select="normalize-space(substring-before($attrlist,'='))"/>
<xsl:if test="$name">
<xsl:variable name="value">
<xsl:choose>
<xsl:when test="substring-before($attrlist,'="')">
<xsl:value-of
select="substring-before(substring-after($attrlist,'="'),'"')"/>
</xsl:when>
<xsl:when test="substring-before($attrlist,'= "')">
<xsl:value-of
select="substring-before(substring-after($attrlist,'= "'),'"')"/>
</xsl:when>
<xsl:when test="substring-before($attrlist,"='")">
<xsl:value-of
select="substring-before(substring-after($attrlist,"='"),&quo
t;'")"/>
</xsl:when>
<xsl:when test="substring-before($attrlist,"= '")">
<xsl:value-of
select="substring-before(substring-after($attrlist,"
='"),"'")"/>
</xsl:when>
</xsl:choose>
</xsl:variable>
<xsl:attribute name="{$name}">
<xsl:value-of select="$value"/>
</xsl:attribute>
</xsl:if>
<xsl:choose>
<xsl:when test="contains($attrlist,' ')">
<xsl:call-template name="attribs">
<xsl:with-param name="attrlist" select="substring-after($attrlist,
' ')"/>
</xsl:call-template>
</xsl:when>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list