Subject: Re: [xsl] "Tunneling" a parameter in document order From: Christian Roth <roth@xxxxxxxxxxxxxx> Date: Thu, 12 Apr 2012 22:42:07 +0200 |
>> How do you go about such problems in general? Is there a best practice? > > Post a small complete sample input covering the various possibilities, > along with the required output for that input. > Before going further: I do *not* want anyone to create an XSLT that transforms the sample source to the desired result below! That would be time well wasted. I'm merely interested in ideas on how to tackle such a kind (or class?) of problem. Trying to describe the problem at a high level, that would essentially be: Keeping a (virtual) global variable's value current while doing a depth-first traversal of a document, where the variable's value is not scoped by either the document's element hierarchy, nor the nesting of XSLT template calls. Hoping to have gotten them right :-), here are source and desired result: -- source.xml -- <?xml version="1.0" encoding="UTF-8"?> <document> <listdefs> <list id="list1" restart="none"> <leveldef level="1" type="decimal"/> <leveldef level="2" type="lower-alpha"/> <leveldef level="3" type="lower-roman"/> </list> <list id="list2" restart="level"> <leveldef level="1" type="decimal"/> <leveldef level="2" type="decimal"/> <leveldef level="3" type="decimal"/> </list> </listdefs> <listrefs> <ref id="ref1" idref="list1"/> <ref id="ref2" idref="list1"> <override level="1" startat="5"/> </ref> <ref id="ref3" idref="list2"/> </listrefs> <body> <a> <b><item idref="ref1" level="1"/></b> <item idref="ref1" level="1"/> <c> <d><item idref="ref1" level="2"/></d> </c> </a> <item idref="ref1" level="3"/> <item idref="ref1" level="2"/> <e><item idref="ref1" level="3"/></e> <item idref="ref2" level="1"/> <item idref="ref2" level="2"/> <f> <item idref="ref3" level="1"/> </f> <item idref="ref3" level="2"/> <item idref="ref2" level="1"/> <g> <h><item idref="ref3" level="1"/></h> </g> <i><item idref="ref3" level="2"/></i> <item idref="ref2" level="3"/> </body> </document> --snip-- -- desired-result.xml -- <document> <body> <a> <b><item num="1" idref="ref1" level="1"/></b> <item num="2" idref="ref1" level="1"/> <c> <d><item num="2.a" idref="ref1" level="2"/></d> </c> </a> <item num="2.a.i" idref="ref1" level="3"/> <item num="2.b" idref="ref1" level="2"/> <e><item num="2.b.ii" idref="ref1" level="3"/></e> <item num="5" idref="ref2" level="1"/> <item num="5.c" idref="ref2" level="2"/> <f> <item num="1" idref="ref3" level="1"/> </f> <item num="1.1" idref="ref3" level="2"/> <item num="6" idref="ref2" level="1"/> <g> <h><item num="2" idref="ref3" level="1"/></h> </g> <i><item num="2.1" idref="ref3" level="2"/></i> <item num="6.c.iii" idref="ref2" level="3"/> </body> </document> --snip-- Think of each /document/listdefs/list representing the declaration of a global 3-element array of counters holding the current item number at that level while traversing the document in document order, and /document/listrefs/ref each being an indirection to the referenced list, resetting some level of the counter array when first referenced. Any occurrence of an <item> increments the counter by 1 for the specified list+level combination unless there's some reset override defined in the referenced list <ref>, which must only be applied the first time a <ref> is referred from the document's body. (I know this is all not too easy to understand, but that is basically how list numbering in OOXML is spec'd.) list1 is set to number each level continuously (restart="none"), list2 is set to restart numbering for a level when a lower level (or higher level - depends on how you name them...) is incremented (restart="level"). Here's what the 3-element array would look like at each element start during document traversal, resulting in the depicted numbering string (@num attribute) to be added to each <item> (see desired-result.xml): element list1 list2 ------------------------------- document 0 0 0 0 0 0 body | | | | | | a | | | | | | b | | | | | | item 1 | | | | | item 2 | | | | | c | | | | | | d | | | | | | item | 1 | | | | item | | 1 | | | item | 2 | | | | e | | | | | | item | | 2 | | | item 5 | | | | | <- new startat value for level 1 item | 3 | | | | f | | | | | | item | | | 1 | | item | | | | 1 | item 6 | | | | | <- @startat only applies once; subsequent refs just increment as usual g | | | | | | h | | | | | | item | | | 2 0 | <- level 2 is reset to "0" because a lower level was incremented i | | | | | | item | | | | 1 | item | | 3 | | | ------------------------------- Christian
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] "Tunneling" a parameter i, Andrew Welch | Thread | Re: [xsl] "Tunneling" a parameter i, Andrew Welch |
Re: [xsl] "Tunneling" a parameter i, Wendell Piez | Date | Re: [xsl] "Tunneling" a parameter i, Andrew Welch |
Month |