Subject: Re: [xsl] Creating new, distinct groups of ranges from an aggregation of individual ranges From: "Michael Friedman sumarimike@xxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Date: Tue, 18 Nov 2014 22:53:21 -0000 |
Greetings,Note: My first reply email was too long and was rejected by the system. I hope this one is shorter. I removed the output, but it can be reproduced using the below. Wow - great suggestions and assistance. Heiko, your solution is very promising and is one I started testing. To answer your question, the gap you identified should be missing. These new ranges only show what SHOULD be output in the final XSLFO, so the gaps need to be omitted. Great catch.I'm including some excerpts of the current state of real data, your stylesheet with some modifications. I think the output is very close. I picked the worst scenario I could find in the ginormous data set I have. In my first email, I was abstractly describing the problem while I started to tackle the real code. My source data is formatted somewhat different than what I first described, but with an almost working solution, I'm going to include something very close to the actual code.My actual source XML is stored in multiple ranges. The ranges are formatted as a string of 8 characters with a space between range sets. I've modified the stylesheet to handle this structure. There is also a problem or two with the source data (see range 4010405, which is missing the leading zero. I add it in the stylesheet).I've collected the source ranges from actual XML, and converted it to ranges that match the stylesheet. Domain-wise, to explain: each <aircraft-range> contains a range of numbers. The numbers represent an individual tail-number of a plane. So the contents of the XML within the range apply to the various planes with that specific number. Example: <aircraft-range>02350240</aircraft-range>, means that the content in that "solution", where the range is, applies to the planes with tail number 235, 236, 237, 238, 239, and 240. Not to any other planes in the rest of the group.Actual ranges in XML:-----------------------------<group><aircraft-range>02010222 02250226 0228 0232 02350240 04010405 0408 0411 04150416</aircraft-range><aircraft-range>02010218 02200222 02250226 0228 0232</aircraft-range><aircraft-range>02350240</aircraft-range><aircraft-range >4010405 0408 0411 04150416</aircraft-range><aircraft-range>02130217 02570261 02860287 04010405 0408 0411 04150416</aircraft-range><aircraft-range>02510252 02550287 0290 0292 0296</aircraft-range><aircraft-range>02510252 02550287 0290 0292 0296 04510460</aircraft-range><aircraft-range>04510460</aircraft-range><aircraft-r ange>0205 0205</aircraft-range><aircraft-range>02110212 0235 02390240 02620263 02670269 0408 0453 04560460</aircraft-range><aircraft-range>02080210 02130218 02200222 02250226 0228 0232 02360238 02510252 02550261 02640266 02700287 0290 0292 0296 04010405 0411 04150416 04510452 04540455</aircraft-range><aircraft-range>02010204 02060207</aircraft-range><aircraft-range>02010222 02250226 0228 0232</aircraft-range><aircraft-range>02350240 02510252 02550287 0290 0292 0296 04010405 0408 0411 04150416 04510460</aircraft-range><aircraft-range>02010218 02200222 02250226 0228 0232 02350239 02510252 02550287 0290 0292 0296 04010405 0408 0411 04150416</aircraft-range><aircraft-range>0240 0240</aircraft-range><aircraft-range>04510460</aircraft-range><aircraft-range >02010207</aircraft-range><aircraft-range>02080213</aircraft-range><aircraft- range>02140222 02250226 0228 0232 02350240 02510252 02550285</aircraft-range><aircraft-range>02860287 0290 0292 0296 04010405 0408 0411 04150416 04510460</aircraft-range><aircraft-range>02010222 02250226 0228 0232 0235 02510252 02550285 04010405 0408 0411 04150416</aircraft-range><aircraft-range>02350240 02860287 0290 0292 0296 04510460</aircraft-range><aircraft-range>02350240 0290 0292 0296 04510460</aircraft-range><aircraft-range>02860287</aircraft-range></group> The XSLT:-------------<?xml version="1.0" encoding="UTF-8"?><!-- 2014 Michael Friedman --><!-- 2014 with help from Heiko Niemann and others via XSLT Guru list at Mulberry Tech --><!DOCTYPE stylesheet [<!ENTITY lb "
"]><xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format"xmlns:xs="http://www.w3.org/2001/ XMLSchema"version="2.0"> <xsl:output method="xml" encoding="UTF-8" indent="yes" /> <xsl:template match="/"><xsl:apply-templates select="//group"/></xsl:template> <xsl:template match="group"><xsl:comment>[group match]</xsl:comment><!-- Step 1, get the ranges --><!-- List of ranges, for reference --><xsl:comment>[Group Ranges: <xsl:text>&lb;</xsl:text><xsl:for-each select="descendant::aircraft-range"><xsl:value-of select="concat(position(),': ',.)"/><xsl:text>&lb;</xsl:text></xsl:for-each>]</xsl:comment><xsl:variable as="element()+" name="bounds"><xsl:for-each select="descendant::aircraft-range"><xsl:for-each select="tokenize(string(.), ' ')"><xsl:variable name="start"><xsl:choose><xsl:when test="string-length(.)=7 and not(starts-with(.,'0'))"><xsl:value-of select="concat('0',substring(.,1,3))"/></xsl:when><xsl:otherwise><xsl:value-of select="substring(.,1,4)"/></xsl:otherwise></xsl:choose></xsl:variable><xsl:v ariable name="end"><xsl:choose><xsl:when test="string-length(.)=7 and not(starts-with(.,'0'))"><xsl:value-of select="substring(.,4,4)"/></xsl:when><xsl:when test="string-length(.)=8"><xsl:value-of select="substring(.,5,4)"/></xsl:when><xsl:otherwise><xsl:value-of select="substring(.,1,4)"/></xsl:otherwise></xsl:choose></xsl:variable><range -start val="{$start}"/><range-end val="{$end}"/></xsl:for-each></xsl:for-each></xsl:variable><!-- Step 2, Remove duplicates and sort the boundaries --><xsl:variable as="element()" name="grouped"><grouped><xsl:for-each-group select="$bounds" group-by="@val"><xsl:sort select="@val"/><xsl:sequence select="current-group()[1]"/></xsl:for-each-group></grouped></xsl:variable><! -- Step 3: Adjust for range endings --><xsl:variable as="element()" name="completed"><completed><xsl:for-each select="$grouped/*"><xsl:copy><xsl:copy-of select="@*"/><xsl:choose><xsl:when test="local-name() = 'range-start'"><xsl:attribute select="following-sibling::range-start[1]/@val - 1" name="end"/></xsl:when><xsl:otherwise><xsl:attribute select="preceding-sibling::range-end[1]/@val + 1" name="beg"/></xsl:otherwise></xsl:choose></xsl:copy></xsl:for-each></complete d></xsl:variable><result><bounds><xsl:copy-of select="$bounds"/></bounds><grouped><xsl:copy-of select="$grouped/*"/></grouped><completed><xsl:copy-of select="$completed/*"/></completed><ranges><xsl:for-each-group group-starting-with="range-start | range-end[preceding-sibling::*[1]/local-name() eq 'range-end']" select="$completed/*"><xsl:variable name="range-start" select="current-group()[local-name() eq 'range-start'][1]"/><xsl:variable name="range-end" select="current-group()[local-name() eq 'range-end'][1]"/><range><xsl:value-of separator="-"><xsl:sequence select="($range-start/@val, $range-end/@beg, 'err')[1]"/><xsl:sequence select="($range-end/@val, $range-start/@end, 'err')[1]"/></xsl:value-of></range></xsl:for-each-group></ranges></result></x sl:template></xsl:stylesheet> I'm currently evaluating the output and hope to work out some of the bugs myself, as well. Thanks,Michael
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] Creating new, distinct gr, Imsieke, Gerrit, le- | Thread | Re: [xsl] Creating new, distinct gr, Imsieke, Gerrit, le- |
Re: [xsl] Creating new, distinct gr, Imsieke, Gerrit, le- | Date | Re: [xsl] Creating new, distinct gr, Imsieke, Gerrit, le- |
Month |