[xsl] Comparing XML, xsl:normalize-space and schemaTron

Subject: [xsl] Comparing XML, xsl:normalize-space and schemaTron
From: "Fraser Goffin" <goffinf@xxxxxxxxxxx>
Date: Fri, 02 Dec 2005 15:14:09 +0000
Slightly confused about using normalize-space.

If I have the following XML instance document (notice the spaces) :-

<compare>
	<compareWith>   A</compareWith>
	<comparisonValues>
		<value>B</value>
		<value>   A   </value>
		<value>A </value>
	</comparisonValues>
</compare>

and I use this expression :-

normalize-space(/compare/comparisonValues/value[3]) = normalize-space(/compare/compareWith)

the result is true.

If I remove [3] it is an error ('too many items')

if I remove normalize-space and [3] from the LHS, the result is false.

and if I remove spaces from the final comparisonValues/value in the XML, the result is true

This seems OK (although it would be nice if I *could* use normalize-space on all of the nodes returned)

What I'm trying to do here to to compare the value in 1 node (compareWith) with all of the nodes within another node-set (comparisonValues/value) and, in the real example the node values I'm comparing will also be a >1, that is, I want to compare each value in node-set 1 to see it it matches any of the values in node set 2 and continue on until all of the nodes in node-set 1 have been checked (the real example is also comparing across 2 documents but I wanted to keep the example simple).

The catch is, I can't use a for-each !!! (so can it be done using apply/call-template ?)

Why not, well I'm implementing this in XSLT schemaTron 1.5 and I don't think its possible to express what I want using the rule (turns into template match='') and assertions (turn into 'choose'). The reference schemaTron only really uses call-template (and apply-templates). I suppose I could re-write the implementation but I'd rather not.

I like schemaTron, and I especially like the way that I can express the rules and assertions in an implementation neutral (ish) way. So I don't want to start extending the schemaTron vocabulary too much and loose that abstraction (that is, I *could* extend schemaTron (in places where it is allowed) to provide a pseudo for-each, but I really don't want to go there for a whole bunch of reasons not least of which that the portability of my rules would then be severely constrained).

I have also tried (successfully) using xsl:key + the key() function to create a set of the values in 1 document and then, using key(), check whether the value of a node in the other document exists in that set. This worked and I was able to do the compare using normalized-space values, but I am a bit wary of whether this approach is costly in terms of performance - can anyone comment ??

Anyway, having seem what I'm trying to acheive and what technologies I hoping to use, can anyone suggest some ideas that might move me on to the next stage.

Thanks

Fraser.

Current Thread