This is the mail archive of the xsl-list@mulberrytech.com mailing list .


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Grouping repeating elements


Hi Till,

>hello
>
>I'm wondering if it's possible to group reapeating
>elements to a category. I tried some of the earlier
>posted solutions but couldn't solve this problem. I
>think, this could be solved with a <xsl:key
>...>-construction, but because I'm new to xml/xsl I
>couldn't figure it out.
>Any help would be appreciated.
>
>thanks
>till
>
>
>initial.xml
>
><persons>
>
>  <name>smith</name>
>  <firstname>john</firstname>
>  <age>28</age>
>
> <name>henderson</name>
>  <firstname>chris</firstname>
>  <age>68</age>
>
> <name>phil</name>
> <firstname>harrison</firstname>
>
> <name>alan</name>
>  <firstname>nilsen</firstname>
>  <age>28</age>
>
></persons>
>
>
>target xml
>
><persons>
>
>  <person>
>  <name>smith</name>
>  <firstname>john</firstname>
>  <age>28</age>
>  </person>
>
>  <person>
>  <name>henderson</name>
>  <firstname>chris</firstname>
>  <age>68</age>
>  </person>
>
>  <person>
>  <name>phil</name>
>  <firstname>harrison</firstname>
>  </person>
>
>  <person>
>  <name>alan</name>
>  <firstname>nilsen</firstname>
>  <age>28</age>
>  </person>
>
></persons>
>
This isn't realy a grouping problem as usually discussed on this list.
Grouping is about taking elements of the same kind and grouping
together those which share some characteristic.  For example if you
took your target output, sorted it by name/firstname then output a
heading for each new initial letter (as in an index) then that would
be a classical grouping problem.

What you are doing is taking elements of different kinds which appear
together in the input.  This is going to be messy because you are
trying to identify *implicit* structure in the input :- XSLT is at its
best when there is *explicit* structure - as in your target output.

To give you a full answer I would need to know the full details of
this implicit structure (and some money ;-).  In particular, which
elements are optional?  <age> obviously is, what about the others?

Assuming <name> is always there, and is always the first element for a
particular person, and you want a consistent order for the
sub-elements of each person regardless of the input order, then here
is an outline approach:

Have a template matching "name".
In the body of this template create the target <person> element,
copying the matched <name> element, e.g. using copy-of.
To handle elements which always appear, use copy-of with
following-sibling to get the *first* element after the name of the
given type.  Get this working first, and see that 'phil' ends up with
age 28.  Make sure everyone gets just one age!
When you have that XPath right, you now have to add a condition that
the node you find matches the current <name> node and not a later one.
So, add a further condition that the <name> node before the one you
have found is the same node as the one matched in your template: use
preceding-sibling and generate-id().

Have a try at this yourself, if you get stuck ask again.

Regards,
Trevor Nash
--
Traditional training & distance learning,
Consultancy by email

Melvaig Software Engineering Limited
voice:     +44 (0) 1445 771 271 
email:     tcn@melvaig.co.uk

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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]