[XSL-LIST Mailing List Archive Home] [By Thread] [By Date]

RE: More XSL Discussion


Subject: RE: More XSL Discussion
From: Boris Moore <Boris.Moore@xxxxxxxxxx>
Date: Fri, 27 Feb 1998 11:51:49 +0100

Paul Prescod wrote (Feb 26) 
> Could you demonstrate how this problem would be solved in your language?
> I ask because having access to more context does not in itself solve the
> problem. It moves some of the complexity from the right hand side into
> the query, but unless you can match element patterns you will probably
> still have the same problem.

Here is an XML fragment - <a>'s interleaved with other element 
types (<b> and <c>)

<a>1.1 </a><b/><a>2.1 </a><a>2.2 </a><c/><a>3.1 </a><b/>
<a>4.1 </a><a>4.2 </a><a>4.3 </a><b/>

You wanted to wrap as a paragraph any series of more than one <a>

Well you asked me to show a solution in our language.  
I'm happy to, but I should mention that the syntax is in a temporary 
prototype version, and is not particularly elegant or familiar!

By way of explanation:
A stylesheet can contain several 'Stylesets' - similar to Modes.
It consists of one or more 'style' definitions, (similar to a construction
rule)  with a pattern on the left hand side and one or more 'Formats' on
the right.  

Formats are re-usable 'actions' which can 'wrap each other'.
e.g. [-foo-] format1 format2
which will apply format2 to any instance of foo to generate a subtree, 
and then apply format1 to the resulting subtree.

Functions are equivalent to Macros.

#DATA is equivalent to <children/>.

Within formats many built-in 'API functions' can be used.  
e.g $data(...) which can return the PCDATA content, element types or 
attribute values.
$ID(...) returns an ID (internal generated if not defined by an attribute) for 
any element or PCDATA instance.

Here is one stylesheet solution:

<-Styleset->
Test1
[-a-] Grouped_a
</-Styleset->

<-Formats->
[-Grouped_a-]  
$if($data(),$data(ID=$ID(nextsibling,-1)),
	else=$if($data(),$data(ID=$ID(nextsibling,1)),
		then=<P>
	)
)
#DATA
$if($data(),$data(ID=$ID(nextsibling,1)),
	else=$if($data(),$data(ID=$ID(nextsibling,-1)),
		then=</P>
	)
)
<-/Formats->

And here  is the  output as viewed in a browser

1.1 

2.1 2.2 

3.1 

4.1 4.2 4.3 

Here is another solution, (same output) using a more generic 'user 
defined function', $Series(...), which could be re-used whenever output 
needs to be conditional on sequential grouping of element types:

<-Styleset->
Test2
[-a-] Grouped_a2
</-Styleset->

<-Formats->
[-Grouped_a2-]  
$Series(first=<P>)
#DATA
$Series(last=</P>)
</-Formats->

<-Functions->
[-$Series(first,last,middle,single)-]
$if($data(),$data(ID=$ID(nextsibling,-1)),
	then=$if($data(),$data(ID=$ID(nextsibling,1)),
		then=middle,
		else=last
	),
	else=$if($data(),$data(ID=$ID(nextsibling,1)),
		then=first,
		else=single
	)
)
</-Functions->

Boris Moore 
RivCom


 XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list



Current Thread
Keywords
xml