[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Re: XPath 2.0 expression that detects a cycle of refe

Subject: Re: XPath 2.0 expression that detects a cycle of references?
From: "Michael Müller-Hillebrand mmh@xxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Tue, 29 Mar 2016 11:19:49 -0000
Re:  XPath 2.0 expression that detects a cycle of  refe
> 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>

[demime 1.01d removed an attachment of type application/pgp-signature which had a name of signature.asc]

Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.