tags:

views:

36

answers:

1

I have this snippet of XSLT code:

<xsl:variable name="key" select="@*[1]"/>

But I need it to actually set key to be the first attribute (if it exists) that doesn't have a special name. So both of these nodes would have the same key, and special_attr is ignored if it exists.

<MyNode var="1" />
<MyNode special_attr="foo" var="1" />

What is the proper select syntax to get the first attribute's value whose name isn't special_attr?

+3  A: 
<xsl:variable name="key" select="@*[not(name() = 'special_attr')][1]"/>
Tomalak
Unfortunately, this may not do exactly what you want, because in XPath, "the relative order of attribute nodes is implementation-dependent" (http://www.w3.org/TR/xpath/#dt-document-order). So it's theoretically a toss-up as to which attribute besides _special_attr_ will come first.
Owen S.
@Owen: Interesting, thanks. My request was to support this fix: http://www.codeproject.com/KB/XML/XMLOverride.aspx?msg=3527558#xx3527558xx, and part of his design uses the concept of "first attribute is the key"... it does work consistently in my implementation, but probably his design should better take the standard into account.
Scott Stafford
@Scott: Agreed. In cases where sequence is important, elements are what you want, not attributes.
Owen S.
@Scott: This is more by-the-book `(@*[not(name() = 'special_attr')])[1]`. Note the parentheses.
Tomalak
@Owen: See above comment.
Tomalak
@Tomiak: I believe the parens are redundant (predicates are always applied in turn to the node set determined by the axis and node test, see section 2.1 of the spec), and would have no bearing on the ordering of the node set.
Owen S.