David from AIP recently asked a question on the listserv which gave me some interesting food for thought.
What was the problem?
Say you have document that looks like this:
<doc rids="doc"><citerefs rids="citerefs"/><doc/>
And you define the macro ‘citerefs’ as:
<ti;${./rids}>
compose will return the word ‘citerefs’.
The syntax ${./rids} refers to the attrbitue rids of the current element. And if the attribute is not there, it will return an empty string.
In the case of our sample document, it does not matter if you change the definition of the macro to the less preferred:
<ti;${rids}>
Compose will still return the word ‘citerefs’.
In xml mode, the form ${rids} will start a lookup for an attribute called ‘rids’. Compose will first look at the current element and if no such attribute exists, compose will look if this attribute can be found on the ancestors of the current element.
So if your document looks like:
<doc rids="doc"><citerefs/><doc/>
compose will return you the word doc as the current element citeref does not contain the requested attribute, but the parent doc does.
Also note that in non-xml mode, you can use also the form ${rids} . In which case it will refer to the value of the ‘named’ argument ‘rids’.
In xml mode as a general rule, if you really want to refer to the rids attribute of the current element (and nothing else), it is best to use the ${./rids} form. This is particulary true if you want to test for the presence of the attribute ($${./rids}).
And that is exactly what David did.
What was wrong with following the general rule?
Well there was a slight complication. In David’s case, the citerefs element was not sitting in the document itself, it was generated from a piece of xyperl code.
All of the sudden, the ${./rids} did no longer work. It just returned nothing.
Much to David’s (and mine as well) surprise, he could fix the problem by switching to the less preferred ${rids} syntax. In which case it returned the value we wanted to see: citerefs.
Does this mean the general rule is wrong?
Well no.
But let’s first look at how the xml document could look like:
<doc rids="doc"><xyperl/><doc/>
Here we would define the xyperl element so it calls a piece of XyPerl code that prints the <citerefs id=”citerefs”> string. As a result, the <xyperl/> elment gets replaced through compose by the <citerefs id=”citerefs”> string. So yo can easily be fooled in thinking that everything remained the same.
Well, it does not. Let me explain you why…
You probably know already that when we print a <citerefs id=”citerefs”>string from XyPerl, compose will only look for a macro definition of citerefs and not for an IF definition.
To me this means that when we print <..> strings from XyPerl, compose does not treat them as xml elements, but as classic macros.
So in this case, the ${./rids} form refers to the attribute that sits on the calling element (in our example that would be the <xyperl/> element) and as this element has no such attribute, compose simply returns an empty string.
But because the <citerefs id=”citerefs”> string is output by XyPerl, it is treated by compose as a classic macro (just like when you work in non-xml mode), ${rids} refers to the named argument of the <citerefs id=”citerefs”> macro. Hence, the ${rids} form does return the correct answer.
Well there you have the complete story…(well almost, see my next blog on XPP V8.2 for more on this topic).

No user commented on " The story of the current element "
Follow-up comment rss or Leave a Trackback