Re: [xsl] Identifier attribute (was: Re: [xsl] Creating Hierarchy)

Subject: Re: [xsl] Identifier attribute (was: Re: [xsl] Creating Hierarchy)
From: Wendell Piez <wapiez@xxxxxxxxxxxxxxxx>
Date: Mon, 20 Oct 2008 18:00:13 -0400
Rowan,

Run as a second pass, a near-identity transform could append any input with identifiers, constructed however you like. Run on the result of an earlier transformation, the logic it would use to construct its identifiers would of course refer to that result, rather than to an earlier input. This makes it simpler and potentially much more robust.

So:

<xsl:template match="node()">
  <xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:apply-templates select="." mode="mark-id"/>
    <xsl:apply-templates/>
  </xsl:copy>
</xsl:template>

<xsl:template match="a | b | c | d" mode="mark-id">
  <!-- match any elements you want to mark with an id -->
  <xsl:attribute name="id">
    <xsl:number count="a | b | c | d" level="any"/>
  </xsl:attribute>
</xsl:template>

<xsl:template match="*" mode="mark-id"/>
<!-- matching other elements in the 'mark-id' mode does nothing -->

Note that this may place an attribute named 'id' on elements that already have one, in which case the old value will be overwritten.

Apart from that wrinkle, however, this is probably the most general way to approach the problem.

If you don't want to run your id-marking process as a second pass, it can be done in the main stylesheet too. But since there, the transformation must refer to the original source rather than its own result, constructing the identifiers (and being sure they are unique) can be complex. How complex depends on how complex the transformation is and the specific requirements for the id attributes (where they have to be, etc.).

Remember also that XSLT 2.0 can pipeline natively, so two passes can be achieved using one stylesheet.

I hope that helps,
Wendell


At 09:04 AM 10/20/2008, you wrote:
Thanks for all your comments. The XML file I need to create was designed by someone else and is interpreted by code which don't have access to. It has attributes with the name "id" and increasing integer values, so this is what I have to generate. I guess these don't use the id semantics. Using <xsl:number/> as suggested by Ken works fine in this particular case, and is very much easier than what I was trying to find a way of doing, which was rather than using the sequence number of the nodes in the input file, to work out how many nodes had been generated in the output file.

If there was no direct correspondence between the number of elements in the input file and the number in the output file (as may become the case with some enhancements that I'm planning), how would I calculate a value of this sort (let's call it a sequence value rather than an id to avoid the confusion)? E.g. if my output file needs to look something like the following, where all the a, b, c and d elements need to have an "id" (sequence) attribute with a steadily incrementing value through the file. There can be all sorts of other nodes (e and f in the example) at various levels in the tree which do not need id/sequence attributes. In this particular system the a elements can be nested to any depth, but there can be only one level of b, c and d elements within each sub-tree, but that's just the way this particular system works.

How would I generate these id/sequence values, either as a second pass, or as part of the first pass which generates this structure from the non-hierarchical source file?
<root>
<a id="1">
<b id="2">
<e/>
</b>
<b id="3">
<c id="4"/>
</b>
<b id="5">
<c id="6">
<d id="7">
<e/>
</d>
<d id="8"/>
</c>
<c id="9">
<d id="10">
<e/>
<f/>
</d>
<d id="11"/>
</c>
</b>
</a>
<a id="12">
<a id="13"/>
<a id="14">
<b id="15"/>
</a>
</a>
</root>


======================================================================
Wendell Piez                            mailto:wapiez@xxxxxxxxxxxxxxxx
Mulberry Technologies, Inc.                http://www.mulberrytech.com
17 West Jefferson Street                    Direct Phone: 301/315-9635
Suite 207                                          Phone: 301/315-9631
Rockville, MD  20850                                 Fax: 301/315-8285
----------------------------------------------------------------------
  Mulberry Technologies: A Consultancy Specializing in SGML and XML
======================================================================

Current Thread