xsl-list
[Top] [All Lists]

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

2003-07-24 10:49:16
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 
"&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



<Prev in Thread] Current Thread [Next in Thread>