RE: [xsl] Reassinging attribute values

Subject: RE: [xsl] Reassinging attribute values
From: "Michael Kay" <mike@xxxxxxxxxxxx>
Date: Wed, 11 Jan 2006 13:24:03 -0000
You can't modify a tree. You have to copy the tree, modifying the attributes
as you go, so the attributes in the new tree are different from those in the
old. You can process a document in the usual way, a recursive descent using
xsl:apply-templates, extended so that it applies templates to attributes as
well as children; and then you simply need to define a template rule for the
attribute you want to modify that contains the necessary logic.

There's nothing wrong with the template rule you showed us, by the way; the
problem is in the way it gets invoked. Attributes of a constructed element
must be generated before the children of that element, so you can call this
template rule like this:

<newElement>
  <xsl:apply-templates select="topic"/>
  <childElement/>
</newElement>

but not like this:

<newElement>
  <childElement/>
  <xsl:apply-templates select="topic"/>
</newElement>

Michael Kay
http://www.saxonica.com/



> -----Original Message-----
> From: Cindy Hunt [mailto:Cindy.Hunt@xxxxxxx] 
> Sent: 11 January 2006 13:10
> To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx
> Subject: [xsl] Reassinging attribute values
> 
> In the effort to deal with our ID values not being unique 
> across a document, I am having to do some manipulation to the 
> ID values to get my link anchors and targets matching up 
> correctly. Many of our larger element types have what we call 
> an eid on them which is just an ID like so:
> 
> <topic eid="1234">
> 
> Because I need to make all of these unique while I transform 
> a document, I am pretty much tacking on information to the 
> front of the ID. Then I would like to reassign the old eid= 
> with my newly created value.
> 
> Here's what I was trying to do:
> 
> <xsl:template match="topic">
>    <xsl:variable name="newId" select="string manipulation to 
> get it how I want via checking xml:base, etc."/>
>    <xsl:attribute name="eid">{$newId}</xsl:attribute>
> </xsl:template>
> 
> Unfortunately, the Saxon parser doesn't allow the 
> xsl:attribute to be there. I get an error saying SYNTAX 
> WARNING::Cannot write an attribute node when no element start 
> tag is open. After doing some reading it seems like the 
> xsl:attribute and xsl:element tags only change these values 
> in the output document which I assume is for when you want to 
> do an XSL->XSL transformation. This isn't what I want so I 
> guess I need to find an alternative way to reassign the eid 
> attribute value.
> 
> If you saw my post yesterday title "Need assistance with 
> match string", this all relates. In that post, I was 
> massaging the eid used on the link anchor and in this one I 
> am trying to massage in on the link target in hopes that they 
> will both match and I can return the title of the topic. This 
> output of this transform is actually FO and I am not having 
> trouble with creating the link in FO (assigning the 
> fo:block's id to my $newId and creating an fo:basic-link to 
> that location and getting the correct fo:page-number-citation 
> returned for my cross-reference) but I am unable to grab the 
> title based on this massaged new eid value.
> 
> So basically I am looking for a way to change an attribute 
> value in the tree while I am processing the document. Is 
> there any way to do this?
> 
> Any suggestions would be greatly appreciated.
> 
> Thanks,
> Cindy Hunt

Current Thread