RE: [xsl] Techniques for transforming content like "&lt;tag&gt;content&lt;/tag&gt;" to "<tag>content</tag>"

Subject: RE: [xsl] Techniques for transforming content like "&lt;tag&gt;content&lt;/tag&gt;" to "<tag>content</tag>"
From: Américo Albuquerque <melinor@xxxxxxx>
Date: Thu, 24 Jul 2003 18:49:16 +0100
Hi

> -----Original Message-----
> From: owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx 
> [mailto:owner-xsl-list@xxxxxxxxxxxxxxxxxxxxxx] On Behalf Of 
> Karr, David
> Sent: Thursday, July 24, 2003 6:27 PM
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] Techniques for transforming content like 
> "&lt;tag&gt;content&lt;/tag&gt;" 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>&lt;userid&gt;98765&lt;/userid&gt;</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 &lt;node&gt;text&lt;/node&gt; 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,'&lt;')">
        <xsl:variable name="tag"
select="substring-before(substring-after($str,'&lt;'),'&gt;')"/>
        <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('&lt;',$tag,'&gt;'))"/>
        </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('&lt;',$tag,'&gt;')),co
ncat('&lt;/',normalize-space($endTag),'&gt;'))"/>
        </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('&lt;',$tag,'&gt;'))"/>
            </xsl:call-template>
          </xsl:when>
          <xsl:otherwise>
            <xsl:call-template name="parse">
              <xsl:with-param name="str"
select="substring-after($str,concat('&lt;/',normalize-space($endTag),'&gt;')
)"/>
            </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,'=&quot;')">
            <xsl:value-of
select="substring-before(substring-after($attrlist,'=&quot;'),'&quot;')"/>
          </xsl:when>
          <xsl:when test="substring-before($attrlist,'= &quot;')">
            <xsl:value-of
select="substring-before(substring-after($attrlist,'= &quot;'),'&quot;')"/>
          </xsl:when>
          <xsl:when test="substring-before($attrlist,&quot;=&apos;&quot;)">
            <xsl:value-of
select="substring-before(substring-after($attrlist,&quot;=&apos;&quot;),&quo
t;&apos;&quot;)"/>
          </xsl:when>
          <xsl:when test="substring-before($attrlist,&quot;= &apos;&quot;)">
            <xsl:value-of
select="substring-before(substring-after($attrlist,&quot;
=&apos;&quot;),&quot;&apos;&quot;)"/>
          </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


Current Thread