Subject: Re: [xsl] Grouping with siblings From: "Terry Badger terry_badger@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Date: Sat, 22 Feb 2025 18:03:27 -0000 |
I wanted to try solving this problem and then using Oxygen's new AI to help with documentation. It seems to explain the templates reasonably well. I added one comment to explain the key logic I used which is the first comment. The following XSL creates the required output. <?xml version="1.0" encoding="UTF-8"?> <!-- TB-COMMENT WHEN USING FOR-EACH-GROUP STARTS WITH chapter AND p ELEMENTS THOSE ELEMENTS THAT IMPLY AN END B B B TO THEM IN SERIAL INPUT BECOME ELEMENTS WITH NO NODES EXCEPT THEMSELVES AND ARE EASILY ELIMINATED BY THE NODE COUNT IN THE XSL:CHOOSE. --> <!-- Transforms an XML document with a root element into a structured "book" format, organizing B B B "div" elements into "chapter" and "p" elements. Handles nested text and formatting elements, B B B ensuring proper grouping and formatting. --> <xsl:stylesheet exclude-result-prefixes="xs" expand-text="yes" version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" B B B xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> B B B <!-- Transforms an XML document with a root element into a structured "book" format. Groups and B B B B B B B processes "div" elements into "chapter" and "p" elements, handling nested text and formatting B B B B B B B elements. --> B B B <xsl:output indent="yes"/> B B B <xsl:strip-space elements="*"/> B B B <!-- Transforms the root element into a "book" element. Applies templates to process child nodes B B B B B B B within the "book" element. --> B B B <xsl:template match="/root"> B B B B B B B <xsl:element name="book"> B B B B B B B B B B B <xsl:apply-templates/> B B B B B B B </xsl:element> B B B </xsl:template> B B B <!-- Transforms "div" elements by grouping nodes into chapters and paragraphs. Constructs B B B B B B B structured XML output with chapter numbers, titles, and cleansed paragraph content. --> B B B <xsl:template match="div"> B B B B B B B <!-- Groups nodes starting with "chapter" and processes each group to create structured "chapter" B B B B B B B B B B B elements. It further groups nodes starting with "p" within each chapter, handling text and B B B B B B B B B B B formatting elements. --> B B B B B B B <xsl:for-each-group group-starting-with="chapter" select="node()"> B B B B B B B B B B B <!-- Processes and structures chapter elements based on their presence and attributes. Groups and B B B B B B B B B B B B B B B formats paragraph elements within chapters, handling text and specific formatting tags. --> B B B B B B B B B B B <xsl:choose> B B B B B B B B B B B B B B B <xsl:when test="count(current-group()/node()) = 0"/> B B B B B B B B B B B B B B B <xsl:otherwise> B B B B B B B B B B B B B B B B B B B <!-- Creates a "chapter" element with a "number" attribute and a "title" element, processing B B B B B B B B B B B B B B B B B B B B B B B grouped "p" elements. It removes extra spaces and line breaks, and copies "emphasis" and "bold" B B B B B B B B B B B B B B B B B B B B B B B elements within paragraphs. --> B B B B B B B B B B B B B B B B B B B <xsl:element name="chapter"> B B B B B B B B B B B B B B B B B B B B B B B <xsl:attribute name="number" select="current-group()/self::chapter/@n"/> B B B B B B B B B B B B B B B B B B B B B B B <xsl:element name="title"> B B B B B B B B B B B B B B B B B B B B B B B B B B B <xsl:value-of select="current-group()/self::chapter/@sID"/> B B B B B B B B B B B B B B B B B B B B B B B </xsl:element> B B B B B B B B B B B B B B B B B B B B B B B <!-- Groups elements starting with "p" and processes them based on their count. If more than one, B B B B B B B B B B B B B B B B B B B B B B B B B B B it creates a new "p" element, concatenating text and copying "emphasis" or "bold" elements. --> B B B B B B B B B B B B B B B B B B B B B B B <xsl:for-each-group group-starting-with="p" select="current-group()"> B B B B B B B B B B B B B B B B B B B B B B B B B B B <xsl:choose> B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B <xsl:when test="count(current-group()/normalize-space(self::node())) = 1"/> B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B <xsl:otherwise> B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B <xsl:element name="p"> B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B <xsl:for-each select="current-group()/(self::node())"> B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B <xsl:value-of select="replace(self::text(), '(B )|
|
', '')"/> B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B <xsl:copy-of select="self::emphasis | self::bold"/> B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B </xsl:for-each> B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B </xsl:element> B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B B </xsl:otherwise> B B B B B B B B B B B B B B B B B B B B B B B B B B B </xsl:choose> B B B B B B B B B B B B B B B B B B B B B B B </xsl:for-each-group> B B B B B B B B B B B B B B B B B B B </xsl:element> B B B B B B B B B B B B B B B </xsl:otherwise> B B B B B B B B B B B </xsl:choose> B B B B B B B </xsl:for-each-group> B B B </xsl:template> </xsl:stylesheet> Terry Badger On Saturday, February 15, 2025 at 11:07:11 PM EST, Liam R. E. Quin liam@xxxxxxxxxxxxxxxx <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote: On Sun, 2025-02-16 at 00:12 +0000, Martin Honnen martin.honnen@xxxxxx wrote: On 16/02/2025 01:00, Liam R. E. Quin liam@xxxxxxxxxxxxxxxx wrote: On Sat, 2025-02-15 at 20:49 +0000, rick@xxxxxxxxxxxxxx wrote: Thank you very much Martin. That got me going in the right direction. A quick note - in some cases group-by won't work well. An example can It was group-starting-with in the posted code, both the original and the suggestion I made (actually the code I spelled out used only group-starting-with but I also said that the existence of start and end marker elements kind of asked for the group-starting-with to wrap a group-ending-with. Yes, your approach was fine for the posterbs case, as i said. Itbs for when they try to take that approach to other applications. Sorry if i wasnbt clear. Best, liam -- Liam Quin,B https://www.delightfulcomputing.com/Available for XML/Document/Information Architecture/XSLT/XSL/XQuery/Web/Text Processing/A11Y training, work & consulting.Barefoot Web-slave, antique illustrations: B http://www.fromoldbooks.orgXSL-List info and archiveEasyUnsubscribe(by email)
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Grouping with siblings, Liam R. E. Quin liam | Thread | [xsl] [ANN] Calling Users of XML, X, B Tommie Usdin btusd |
Re: [xsl] xsl:for-each is not a loo, David Carlisle d.p.c | Date | [xsl] How to output the characters , Roger L Costello cos |
Month |