Re: [xsl] (consistency in select results?) converting attributes to nested tags recursively

Subject: Re: [xsl] (consistency in select results?) converting attributes to nested tags recursively
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Fri, 8 Feb 2002 20:25:57 +0000
Hi Edward,

> Thanks for your help this is mostly what I was looking for but I was
> hoping to do it in a way that used Template matches for the nodes
> for the following reasons.

OK. You still have to use a parameter to pass the attributes through
from template to template. But you can change the createTag template
into a template that matches attributes, as follows:

<xsl:template match="@*">
  <xsl:param name="attributes" select="../@*[position() > 1]" />
  <tag name="{name()}" value="{.}">
    <xsl:choose>
      <xsl:when test="$attributes">
        <!-- if there are more attributes, apply templates to them to
             create the tag element's content -->
        <xsl:apply-templates select="$attributes[1]">
          <xsl:with-param name="attributes"
                          select="$attributes[position() > 1]" />
        </xsl:apply-templates>
      </xsl:when>
      <xsl:otherwise>
        <!-- if there aren't any more attributes, apply templates to
             the content of the current attribute's parent element -->
        <xsl:apply-templates select="../*" />
      </xsl:otherwise>
    </xsl:choose>
  </tag>
</xsl:template>

Then for those attributes for which you need to create an element
named after the attribute, you can do something like:

<xsl:template match="@attrib1">
  <xsl:param name="attributes" select="../@*[position() > 1]" />
  <attrib1 value="{.}">
    <xsl:choose>
      <xsl:when test="$attributes">
        <xsl:apply-templates select="$attributes[1]">
          <xsl:with-param name="attributes"
                          select="$attributes[position() > 1]" />
        </xsl:apply-templates>
      </xsl:when>
      <xsl:otherwise>
        <xsl:apply-templates select="../TagB" />
      </xsl:otherwise>
    </xsl:choose>
  </attrib1>
</xsl:template>

Since the content of the two templates (and any more that you create)
are similar, you could make a separate named template to handle
creating the content of the elements.

For the tagA element, you need something like:

<xsl:template match="tagA">
  <xsl:apply-templates select="@*[1]" />
</xsl:template>

For the TagB element, it would be:

<xsl:template match="TagB">
  <TagB>
    <xsl:apply-templates select="@*[1]" />
  </TagB>
</xsl:template>

I hope that's closer to what you were after.

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list


Current Thread