xsl-list
[Top] [All Lists]

Re: [xsl] Wrap changing element sequence into container: with 'for-each-group'?

2007-01-31 08:32:39
David Carlisle schrieb:

It's so much easier if you provide an example, failing that I'll provide
one:-)

I apologize for wasting your time by having you guess what I mean instead of giving an example right away. As was to be expected, my longish explanations would mislead you about what I was looking for... So I shamefully promise to get better - here is a realistic example I was able to craft.

input.xml (I left blank lines to emphasize the variations):

<root>
  <flatsequence>
    <a>a</a>
    <b>b</b>
    <c>c</c>
    <d>d</d>
    <e>e</e>
    <f>f</f>

    <h>h</h>
    <i>i</i>
    <j>j</j>
  </flatsequence>
  <flatsequence>
    <a>a</a>

    <c>c</c>
    <d>d</d>
    <e>e</e>
    <f>f</f>
    <g>g</g>
    <h>h</h>
    <i>i</i>
    <j>j</j>
  </flatsequence>
</root>


desired output:

<root>
  <hierarchy>
    <a>a</a>
    <container1>
      <b>b</b>
      <c>c</c>
    </container1>
    <d>d</d>
    <e>e</e>
    <f>f</f>
    <container2>

      <h>h</h>
      <i>i</i>
    </container2>
    <j>j</j>
  </hierarchy>
  <hierarchy>
    <a>a</a>
    <container1>

      <c>c</c>
    </container1>
    <d>d</d>
    <e>e</e>
    <f>f</f>
    <container2>
      <g>g</g>
      <h>h</h>
      <i>i</i>
    </container2>
    <j>j</j>
  </hierarchy>
</root>


This is, I want to group certain element sequences (of which the first element may be optional) that are occurring within a flat sequence into some container, and group other element sequences within the same flat sequence the same way into other containers, while leaving the rest unchanged. The elements to group, however, are not easily identified formally as their names are dissimilar, so I suppose I will have to spell out their names.

Your last style sheet suggestion was fine. Adapting it to my example lets me create container1 in the case above, but I am stuck as far as creating container2 in the same run is concerned:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>

  <xsl:output indent="yes"/>

  <xsl:template match="root">
    <xsl:copy>
      <xsl:apply-templates/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="flatsequence">
    <hierarchy>
      <xsl:for-each-group
        select="*" group-adjacent="exists(self::b|self::c)">
<!-- how to match g, h and i as well within the same "for-each-group"? -->
        <xsl:choose>
          <xsl:when test="current-grouping-key()">
            <container1>
              <xsl:copy-of select="current-group()"/>
            </container1>
          </xsl:when>
          <!-- how to group g, h and i into container2? -->
          <xsl:otherwise>
            <xsl:copy-of select="current-group()"/>
          </xsl:otherwise>
        </xsl:choose>
      </xsl:for-each-group>
    </hierarchy>
  </xsl:template>

</xsl:stylesheet>


How to care, in the same pass, for container2 (and a finite number of other containers), which have no "derivable" relation to the elements they are to group?

Do I have to apply some kind of tree-walking or recursion?

  Yves

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--

<Prev in Thread] Current Thread [Next in Thread>