Subject: Re: [xsl] XPath 2.0 expression that detects a cycle of references? From: "Dimitre Novatchev dnovatchev@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> Date: Thu, 31 Mar 2016 04:41:11 -0000 |
>> Dimitre has an article on using two anonymous function together with "let", to implement the recursion: >> >> https://dnovatchev.wordpress.com/2012/10/15/recursion-with-anonymous-inline-f unctions-in-xpath-3-0-2/ > > Wow, 2012! And mentioning Roger Costellob& There are two other places where this technique was presented: [1] Balisage 2013, "Programming in XPath 3.1" [2] The Evolution of XPath: Whatbs New in XPath 3.0 -- a video training course at Pluralsight, 2013 Programming in pure XPath is a powerful way of producing valuable modules that are completely portable and independent of any vendor-specific XSLT or XQuery processors -- thus achieving maximum spread and (re)usability regardless of platform or programming language. This could be one reason why XSLT/XQuery vendors -- even those who are aware of this -- rarely, if at all, mention XPath programming... :) Roger certainly knows about this technique, because he was de facto a co-author of [1]. This is why he specifically asks about an XPath 2.0 solution. The technique described in [1] and [2] was used (in a comprehensive example) for implementing, instantiating and using a new, custom-defined data-type in XPath 3.0 -- the Binary Search Tree datatype. While the Balisage paper was limited in time, the Pluralsight course dedicates a single, 40-minutes module on XPath 3.0 programming, preceded by another 17 minutes+ single clip on implementing recursion using anonymous functions in XPath 3.0. Links: [1] Paper: http://www.balisage.net/Proceedings/vol10/html/Novatchev01/BalisageVol10-Nova tchev01.html , Slides: http://www.balisage.net/Proceedings/vol10/author-pkg/Novatchev01/BalisageVol1 0-Novatchev01.html [2] Course: https://www.pluralsight.com/courses/xpath-3-0-whats-new Cheers, Dimitre On Tue, Mar 29, 2016 at 4:19 AM, Michael MC<ller-Hillebrand mmh@xxxxxxxxx <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote: > >> Martin Honnen wrote: >> >>> I have no idea how one would have to handle this using XPath 3b& any suggestions? >> >> Dimitre has an article on using two anonymous function together with "let", to implement the recursion: >> >> https://dnovatchev.wordpress.com/2012/10/15/recursion-with-anonymous-inline-f unctions-in-xpath-3-0-2/ > > Wow, 2012! And mentioning Roger Costellob& > > Assuming my original function worked correctly, this would be the XPath 3.0 version of it: > > let $f := function( > $this as element()+, > $visited as xs:string*, > $f1 as function(element(), xs:string*, function(*)) as xs:boolean > ) as xs:boolean > { > let $refId := $this/for-more-info/@idref, > $refTgt := $this/../item[@id = $refId] > return > if (not(exists($refTgt))) then false() > else if ($refId = $visited) then true() > else some $e in $refTgt satisfies $f1($e, ($visited, $refId), $f1) > } > return $f(., (), $f) > > At least with Saxon 9.6.0.7 (in Oxygen) in gives the same results. > > Thanks a lot for hints, I learned quite a bit! > > - Michael > > Complete example: > > Input: > > <?xml version="1.0" encoding="UTF-8"?> > <document> > <item id="HF"> > <title>Huckleberry Finn</title> > <for-more-info idref="MT"/> > </item> > <item id="MT"> > <name>Mark Twain</name> > <for-more-info idref="SP"/> > <for-more-info idref="ZP"/> > </item> > <item id="SP"> > <publisher>Springer</publisher> > <for-more-info idref="HF"/> > </item> > <item id="XP"> > <publisher>XPress</publisher> > <for-more-info idref="HF"/> > </item> > <item id="YP"> > <publisher>YPress</publisher> > <for-more-info idref="ZP"/> > </item> > <item id="ZP"> > <publisher>ZPress</publisher> > </item> > </document> > > Stylesheet including both options as attributes cycle2 (XSLT function) and cycle3 (Xpath 3.0): > > <?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" > xmlns:my="my" exclude-result-prefixes="#all" > version="3.0"> > > <xsl:output indent="yes"/> > > <xsl:template match="document"> > <report> > <xsl:for-each select="item"> > <xsl:copy> > <xsl:copy-of select="@id"/> > <xsl:attribute name="cycle2" select="my:CycleFound(., ())"/> > <xsl:attribute name="cycle3" > select=" > let $f := function( > $this as element()+, > $visited as xs:string*, > $f1 as function(element(), xs:string*, function(*)) as xs:boolean > ) as xs:boolean > { > let $refId := $this/for-more-info/@idref, > $refTgt := $this/../item[@id = $refId] > return > if (not(exists($refTgt))) then false() > else if ($refId = $visited) then true() > else some $e in $refTgt satisfies $f1($e, ($visited, $refId), $f1) > } > return $f(., (), $f) > " > /> > </xsl:copy> > </xsl:for-each> > </report> > </xsl:template> > > <xsl:function name="my:CycleFound" as="xs:boolean"> > <xsl:param name="this" as="element()?"/> > <xsl:param name="visited" as="xs:string*"/> > <xsl:variable name="refId" select="$this/for-more-info/@idref" as="xs:string*"/> > <xsl:variable name="refTgt" select="$this/../item[@id = $refId]" as="element()*"/> > > <xsl:sequence select=" > if (not(exists($refTgt))) then false() > else if ($refId = $visited) then true() > else some $e in $refTgt satisfies my:CycleFound($e, ($visited, $e/@id)) > "/> > </xsl:function> > > </xsl:stylesheet> > > -- Cheers, Dimitre Novatchev --------------------------------------- Truly great madness cannot be achieved without significant intelligence. --------------------------------------- To invent, you need a good imagination and a pile of junk ------------------------------------- Never fight an inanimate object ------------------------------------- To avoid situations in which you might make mistakes may be the biggest mistake of all ------------------------------------ Quality means doing it right when no one is looking. ------------------------------------- You've achieved success in your field when you don't know whether what you're doing is work or play ------------------------------------- To achieve the impossible dream, try going to sleep. ------------------------------------- Facts do not cease to exist because they are ignored. ------------------------------------- Typing monkeys will write all Shakespeare's works in 200yrs.Will they write all patents, too? :) ------------------------------------- Sanity is madness put to good use. ------------------------------------- I finally figured out the only reason to be alive is to enjoy it.
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
Re: [xsl] XPath 2.0 expression that, Michael Müller-Hille | Thread | [xsl] Code generation template stru, Joseph L. Casale jca |
Re: [xsl] XPath 2.0 expression that, Michael Müller-Hille | Date | |
Month |