xsl-list
[Top] [All Lists]

Re: [xsl] Combining of nested children

2012-09-06 00:30:00
Syd,
Thanks for your suggestions. As you can see, the requirements are a bit more complex than in the example I sent Here is the code I worked out that works for <Heading> but not at the nested <SubDiv1> level.
I get a "multiple-argument for concat" at the second level in this template.
I suspect I am doing something stupid, but not sure what the arguments of the second for-each-group should be.
Mark

<xsl:param name=" sorting-collation" select="'http://www.w3.org/2005/xpath-functions/collation/codepoint'"/> <!--<xsl:param name=" sorting-collation" select="'http://saxon.sf.net/collation?class=CzechCollation'"/>-->

<xsl:template match="List">
  <List>
    <!-- Group by  Heading -->
<!-- The ' ' separator between Heading and Heading/@entry insures proper sorting --> <xsl:for-each-group select="Item" group-by="concat(Heading/@data, Heading/@catalog, Heading/@scott-number, Heading/@pofis-number,' ',Heading/@entry) " collation="{$sorting-collation}"> <xsl:sort select="current-grouping-key()" collation="{$sorting-collation}"/>
      <Item>
        <Heading>
          <xsl:copy-of select="current-group()/Heading/@*"/>
          <xsl:copy-of select="current-group()/Heading/ToRef"/>
          <xsl:copy-of select="current-group()/Heading/Article"/>

<!-- <xsl:copy-of select="Heading/SubDiv1"/> Ignore this line it substitutes for the code below without inserting the <ToRef>-->

<!-- This is failing
<xsl:for-each-group select="current-group()" group-by="concat(Heading/SubDiv1/@data, Heading/SubDiv1/@catalog, Heading/SubDiv1/@scott-number, Heading/SubDiv1/@pofis-number)"> <xsl:sort select="current-grouping-key()" collation="{$sorting-collation}"/>
            <xsl:if test="Heading/SubDiv1">
              <xsl:element name="SubDiv1">
                <xsl:copy-of select="current()/Heading/SubDiv1/@*"/>
<xsl:copy-of select="current-group()/Heading/SubDiv1/ToRef"/> <xsl:copy-of select="current-group()/Heading/SubDiv1/Article"/>
                <xsl:copy-of select="Heading/SubDiv1/SubDiv2"/>
              </xsl:element>
            </xsl:if>
          </xsl:for-each-group>
-->
        </Heading>
      </Item>
    </xsl:for-each-group>
  </List>
</xsl:template>

-----Original Message----- From: Syd Bauman
Sent: Wednesday, September 05, 2012 9:28 PM
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: Re: [xsl] Combining of nested children

Not sure I understand the requirements completely, but given your
input, the following does produce the desired output.

---------
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
xmlns:xs="http://www.w3.org/2001/XMLSchema"; exclude-result-prefixes="xs" version="2.0">

 <!-- standard easy-to-write identity template -->
 <xsl:template match="@*|node()">
   <xsl:copy>
     <xsl:apply-templates select="@*|node()"/>
   </xsl:copy>
 </xsl:template>

 <!-- process a heading that has an @id specially: -->
 <xsl:template match="Heading[@id]">
   <xsl:copy>
     <!-- first, process my attributes -->
     <xsl:apply-templates select="@*"/>
     <!-- then, copy over desired <ToRef> -->
     <xsl:apply-templates
select="../../Item/Heading[ not(@id) and @entry = current()/@entry and @data eq current()/@data ]/ToRef"/>
     <!-- last, process my children -->
     <xsl:apply-templates select="node()"/>
   </xsl:copy>
 </xsl:template>

<!-- ignore <Item>s that have <Heading>s from which we already took the <ToRef> --> <!-- (Note that this code does not check to see that we actually took or will --> <!-- take the <ToRef> ? rather it just tests if there is no id= attr, and figures --> <!-- that if there is not an id=, then the entry= and data= must have matched. -->
 <xsl:template match="Item[Heading[not(@id)]]"/>

</xsl:stylesheet>
---------


I need to find <Items> in a <List> that have an identical <Heading>
attributes except for the @id, and insert a <ToRefs> element from
the <Item> without an @id into the <Item> that has the @id
attribute. Sample input and output <Item>s are shown below.

I will need to do the same sort of insertion at the <SubDiv1>
level, or at the two other possible nested levels of <SubDiv2> and
<SubDiv3> [not shown].

I will try to figure out how to do those latter cases once I
understand how to do the <Headings> case.

Any help appreciated,

Input:

<List>
  <Item>
    <Heading id="A4" entry="subject" data="Abolition of Serfdom">
      <SubDiv1 id="A4-1" catalog="1" scott-number="350" pofis-number="474"
data="1948. 100th Anniversary of Abolition">
        <Article>
          <Person>Bulletin of the Ministry of Posts</Person>
          <Title>New issues [Title varies or absent]</Title>
        </Article>
      </SubDiv1>
    </Heading>
  </Item>
  <Item>
    <Heading entry="subject" data="Abolition of Serfdom">
<ToRef xref="See also" data="Slovakia - Peasant Revolt 1848" file="s"
block="A1272-21"/>
    </Heading>
  </Item>
</List>

Output:
<List>
  <Item>
    <Heading id="A4" entry="subject" data="Abolition of Serfdom">
<ToRef xref="See also" data="Slovakia - Peasant Revolt 1848" file="s"
block="A1272-21"/>
      <SubDiv1 id="A4-1" catalog="1" scott-number="350" pofis-number="474"
data="1948. 100th Anniversary of Abolition">
        <Article>
          <Person>Bulletin of the Ministry of Posts</Person>
          <Title>New issues [Title varies or absent]</Title>
        </Article>
      </SubDiv1>
    </Heading>
  </Item>

--~------------------------------------------------------------------
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>
--~--




--~------------------------------------------------------------------
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>