Re: REQUIRED vs. IMPLIED attributes

Subject: Re: REQUIRED vs. IMPLIED attributes
From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx>
Date: Sat, 22 Jul 2000 10:42:31 +0100
Bryan,

>(such as perhaps) Is there a generic way to code for 
>1. "grab any attribute and simply repeat it"
>
>or
>
>2. "grab IMPLIED attribute WHEN they're there
>    and deal with them"

XSLT processors do not know whether an attribute is declared as #REQUIRED
or #IMPLIED or has a default value or whatever.  All the XSLT processor can
see is the result given to it by the XML parser.  The XML parser that it
uses *may* look at the DTD and fill in the gaps accordingly (such as adding
#FIXED or defaulted attributes to elements), but the DTD contents won't be
made available to the XSLT processor.

[Aside: A side-effect of this is that the XSLT processor cannot tell the
difference between a defaulted attribute and an attribute declared with the
same value.]

If you were using an XML Schema rather than a DTD, then it would be
possible to access that schema and check whether an attribute is (the
equivalent of) #REQUIRED or #IMPLIED from there.  However, I think this is
over-engineering the problem.

It is fairly easy to copy the value of an attribute when it is there, and
not if it isn't, using an xsl:if element that tests on whether the
attribute is there:

<xsl:template match="Link">	
  <h2>
    <xsl:attribute name="name">
      <xsl:value-of select="./@linkid"/>
    </xsl:attribute>
    <xsl:if test="@date">
      <xsl:attribute name="date">
        <xsl:value-of select="./@date"/>
      </xsl:attribute>
    </xsl:if>
    <xsl:apply-templates/>
  </h2>
</xsl:template>

[Aside: Personally, I would shorten this template to:

  <xsl:template match="Link">	
    <h2 name="{@linkid}">              <!-- changed for brevity -->
      <xsl:if test="@date">
        <xsl:copy-of select="@date" /> <!-- changed for brevity -->
      </xsl:if>
      <xsl:value-of select="." />      <!-- changed for performance -->
    </h2>
  </xsl:template>
]

For a more generic solution, you can cycle through the attributes that are
present and make copies of them.  Naturally, this will capture all
#REQUIRED attributes (as they will be [*must* be] present) and any #IMPLIED
attributes that are around.

<xsl:template match="Link">
  <h2>
    <xsl:for-each select="@*">
      <xsl:copy />
    </xsl:for-each>
    <xsl:value-of select="." />
  </h2>
</xsl:template>

The problem with this approach is that you cannot change the names of the
attributes.  This involves using extra knowledge about the mapping between
the old names and the new names, which you have to either embed in the
template itself or make explicit elsewhere and reference from within the
template (let me know if you want to see an example).

I hope this helps,

Jeni

Dr Jeni Tennison
Epistemics Ltd * Strelley Hall * Nottingham * NG8 6PE
tel: 0115 906 1301 * fax: 0115 906 1304 * email: jeni.tennison@xxxxxxxxxxxxxxxx


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


Current Thread