Re: [xsl] Grouping by attribute

Subject: Re: [xsl] Grouping by attribute
From: Jostein Austvik Jacobsen <josteinaj@xxxxxxxxx>
Date: Thu, 22 Oct 2009 15:54:57 +0200
What I didn't mention earlier is that the quote's can't have text
nodes right underneath themselves. All-in-all I have found this to
solve my problem (the last one mentioned anyway, not the one that
started the thread - but inspired by it):

	<xsl:template match="p">
		<xsl:for-each-group select="./node()" group-starting-with="p | quote
| illustration">
			<xsl:choose>
				<xsl:when test="(name(current-group()[1])='p') or
(name(current-group()[1])='quote'))">
					<xsl:apply-templates select="current-group()[1]"/>
					<p>
						<xsl:apply-templates select="current-group()[position()>1]"/>
					</p>
				</xsl:when>
				<xsl:otherwise>
					<p>
						<xsl:apply-templates select="current-group()"/>
					</p>
				</xsl:otherwise>
			</xsl:choose>
		</xsl:for-each-group>
	</xsl:template>

	<xsl:template match="quote">
		<quote>
			<xsl:for-each-group select="./node()" group-starting-with="p">
				<xsl:choose>
					<xsl:when test="name(current-group()[1])='p'">
						<xsl:apply-templates select="current-group()[1]"/>
						<p>
							<xsl:apply-templates select="current-group()[position()>1]"/>
						</p>
					</xsl:when>
					<xsl:otherwise>
						<p>
							<xsl:apply-templates select="current-group()"/>
						</p>
					</xsl:otherwise>
				</xsl:choose>
			</xsl:for-each-group>
		</quote>
	</xsl:template>

Which on the previously stated input gives:

<body>
	<!-- case 1 -->
	<p>text</p>

	<!-- case 2 -->
	<quote>
		<p>
			text
		</p>
		<p>text</p>
		<p>
			text
			<span>text</span>
		</p>
	</quote>

	<!-- case 3 -->
	<quote>
		<p>
			text
		 </p>
	</quote>
	<p/>

	<!-- case 4 -->
	<p>
		text
	</p>
	<quote>
		<p>text</p>
	</quote>
	<p>
		text
		<span>text</span>
		text
	</p>
</body>

Thanks for the help folks.
Jostein

2009/10/21 Jostein Austvik Jacobsen <josteinaj@xxxxxxxxx>:
> <quote> tags were occuring inside <p> tags, which they are not allowed
> to do. Initially <quote> tags are the only thing I need to move out of
> <p>. So:
>
> <body>
>  <!-- case 1 -->
>  <p>text<p>
>
>  <!-- case 2 -->
>  <quote>
>    text
>    <p>text</p>
>    text
>    <span>text</span>
>  </quote>
>
>  <!-- case 3 -->
>
>  <p><quote>text</quote></p>
>
>  <!-- case 4 -->
>
>  <p>
>    text
>    <quote>text</quote>
>    text
>    <span>text</quote>
>    text
>  </p>
> </body>
>
> should become:
>
> <body>
>  <!-- case #1 -->
>  <p>text</p>
>
>  <!-- case #2 -->
>  <quote>
>    text
>    <p>text</p>
>    text
>    <span>text</span>
>  </quote>
>
>  <!-- case #3 -->
>  <quote>text</quote>
>
>  <!-- case #4 result #1 -->
>
>  <p>text</p>
>  <quote>text</quote>
>  <p>
>    text
>    <span>text</span>
>    text
>  </p>
> </body>
>
> I'm not sure if the last p actually turns into three p's:
>
>  <!-- case #4 result #2 -->
>  <p>text</p>
>  <p><span>text</span></p>
>  <p>text</p>
>
> Result #1 would be best, but result #2 this is also acceptable. I'll
> check tomorrow what is actually happening. In any case, it validates
> against the DTD used and the result is working as expected.
>
> -Jostein
>
> 2009/10/21 Wendell Piez <wapiez@xxxxxxxxxxxxxxxx>
>>
>> Jostein,
>>
>> At 08:33 AM 10/21/2009, you wrote:
>>>
>>> Nice. I modified it slightly for the more complex structure of the
>>> actual XML, but you essentially solved it.
>>
>> But ... as so often, the problem as specified is just the tip of what could
be a much larger iceberg.
>>
>> What if your data has
>>
>> <p>
>>  text <span>more text</text> text
>>  <quote>text</quote>
>>  text
>>  <quote>text</quote>
>>  text
>> </p>
>>
>> What do you want to happen then?
>>
>> By generating p elements only when you match "text()[parent::p]" (or,
equivalently, "p/text()"), you succeed in splitting out all the text node
children of p from their sibling elements. But your problem specification
didn't actually say this was what you wanted to do -- and the problem of
splitting only some of the elements is at least as common.
>>
>> For that problem, you do in fact want to use grouping. (And I think it came
up quite recently on the list).
>>
>> Cheers,
>> Wendell
>>
>>
>>
>> ======================================================================
>> Wendell Piez                            mailto:wapiez@xxxxxxxxxxxxxxxx
>> Mulberry Technologies, Inc.                http://www.mulberrytech.com
>> 17 West Jefferson Street                    Direct Phone: 301/315-9635
>> Suite 207                                          Phone: 301/315-9631
>> Rockville, MD  20850                                 Fax: 301/315-8285
>> ----------------------------------------------------------------------
>>  Mulberry Technologies: A Consultancy Specializing in SGML and XML
>> ======================================================================

Current Thread