Subject: Re: [xsl] Issue with nested grouping From: Florent Georges <lists@xxxxxxxxxxxx> Date: Sun, 2 Dec 2007 20:49:43 +0100 (CET) |
Geert Bormans wrote: Hi Geert, > I have been looking at this for too long now, and I am > still not sure why this doesn't work > I have an XML (stripped down version of a word XML > document) That requires (nested) grouping, based on the > text content of some paragraphs. Personally, I wouldn't use for-each-group, but I would traverse the W:P elements one by one, starting at the first and then chaining the following sibling. If a W:P is starting a group, I create the group element and I apply the next sibling as content of the group, then I apply the next sibling of the corresponding ending group (with the same id) after the newly created group element. If a W:P is ending a group, I do nothing (that's the end recursion condition). In any other case I copy the node then I continue to the next following sibling. Here below is a complete stylesheet that shows that. Is it what you are looking for? Regards, --drkm Welcome to the Emacs shell ~/xslt/tests $ cat geert.xsl <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml" xmlns:wx="http://schemas.microsoft.com/office/word/2003/auxHint" xmlns:my="my:geert.xsl" version="2.0" exclude-result-prefixes="my xs"> <!-- ........................................................... Constant variables. --> <!-- RE matching the text of a group starting W:P/W:R/W:T. --> <xsl:variable name="group-start-re" select=" '^\[start\s+pgroup\s+id="([^"]+)".*$'"/> <!-- RE matching the text of a group ending W:P/W:R/W:T. --> <xsl:variable name="group-end-re" select=" '^\[end\s+pgroup\s+id="([^"]+)".*$'"/> <!-- ........................................................... Utility functions. --> <!-- Return the group id of a group starting W:P, may be (). --> <xsl:function name="my:group-start-id" as="xs:string?"> <xsl:param name="p" as="element(w:p)"/> <xsl:analyze-string select="$p/w:r/w:t" regex="{ $group-start-re }"> <xsl:matching-substring> <xsl:sequence select="regex-group(1)"/> </xsl:matching-substring> </xsl:analyze-string> </xsl:function> <!-- Return the group id of a group ending W:P, may be (). --> <xsl:function name="my:group-end-id" as="xs:string?"> <xsl:param name="p" as="element(w:p)"/> <xsl:analyze-string select="$p/w:r/w:t" regex="{ $group-end-re }"> <xsl:matching-substring> <xsl:sequence select="regex-group(1)"/> </xsl:matching-substring> </xsl:analyze-string> </xsl:function> <!-- Return the group ending W:P corresponding to a group starting W:P, may be (). --> <xsl:function name="my:group-closer" as="element(w:p)?"> <xsl:param name="p" as="element(w:p)"/> <xsl:variable name="id" select="my:group-start-id($p)"/> <xsl:if test="exists($id)"> <xsl:sequence select=" $p/following-sibling::w:p[my:group-end-id(.) eq $id]"/> </xsl:if> </xsl:function> <!-- ........................................................... Main template rules. --> <!-- Identity template. --> <xsl:template match="node()"> <xsl:copy> <xsl:copy-of select="@*"/> <xsl:apply-templates select="node()"/> </xsl:copy> </xsl:template> <!-- Handle a WX:SUB-SECTION, start the grouping recursion over following siblings. Launches the mode MY:GROUP. --> <xsl:template match="wx:sub-section"> <xsl:copy> <xsl:copy-of select="@*"/> <xsl:apply-templates select="w:p[1]" mode="my:group"/> </xsl:copy> </xsl:template> <!-- ........................................................... Mode: group. --> <!-- Handle a group starting W:P. --> <xsl:template match="w:p[exists(my:group-start-id(.))]" mode="my:group"> <pgroup id="{ my:group-start-id(.) }"> <xsl:apply-templates mode="my:group" select=" following-sibling::node()[1]"/> </pgroup> <xsl:apply-templates mode="my:group" select=" my:group-closer(.)/following-sibling::node()[1]"/> </xsl:template> <!-- Handle a group ending W:P. --> <xsl:template match="w:p[exists(my:group-end-id(.))]" mode="my:group"/> <!-- Identity template then recurse on the following sibling. --> <xsl:template match="node()" mode="my:group"> <xsl:copy> <xsl:copy-of select="@*"/> <xsl:apply-templates select="node()"/> </xsl:copy> <xsl:apply-templates mode="my:group" select=" following-sibling::node()[1]"/> </xsl:template> </xsl:stylesheet> ~/xslt/tests $ cat geert.xml <?xml version="1.0" encoding="UTF-8"?> <w:wordDocument xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml" xmlns:wx="http://schemas.microsoft.com/office/word/2003/auxHint"> <w:body> <wx:sect> <wx:sub-section> <w:p> <w:r><w:t>Text before first pgroup</w:t></w:r> </w:p> <w:p> <w:r><w:t>[start pgroup id="43210023"</w:t></w:r> </w:p> <w:p> <w:r><w:t>First P in pgroup</w:t></w:r> </w:p> <w:p> <w:r><w:t>Second P in pgroup.</w:t></w:r> </w:p> <w:p> <w:r><w:t>[start pgroup id="54320024"</w:t></w:r> </w:p> <w:p> <w:r><w:t>P in nested pgroup</w:t></w:r> </w:p> <w:p> <w:r><w:t>[end pgroup id="54320024"</w:t></w:r> </w:p> <w:p> <w:r><w:t>First P after nested group</w:t></w:r> </w:p> <w:p> <w:r><w:t>[end pgroup id="43210023"</w:t></w:r> </w:p> <w:p> <w:r><w:t>In between</w:t></w:r> </w:p> <w:p> <w:r><w:t>Other In between</w:t></w:r> </w:p> <w:p> <w:r><w:t>[start pgroup id="43210025"</w:t></w:r> </w:p> <w:p> <w:r><w:t>[start pgroup id="54320026"</w:t></w:r> </w:p> <w:p> <w:r><w:t>Isolated nested pgroup</w:t></w:r> </w:p> <w:p> <w:r><w:t>[end pgroup id="54320026"</w:t></w:r> </w:p> <w:p> <w:r><w:t>[end pgroup id="43210025"</w:t></w:r> </w:p> </wx:sub-section> </wx:sect> </w:body> </w:wordDocument> ~/xslt/tests $ saxon geert.xml geert-my.xsl <?xml version="1.0" encoding="UTF-8"?><w:wordDocument xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml" xmlns:wx="http://schemas.microsoft.com/office/word/2003/auxHint"> <w:body> <wx:sect> <wx:sub-section><w:p> <w:r><w:t>Text before first pgroup</w:t></w:r> </w:p> <pgroup id="43210023"> <w:p> <w:r><w:t>First P in pgroup</w:t></w:r> </w:p> <w:p> <w:r><w:t>Second P in pgroup.</w:t></w:r> </w:p> <pgroup id="54320024"> <w:p> <w:r><w:t>P in nested pgroup</w:t></w:r> </w:p> </pgroup> <w:p> <w:r><w:t>First P after nested group</w:t></w:r> </w:p> </pgroup> <w:p> <w:r><w:t>In between</w:t></w:r> </w:p> <w:p> <w:r><w:t>Other In between</w:t></w:r> </w:p> <pgroup id="43210025"> <pgroup id="54320026"> <w:p> <w:r><w:t>Isolated nested pgroup</w:t></w:r> </w:p> </pgroup> </pgroup> </wx:sub-section> </wx:sect> </w:body> </w:wordDocument> ~/xslt/tests $ _____________________________________________________________________________ Ne gardez plus qu'une seule adresse mail ! Copiez vos mails vers Yahoo! Mail
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] Issue with nested grouping, Geert Bormans | Thread | Re: [xsl] Issue with nested groupin, Florent Georges |
RE: RE: [xsl] Help with tree menu, cknell | Date | Re: [xsl] Issue with nested groupin, Florent Georges |
Month |