<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description></description><title>john.snelson.org.uk</title><generator>Tumblr (3.0; @johnpcsnelson)</generator><link>http://john.snelson.org.uk/</link><item><title>RDF for XML Enthusiasts</title><description>&lt;p&gt;I’ve been learning RDF and SPARQL for a while now, and recently I had the chance to talk to a number of MarkLogic customers who are using RDF with or alongside MarkLogic. One of the results of that is this presentation, which I gave at XML Prague this weekend.&lt;/p&gt;
&lt;p&gt;&lt;iframe frameborder="0" src="http://prezi.com/embed/3qhmoo4u31up/?bgcolor=ffffff&amp;amp;amp;lock_to_path=0&amp;amp;amp;autoplay=no&amp;amp;amp;autohide_ctrls=0"&gt;&lt;/iframe&gt;&lt;/p&gt;</description><link>http://john.snelson.org.uk/post/48547559632</link><guid>http://john.snelson.org.uk/post/48547559632</guid><pubDate>Sun, 10 Feb 2013 13:06:00 +0000</pubDate></item><item><title>I need a place to host a photo of me</title><description>&lt;img src="http://24.media.tumblr.com/84caa6b2ea9d1f907394b75bea937ae0/tumblr_mlme63mAqF1s7y0gno1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;&lt;h2&gt;I need a place to host a photo of me&lt;/h2&gt;&lt;/p&gt;</description><link>http://john.snelson.org.uk/post/48547566231</link><guid>http://john.snelson.org.uk/post/48547566231</guid><pubDate>Thu, 17 May 2012 16:37:17 +0100</pubDate></item><item><title>On determining itemtype-subtype() for recursive types</title><description>&lt;p&gt;There were questions as to whether type checking using a lenient recursive type alias like I proposed in my previous post would terminate. I&amp;#8217;ve been doing some research - so if like me you struggle to know the correct academic term to use to search for information, here is a handy guide:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="font-size: medium;"&gt;Equirecursive types:&lt;/span&gt;&lt;/strong&gt; The kind of type recursion we&amp;#8217;re talking about for XSLT 3.0. More formally, a type system where A is considered the same type as B, given:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&amp;lt;xsl:type-alias name="A" as="map(xs:string, A)"/&amp;gt;
&amp;lt;xsl:type-alias name="B" as="map(xs:string, map(xs:string, B))"/&amp;gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;In other words, a recursive type is considered equal to it&amp;#8217;s unrolling by one level.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="font-size: medium;"&gt;Isorecursive types:&lt;/span&gt;&lt;/strong&gt; Recursive types that provide new type annotations. An unrolled isorecursive type is not considered equal to the original type. These are apparently considered simpler to reason about than equirecursive types.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span style="font-size: medium;"&gt;Unification:&lt;/span&gt;&lt;/strong&gt; An algorithm that allows you to check equality of two types (well, directed graphs actually). If implemented correctly, it handles graphs with cycles (recursive types), as well as graphs with variables (parametric types). Incidently the same algorithm an be used for both pattern matching and type inference.&lt;/p&gt;
&lt;p&gt;My source material for the algorithm comes from the &lt;a href="http://www.amazon.com/Compilers-Principles-Techniques-Tools-2nd/dp/0321486811"&gt;&amp;#8220;Dragon Book&amp;#8221;&lt;/a&gt;, section 6.5.5. The unification algorithm for ItemType equality would look something  like this:&lt;/p&gt;
&lt;p&gt;1) Express the types as directed graphs with type aliases expanded (I&amp;#8217;ve  numbered the nodes so I can refer to them later):&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&amp;lt;!-- Slightly different defintion of B this time --&amp;gt;
&amp;lt;xsl:type-alias name="A" as="map(xs:string, A)"/&amp;gt;
&amp;lt;xsl:type-alias name="B" as="map(xs:string, map(xs:NMTOKEN, B))"/&amp;gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;A:         map[1]-+
            /\    |
           /  ----+
xs:string[2]&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;B:         map[3]-----+
            /\        |
           /  \       |
xs:string[4]   map[5] |
               /\     |
              /  -----+
  xs:NMTOKEN[6]&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;2) The basic idea is to start with two nodes from the graphs, M and N,  that you want to assert are equal. The algorithm keeps track of sets of  nodes that must be equal for this assertion to be true, called  equivalence classes. Equivalence classes are represented by a single  node picked from that set.&lt;/p&gt;
&lt;p&gt;3) find(n) returns the node representing the equivalence class for the  node n. Each node starts off in it&amp;#8217;s own equivalence class, and these  classes get merged successively by the union(m,n) procedure.&lt;/p&gt;
&lt;p&gt;4) The algorithm proceeds:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;boolean unify(M, N) {
   S = find(M), T = find(N);
   if(S = T) return true;
   if(S and T have the same node label and the same number of children) {
     union(S, T);
     return every child s in S, child t in T satisfies unify(s, t)
   }
   return false;
}&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;5) The algorithm terminates because the number of equivalence classes is  reduced by 1 for each recursion.  Finally, we can extend the notion of unification to use equivalence  classes based on itemtype-subtype() rules.  We only need to make sure  that every node in the equivalence class is a subtype of the  representative node. By doing so, our unification algorithm verifies a  subtype relationship rather than an equality relationship.&lt;/p&gt;
&lt;p&gt;A working of the itemtype-subtype() algorithm for the types I named A  and B above:&lt;/p&gt;
&lt;p&gt;i) Equivalence classes: (map[1]), (xs:string[2]), (map[3]), (xs:string[4]),  (map[5]), (xs:NMTOKEN[6])&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;unify(map[1], map[3])
   - S = map[1], T = map[3]
   - S and T are matching non-leaf nodes
   - union(S, T)
   - recursively check the children&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;ii) Equivalence classes: (map[1], map[3]), (xs:string[2]), (xs:string[4]),  (map[5]), (xs:NMTOKEN[6])&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;unify(xs:string[2], xs:string[4])
   - S = xs:string[2], T = xs:string[4]
   - S is a subtype of T
   - union(S, T)
   - return true (no children to check)&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;iii) Equivalence classes: (map[1], map[3]), (xs:string[2], xs:string[4]),  (map[5]), (xs:NMTOKEN[6])&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;unify(map[1], map[5])
   - S = map[1], T = map[5]
   - S and T are matching non-leaf nodes
   - union(S, T)
   - recursively check the children&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;iv) Equivalence classes: (map[1], map[3], map[5]), (xs:string[2],  xs:string[4]), (xs:NMTOKEN[6])&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;unify(xs:string[2], xs:NMTOKEN[6])
   - S = xs:string[2], T = xs:NMTOKEN[6]
   - S is a subtype of T
   - union(S, T)
   - return true (no children to check)&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;v) Equivalence classes: (map[1], map[3], map[5]), (xs:string[2],  xs:string[4], xs:NMTOKEN[6])&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;unify(map[1], map[3])
   - S = map[1], T = map[1]
   - S = T
   - return true&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;And we successfully determine that the recursive ItemType A is a subtype of the recursive ItemType B.&lt;/p&gt;</description><link>http://john.snelson.org.uk/post/48547567561</link><guid>http://john.snelson.org.uk/post/48547567561</guid><pubDate>Fri, 22 Jul 2011 16:32:08 +0100</pubDate></item><item><title>Proposal to add Type Aliases to XSLT 3.0</title><description>&lt;p&gt;&lt;strong&gt;&lt;span style="font-size: medium;"&gt;Type Alias Declaration&lt;/span&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&amp;lt;!-- Category: declaration --&amp;gt;
&amp;lt;xsl:type-alias
   name = qname
   as = item-type
   visibility? = "public" | "private" /&amp;gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;[DEFINITION: A type alias declaration adds a binding to the static context, between an expanded-QName and an ItemType, called the &lt;strong&gt;aliased type&lt;/strong&gt;. The &lt;strong&gt;aliased type&lt;/strong&gt; is specified in the mandatory &amp;#8220;as&amp;#8221; attribute.] &lt;/p&gt; [ERR TBD] A type alias name must be in a namespace, and must not be the same as the name of any type in the in-scope schema components, or any other type alias name. &lt;p&gt;&lt;/p&gt; Type aliases are imported and included from stylesheet modules, and may be exported by a package where they can be given visibilities of &amp;#8220;public&amp;#8221; and &amp;#8220;private&amp;#8221;.  NOTE: This proposal does not provide a way for type aliases to be overridden. &lt;p&gt;&lt;/p&gt; [DEFINITION: A type alias may be used as a SequenceType by using a &lt;strong&gt;type alias reference&lt;/strong&gt;, which is a SequenceType consisting only of a bare EQName (which is parsed as an ItemType by the AtomicOrUnionType grammar production in XPath 3.0) resolving to an expanded-QName equal to the type alias name.] A &lt;strong&gt;type alias reference&lt;/strong&gt; behaves exactly as if the &lt;strong&gt;aliased type&lt;/strong&gt; had been used in it&amp;#8217;s place. A type alias is in scope for every stylesheet module in the stylesheet, and may be used anywhere an ItemType is expected.  NOTE: Type aliases do not provide new type annotations with which values are annotated - in this way they do not define new types, and are true to the name &amp;#8220;alias&amp;#8221;. &lt;p&gt;&lt;/p&gt; NOTE: This does not permit the use of a type alias in a number of places where an atomic type name is valid, including a cast expression and as the TypeName in an element test.  [DEFINITION: A type alias A &lt;strong&gt;trivially depends&lt;/strong&gt; on a type alias B if A&amp;#8217;s &lt;strong&gt;aliased type&lt;/strong&gt; is a &lt;strong&gt;type alias reference&lt;/strong&gt; to B, or to a type alias C that itself &lt;strong&gt;trivially depends&lt;/strong&gt; on B.] [ERR TBD] It is an error for a type alias to &lt;strong&gt;trivially depend&lt;/strong&gt; on itself. &lt;p&gt;&lt;/p&gt; NOTE: This proposal does not extend to defining parametrized type aliases, but does not preclude adding them in the future.  &lt;strong&gt;&lt;span style="font-size: small;"&gt;Examples:&lt;/span&gt;&lt;/strong&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&amp;lt;xsl:type-alias name="my:complexNumber"
   as="map(xs:boolean, xs:double)"/&amp;gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;A type alias for a complex number implemented as a map from booleans to doubles.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&amp;lt;xsl:type-alias name="my:predicate"
   as="function(item()) as xs:boolean"/&amp;gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;A type alias for a function which can be used as a predicate.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&amp;lt;xsl:type-alias name="my:tree" as="map(xs:string,my:tree)"/&amp;gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;A recursive type alias for an edge labelled tree structure implemented using maps. &lt;/p&gt;  &lt;br/&gt;&lt;strong&gt;&lt;span style="font-size: medium;"&gt;Other Changes&lt;/span&gt;&lt;/strong&gt;&lt;p&gt;&lt;/p&gt; Add a paragraph to the end of &lt;a href="http://www.w3.org/TR/2010/WD-xslt-21-20100511/#external-objects"&gt;Section 22.1.3 of XSLT 3.0&lt;/a&gt;:
&lt;p&gt;&amp;lt;new&amp;gt;&lt;br/&gt;If a new type is added to the type system, implementations may denote that type in the SequenceType syntax using a bare EQName in a (non-null) implementation specific namespace - which is parsed as an ItemType by the AtomicOrUnionType grammar production in XPath 3.0.&lt;/p&gt;
&lt;p&gt;&amp;lt;/new&amp;gt;&lt;/p&gt;</description><link>http://john.snelson.org.uk/post/48547568560</link><guid>http://john.snelson.org.uk/post/48547568560</guid><pubDate>Thu, 21 Jul 2011 15:27:00 +0100</pubDate></item><item><title>Ant Classpath Woes</title><description>&lt;p&gt;When building the specification documents for the W3C XQuery and XSLT working groups, I&amp;#8217;m constantly finding I have to battle against Java&amp;#8217;s over-engineered dependency injection based XSLT APIs. &lt;/p&gt; I could rant about how an XSLT 1.0 processor won&amp;#8217;t do when I&amp;#8217;ve got XSLT 2.0 stylesheets - indeed generally speaking I choose my libraries carefully because I want to use exactly those ones, not some others that happens to be hanging around. &lt;p&gt;&lt;/p&gt; Anyhow, this isn&amp;#8217;t meant to be that rant. This is just to document the solution to my problems. It seems that the shell script that launches ant likes to add it&amp;#8217;s dependencies to the classpath, despite my wishes to the contrary. The way to force it to my will is to use the CLASSPATH_OVERRIDE environment variable, thus:  CLASSPATH_OVERRIDE=1 CLASSPATH=../../lib/xercesImpl.jar:../../lib/saxon9.jar:../../lib/saxon.jar ant &lt;p&gt;&lt;/p&gt; Sweet joy!</description><link>http://john.snelson.org.uk/post/48547569186</link><guid>http://john.snelson.org.uk/post/48547569186</guid><pubDate>Wed, 16 Mar 2011 12:06:00 +0000</pubDate></item><item><title>Australian Humour</title><description>A real email my sister received from Townsville Freecycle!  Sent: Wednesday, 2 February 2011&amp;#160;12:39 PM &lt;br/&gt;To: &lt;a href="mailto:townsville_freecycle@yahoogroups.com"&gt;townsville_freecycle@yahoogroups.com&lt;/a&gt; &lt;br/&gt;Subject: [townsville_freecycle] OFFER - Tropical Cyclone YASI (Category 5) - Townsville &lt;p&gt;&lt;/p&gt; No longer wanted, to large to fit anywhere. To be taken away ASAP please. Thanks in advance.</description><link>http://john.snelson.org.uk/post/48547570415</link><guid>http://john.snelson.org.uk/post/48547570415</guid><pubDate>Thu, 03 Feb 2011 14:24:04 +0000</pubDate></item><item><title>Ice Crystals in Wytham WoodsPosted from:  Oxfordshire County...</title><description>&lt;img src="http://25.media.tumblr.com/baefcfda6f4d3a27214ebddea3a4146e/tumblr_mlme4yC2UW1s7y0gno1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;&lt;h2&gt;Ice Crystals in Wytham Woods&lt;/h2&gt;&lt;br/&gt;Posted from:  Oxfordshire County OX2, UK&lt;/p&gt;</description><link>http://john.snelson.org.uk/post/48547586387</link><guid>http://john.snelson.org.uk/post/48547586387</guid><pubDate>Tue, 07 Dec 2010 14:51:52 +0000</pubDate></item><item><title>Interesting use case for the XQuery 1.1 switch expression</title><description>&lt;p&gt;XQuery 1.1 introduces a new switch expression, which was intended for matching an expression against a number of different possible values. &lt;/p&gt; &lt;a href="http://www.w3.org/TR/xquery-11/#id-switch"&gt;&lt;a href="http://www.w3.org/TR/xquery-11/#id-switch"&gt;http://www.w3.org/TR/xquery-11/#id-switch&lt;/a&gt;&lt;/a&gt; &lt;p&gt;&lt;/p&gt; However, it can also be used instead of doing a series of nested if expressions, like this:  switch(true()) &lt;br/&gt;case $a &amp;gt; 0 return &amp;#8220;positive&amp;#8221; &lt;br/&gt;case $a &amp;lt; 0 return &amp;#8220;negative&amp;#8221; &lt;br/&gt;default return &amp;#8220;zero&amp;#8221; &lt;p&gt;&lt;/p&gt; I think that could become a common usage pattern.</description><link>http://john.snelson.org.uk/post/48547587389</link><guid>http://john.snelson.org.uk/post/48547587389</guid><pubDate>Mon, 06 Sep 2010 15:03:00 +0100</pubDate></item><item><title>Transferring websites to my iPhone with QR codes</title><description>I often want to transfer a website I&amp;#8217;ve been reading from my desktop to my iPhone so I can read it elsewhere. The solution I&amp;#8217;ve come up with is the following javascript bookmark to generate a QR code for the current website I&amp;#8217;m browsing:  javascript:var%20url%20=%20&amp;#8221;http://chart.apis.google.com/chart?cht=qr&amp;amp;chs=300x300&amp;amp;chl=&amp;#8221;%20+%20encodeURIComponent(window.location);window.location%20=%20url; &lt;p&gt;&lt;/p&gt; Saving that to a bookmark on your browser&amp;#8217;s toolbar, and you can easily create a QR code for any website. You can then use iPhone apps like ZBar to read the QR code direct from your monitor and open the webpage.</description><link>http://john.snelson.org.uk/post/48547588490</link><guid>http://john.snelson.org.uk/post/48547588490</guid><pubDate>Mon, 17 May 2010 15:03:31 +0100</pubDate></item><item><title>Definitely the best toad-in-the-hole I’ve ever cooked.</title><description>&lt;img src="http://25.media.tumblr.com/787617fcb24f8657b312cd606b6c080e/tumblr_mlme6tXiVf1s7y0gno1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;&lt;h2&gt;Definitely the best toad-in-the-hole I’ve ever cooked.&lt;/h2&gt;&lt;/p&gt;</description><link>http://john.snelson.org.uk/post/48547604449</link><guid>http://john.snelson.org.uk/post/48547604449</guid><pubDate>Wed, 14 Apr 2010 19:23:21 +0100</pubDate></item><item><title>Grandpa, Emily and Jez</title><description>&lt;img src="http://24.media.tumblr.com/da8c7ebaada85e6be27c80e20709fb8e/tumblr_mlme75yyfD1s7y0gno1_500.jpg"/&gt;&lt;br/&gt;&lt;br/&gt;&lt;p&gt;&lt;h2&gt;Grandpa, Emily and Jez&lt;/h2&gt;&lt;/p&gt;</description><link>http://john.snelson.org.uk/post/48547621333</link><guid>http://john.snelson.org.uk/post/48547621333</guid><pubDate>Mon, 15 Mar 2010 19:53:22 +0000</pubDate></item><item><title>Proposal to add Function Annotations to XQuery 1.1 and XPath 2.1</title><description>&lt;p&gt;This post looks at a way to unify recent syntactic category extensions to the function declaration syntax in XQuery (1.1, Scripting Extensions, Update Facility etc.), by providing a generic function annotation facility. This is designed to give implementations a way to extend XQuery in similar ways to those the XQuery Working Group have been pursuing, and would also provide a modest level of reflective capability to the language.&lt;/p&gt;
&lt;p&gt;In choosing a syntax for function annotations, it was my aim that it should work with function declarations in the prolog, inline functions, and function item SequenceTypes. In addition for symmetry, it might also be beneficial to let the same syntax work with prolog variable declarations - especially considering XQSX&amp;#8217;s &amp;#8221;assignable&amp;#8221; qualifier.&lt;/p&gt;
&lt;p&gt;Finding a syntax that works where needed proved difficult, and I could describe many more syntaxes that won&amp;#8217;t work than ones that would. In the end, I have taken inspiration from Java&amp;#8217;s annotations which have a syntax that starts with an &amp;#8220;@&amp;#8221; [1]. Of course, &amp;#8220;@&amp;#8221; is already used in XQuery, so I have used the &amp;#8220;%&amp;#8221; character.&lt;/p&gt;
&lt;h2&gt;Annotations&lt;/h2&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;  FunctionDecl ::= "declare" FunctionAnnotation* "function" QName
    "(" ParamList? ")" ("as" SequenceType)? (EnclosedExpr | "external")

  FunctionAnnotation ::= "updating" | Annotation

  Annotation ::= "%" QName ("(" Literal ("," Literal)* ")")?&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Annotations are pairs of QName and an &amp;lt;annotation value&amp;gt; that are statically associated with a function or FunctionTest. The &amp;lt;annotation value&amp;gt; is a non-empty XDM sequence constructed entirely of literal values.&lt;/p&gt;
&lt;p&gt;The prefix of the QName in the Annotation is resolved using the statically known namespaces. An unprefixed annotation name is considered to be in the default function namespace.&lt;/p&gt;
&lt;p&gt;If the annotation is followed by a parenthesised list of Literals, those literals make up the &amp;lt;annotation value&amp;gt;, otherwise the &amp;lt;annotation value&amp;gt; is a single xs:boolean item with the value &amp;#8220;true&amp;#8221;.&lt;/p&gt;
&lt;p&gt;XQuery 1.1 defines a number of built-in annotations in the &amp;#8220;fn&amp;#8221; namespace, including &amp;#8220;fn:private&amp;#8221;, &amp;#8220;fn:public&amp;#8221;, &amp;#8220;fn:nondeterministic&amp;#8221;, and &amp;#8221;fn:deterministic&amp;#8221;. Users SHOULD avoid using annotations in the &amp;#8220;fn&amp;#8221; namespace, since further use of this namespace is reserved for future language extensions.&lt;/p&gt;
&lt;p&gt;An XQuery user MAY use arbitrary annotations of their own design. An implementation MAY choose to support a number of further annotations whose effect is beyond the scope of this specification.&lt;/p&gt;
&lt;p&gt;NOTE: For backwards compatibility with XQuery Update 1.0, the bare keyword &amp;#8220;updating&amp;#8221; can be used as syntactic sugar for the annotation &amp;#8220;%updating&amp;#8221;.&lt;/p&gt;
&lt;h3&gt;Examples:&lt;/h3&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;  declare %private %updating function local:bar()
  {
    put(&amp;lt;foo/&amp;gt;)
  };&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;A private updating function.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;  declare %private %sequential %my:recursion-depth(10) function local:foo($a)
  {
    $a + 1, local:foo(tail($a))
  };&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;A private sequential function, using a custom annotation to limit recursion depth to 10.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;  declare %rest:get("blog/") function local:get-blog($httpRequest)
  {
    &amp;lt;html&amp;gt;
      &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;My Blog&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;
      &amp;lt;body&amp;gt;&amp;lt;h1&amp;gt;My Blog&amp;lt;/h1&amp;gt;&amp;lt;/body&amp;gt;
    &amp;lt;/html&amp;gt;
  };&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;A custom annotation associating the local:get-blog#1 function with a GET http request with a relative URI of &amp;#8220;blog/&amp;#8221;.&lt;/p&gt;
&lt;p&gt;An external function with a custom annotation resolving the implementation to a Java static method.&lt;/p&gt;
&lt;h2&gt;Inline Function Annotations&lt;/h2&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;  InlineFunction ::= Annotation* "function" "(" ParamList? ")"
    ("as" SequenceType)? EnclosedExpr&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;An inline function can also be preceded by a list of zero or more Annotations.&lt;/p&gt;
&lt;h3&gt;Examples:&lt;/h3&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;  %nondeterministic function($a, $b) { 20 }[189]&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;A non-deterministic InlineFunction.&lt;/p&gt;
 
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;  %my:inline function($a) { $a + 1 }&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;An InlineFunction with a custom annotation directing the implementation to inline the function wherever possible.&lt;/p&gt;
&lt;h2&gt;FunctionTest Annotation Assertions&lt;/h2&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;  FunctionTest ::= AnyFunctionTest | TypedFunctionTest
 
  AnyFunctionTest ::= Annotation* "function" "(" "*" ")"
 
  TypedFunctionTest ::= Annotation* "function" "(" (SequenceType
    ("," SequenceType)*)? ")" "as" SequenceType&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Annotations associated with a FunctionTest are called &amp;lt;annotation assertions&amp;gt;. Annotation assertions can be used to further restrict the set of function items matched by the FunctionTest.&lt;/p&gt;
&lt;p&gt;XQuery 1.1 defines a number of built-in &amp;lt;annotation assertions&amp;gt; in the &amp;#8220;fn&amp;#8221; namespace, including:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;%fn:nondeterministic - matches function items with a %fn:deterministic or %fn:nondeterministic annotation.&lt;/li&gt;
&lt;li&gt;%fn:deterministic - matches function items with a %fn:deterministic annotation.  If no %fn:nondeterministic &amp;lt;annotation assertion&amp;gt; is present, this is the default matching behaviour.&lt;/li&gt;
&lt;li&gt;%fn:updating - matches function items with a %fn:simple or %fn:updating annotation.&lt;/li&gt;
&lt;li&gt;%fn:sequential - matches function items with a %fn:simple or %fn:sequential annotation.&lt;/li&gt;
&lt;li&gt;%fn:simple - matches function items with a %fn:simple annotation. If no %fn:updating or %fn:sequential &amp;lt;annotation assertion&amp;gt; is present, this is the default matching behaviour.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Users SHOULD avoid using &amp;lt;annotation assertions&amp;gt; in the &amp;#8220;fn&amp;#8221; namespace, since further use of this namespace is reserved for future language extensions.&lt;/p&gt;
&lt;p&gt;An XQuery user MAY use arbitrary &amp;lt;annotation assertions&amp;gt; of their own design. It is implementation defined how the effect of these assertions is determined. An implementation MAY choose to support a number of further &amp;lt;annotation assertion&amp;gt; whose effect is beyond the scope of this specification.&lt;/p&gt;
&lt;h3&gt;Examples:&lt;/h3&gt;
&lt;p&gt;Allow the function item in $a to have the %fn:nondeterministic annotation.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;  declare function fn:map(
    $f as %simple function(item()) as item()*,
    $seq as item()*
  ) as item()*
  {
    ...
  }&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Assert that the $f argument of fn:map has the %fn:simple annotation.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;  declare function local:sort(
    $compare as %my:transitive function(item(), item())as xs:boolean,
    $seq as item()*
  ) as item()*
  {
    ...
  }&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Use the custom &amp;lt;annotation assertion&amp;gt; %my:transitive to check that the $compare argument of local:sort has the %my:transitive annotation.&lt;/p&gt;
&lt;h2&gt;Querying Annotation Names&lt;/h2&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;  fn:annotation-names($f as function(*)) as xs:QName*&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Summary: Returns the set of annotation names associated with the function item $f as a sequence of xs:QName items.&lt;/p&gt;
&lt;p&gt;Rules: The set of annotation names are returned in an implementation defined but stable order. The set will include the names of built-in annotations &amp;#8220;fn:name&amp;#8221; and &amp;#8220;fn:arity&amp;#8221;.&lt;/p&gt;
&lt;h3&gt;Examples:&lt;/h3&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;  every $name in (xs:QName("fn:name"), xs:QName("fn:arity"),
    xs:QName("fn:simple"), xs:QName("fn:deterministic"))
  satisfies fn:annotation-names(fn:concat#2) = $name&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Returns xs:boolean(&amp;#8220;true&amp;#8221;).&lt;/p&gt;
&lt;h2&gt;Querying Annotation Values&lt;/h2&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;  fn:annotation($f as function(*), $name as xs:QName)
    as xs:anyAtomicType*&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Summary: Returns the &amp;lt;annotation value&amp;gt; for the annotation named $name associated with the function item $f.&lt;/p&gt;
&lt;p&gt;Rules: If $f has no annotation with name $name associated with it, the empty sequence is returned.&lt;/p&gt;
&lt;h3&gt;Examples:&lt;/h3&gt;
&lt;p&gt;Returns xs:QName(&amp;#8220;fn:concat&amp;#8221;).&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;  annotation(fn:concat#2, xs:QName("fn:arity"))&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Returns 2.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;  declare function fn:map(
    $f as function(item()) as item()*,
    $seq as item()*
  ) as item()*
  {
    if(fn:annotation($f, xs:QName("fn:sequential")))
      then my:sequential-map($f, $seq)
      else my:parallel-map($f, $seq)
  }&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Call a parallel algorithm for fn:map() if the function item $f does not have the annotation %fn:sequential.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;  declare function fn:ref($seq as item()*) as function() as item()*
  {
    %fn:ref function() { $seq }
  };
 
  declare function fn:deref($f as function() as item()*) as item()*
  {
    if(fn:annotation($f, xs:QName("fn:ref"))) then $f()
    else fn:error(xs:QName("err:XPTY0004"), "$f is not a sequence reference")
  };&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Check for the %fn:ref annotation on the function item $f to make sure that it was returned as the result of a call to fn:ref().&lt;/p&gt;
&lt;h2&gt;Annotations for Global Variables&lt;/h2&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;  VarDecl ::= "declare" Annotation* "variable" "$" VarName TypeDeclaration?
    ((":=" VarValue) | ("external" (":=" VarDefaultValue)?))&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;It&amp;#8217;s harder to know how to query this kind of annotation, or whether querying it is even desirable. However I think it would be nice to allow the same annotation syntax in this case.&lt;/p&gt;
&lt;h3&gt;Examples:&lt;/h3&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;  declare %assignable variable $bar as xs:decimal := 5;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Declare an assignable global variable in scripting.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;  declare %my:volatile variable $time as xs:time external;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;A custom annotation labelling the $time variable as volatile.&lt;/p&gt;</description><link>http://john.snelson.org.uk/post/48547623263</link><guid>http://john.snelson.org.uk/post/48547623263</guid><pubDate>Mon, 01 Mar 2010 13:05:04 +0000</pubDate></item><item><title>Adding Recursive Inline Functions to XQuery 1.1 and XPath 2.1</title><description>&lt;p&gt;It was recently pointed out on the &lt;a href="http://www.w3.org/Bugs/Public/show_bug.cgi?id=8662"&gt;W3C Bugzilla&lt;/a&gt; that XQuery 1.1 can not define recursive inline functions. This post looks at possibilities for solving that problem. &lt;/p&gt; &lt;span style="text-decoration: underline;"&gt;Examining the Options&lt;/span&gt;&lt;p&gt;&lt;/p&gt; Lets consider a recursive function, and a pair of mutually recursive functions. Defined using named functions, they look like this:  
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;declare function sum($a)
{
  if(empty($a)) then 0
  else $a[1] + sum(subsequence($a, 2))
};

declare function even($a)
{
  if($a == 0) then true()
  else odd(abs($a) - 1)
};

declare function odd($a)
{
  if($a == 0) then false()
  else even(abs($a) - 1)
};&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;br/&gt;&lt;span style="text-decoration: underline;"&gt;1. Allow an inline function to specify a name&lt;/span&gt; &lt;/p&gt; The first problem you hit here is that the obvious syntax is ambiguous:
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;function eq($a) { $a }
function eq ($a)&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;So lets say that we go with using the two tokens &amp;#8220;local function&amp;#8221; to start the named inline function - then our example functions look like this:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;local function sum($a)
{
  if(empty($a)) then 0
  else $a[1] + sum(subsequence($a, 2))
}

local function even($a)
{
  if($a == 0) then true()
  else if(abs($a) - 1 == 0) then false()
  else even(abs($a) - 2)
}&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Notice that odd() has been inlined inside even(), which shows the basic problem for mutually recursive functions using this technique. At least one of the functions no longer exists, meaning you can&amp;#8217;t idependantly call it, and you can&amp;#8217;t choose to factor that code out into a function. Note also that in more complex mutual recursion scenarios it&amp;#8217;s not clear that this rewrite is even possible. &lt;/p&gt;  &lt;br/&gt;&lt;span style="text-decoration: underline;"&gt;2. Provide a &amp;#8220;special&amp;#8221; variable for referencing the function&lt;/span&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;function($a)
{
  if(empty($a)) then 0
  else $a[1] + $self(subsequence($a, 2))
}

function($a)
{
  if($a == 0) then true()
  else if(abs($a) - 1 == 0) then false()
  else $self(abs($a) - 2)
}&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The mutually recursive functions here suffer from the same problem as with solution 1. In addition, the technique relies on introducing a magic variable, which is both backwards incompatible and ineligant to my way of thinking. &lt;/p&gt;  &lt;br/&gt;&lt;span style="text-decoration: underline;"&gt;3. Recursive let&lt;/span&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;letrec $sum := function($a)
{
  if(empty($a)) then 0
  else $a[1] + sum(subsequence($a, 2))
}
return $sum

letrec $even := function($a)
{
  if($a == 0) then true()
  else $odd(abs($a) - 1)
},
$odd := function($a)
{
  if($a == 0) then false()
  else $even(abs($a) - 1)
}
return ($even, $odd)&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;This is a well-known solution in the functional programming world, and provides a good solution to the mutually recursive function problem. However people have pointed out that it also allows possibly undesirable assignments like this:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;letrec $a := 1 + $a
return $a&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;&lt;br/&gt;&lt;span style="text-decoration: underline;"&gt;4. Local functions&lt;/span&gt;&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;local $sum := function($a)
{
  if(empty($a)) then 0
  else $a[1] + $sum(subsequence($a, 2))
}
return $sum

local $even := function($a)
{
  if($a == 0) then true()
  else $odd(abs($a) - 1)
},
$odd := function($a)
{
  if($a == 0) then false()
  else $even(abs($a) - 1)
}
return ($even, $odd)&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Local function expressions work in a similar fashion to solution 3, but are restricted to only define function items. All variables declared this way are in scope for all the inline function expressions, and for the return expression. This solution has none of the drawbacks of the previous three. &lt;/p&gt;
&lt;p&gt;&lt;/p&gt; &lt;span style="text-decoration: underline;"&gt;Proposal&lt;/span&gt;  I propose that we add a local function expression to XQuery 1.1 and XPath 2.1 by inserting a new section 3.16 (XQuery 1.1) or 3.12 (XPath 2.1) as follows: &lt;p&gt;&lt;/p&gt; 3.16&amp;#160;&lt;strong&gt;Local Function Expressions&lt;/strong&gt;&lt;br/&gt;

&lt;p&gt;&lt;em&gt; &lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt; &lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt; &lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;LocalFunctionExpr ::= "local" LocalFunctionBinding ("," LocalFunctionBinding)*
                                    "return" ExprSingle
LocalFunctionBinding ::= LocalFunctionVar ":=" InlineFunction
LocalFunctionVar ::= "$" VarName&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;/em&gt; Local function expressions bind InlineFunction expressions to variables, allowing the definition of recursive inline functions. Each variable defined by the local function expression is in scope for all InlineFunction expressions and for the return expression.&lt;/p&gt;Evaluation of a local function expression is equivalent to the following:
&lt;ol&gt;&lt;li&gt;Every LocalFunctionVar is bound to a hypothetical &lt;em&gt;null&lt;/em&gt; value.&lt;/li&gt;
&lt;li&gt;The InlineFunction expression from each LocalFunctionBinding is evaluated in turn, and its result is assigned to the LocalFunctionVar. &lt;/li&gt;
&lt;li&gt;The return expression is evaluated and it&amp;#8217;s result returned.&lt;/li&gt;
&lt;/ol&gt;&lt;blockquote class="posterous_short_quote"&gt;&lt;em&gt;NOTE: The static type of every LocalFunctionVar can easily be inferred from the &lt;/em&gt;&lt;em&gt;InlineFunction it is bound to.&lt;/em&gt;&lt;/blockquote&gt;
&lt;p&gt; &lt;/p&gt;</description><link>http://john.snelson.org.uk/post/48547624654</link><guid>http://john.snelson.org.uk/post/48547624654</guid><pubDate>Fri, 05 Feb 2010 20:24:00 +0000</pubDate></item><item><title>Fast XML Pull Parser 0.3 released</title><description>&lt;p&gt;I&amp;#8217;ve been doing quite a bit of work on &lt;a href="http://faxpp.sourceforge.net/"&gt;Faxpp&lt;/a&gt; recently. My enthusiasm had kind of ground to a halt for a while after I realised the full complexity of implementing entities, but then I decided I just needed to knuckle down and get it finished. The fruit of my labours can now be &lt;a href="http://sourceforge.net/project/showfiles.php?group_id=201903"&gt;downloaded from Sourceforge&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I think I&amp;#8217;ve got a robust framework for resolving and parsing internal and external entities - and I&amp;#8217;ve learnt things about XML that I&amp;#8217;m not sure many people in the world know:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Parameter entities (&amp;#8220;%entity;&amp;#8221;) can appear almost anywhere in an external subset (DTD), but their replacement value is substituted with an extra leading and trailing space if the reference isn&amp;#8217;t in a literal value.&lt;/li&gt;
&lt;li&gt;Character references in entity values are expanded when the entity declaration is parsed, but general entity references are not resolved until the entity value is substituted for a reference.&lt;/li&gt;
&lt;li&gt;An XML 1.0 DTD referenced by an XML 1.1 document will be parsed as though it were XML 1.1.&lt;/li&gt;
&lt;li&gt;At least two thirds of the code in an XML parser is there to support functionality that 90% of XML documents never use.&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;I can also lay claim to actually understanding what notations are, although I don&amp;#8217;t think I&amp;#8217;ll ever find a use for them.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;m calling this release a beta, because I know there&amp;#8217;s still a bit of work left to be done. Top of the list is implementing default attribute values, then maybe I&amp;#8217;ll get to work on shrinking the parser - since the DTD parsing code has made it much larger than I want it to be.&lt;/p&gt;</description><link>http://john.snelson.org.uk/post/48547625818</link><guid>http://john.snelson.org.uk/post/48547625818</guid><pubDate>Fri, 21 Mar 2008 07:18:00 +0000</pubDate></item><item><title>XQilla in the News</title><description>&lt;p&gt;Oracle &lt;a href="http://www.oracle.com/corporate/press/2008_mar/xquilla.html"&gt;officially announced&lt;/a&gt; the &lt;a href="http://xqilla.sourceforge.net/HomePage"&gt;XQilla&lt;/a&gt; license change today. It feels like this has been a long time coming - I was involved in pushing for the original &lt;a href="http://software.decisionsoft.com/oldsite/pathanIntro.html"&gt;Pathan&lt;/a&gt;project to be open sourced in 2003 when I worked at &lt;a href="http://www.decisionsoft.com/"&gt;Decisionsoft&lt;/a&gt;. Later when I worked for Sleepycat, I was involved in pushing for a liberally licensed release of the XQuery implementation and improvements to Pathan which became XQilla some 3 years later.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s great to see something that I&amp;#8217;ve worked on for the last 7 years start to get the exposure I always thought it deserved. XQuery has huge potential to change the way that people use their data, and it&amp;#8217;s close relationship to the web means now might be the right time, and XQilla might be in the right place.&lt;/p&gt;
&lt;p&gt;Thanks has to go to &lt;a href="http://blogs.oracle.com/mikeolson/"&gt;Mike Olson&lt;/a&gt; who put in the lion&amp;#8217;s share of the work needed to make this happen. Hopefully his efforts will make it easier for even more Oracle code to reach it&amp;#8217;s potential by being released as open source.&lt;/p&gt;</description><link>http://john.snelson.org.uk/post/48547626927</link><guid>http://john.snelson.org.uk/post/48547626927</guid><pubDate>Wed, 19 Mar 2008 06:19:00 +0000</pubDate></item><item><title>Parsing JSON into XQuery</title><description>&lt;p&gt;Doug Crockford stirred things up at &lt;a href="http://2007.xmlconference.org/public/content/home"&gt;XML 2007&lt;/a&gt; with his &lt;a href="http://blog.360.yahoo.com/blog-TBPekxc1dLNy5DOloPfzVvFIVOWMB0li?p=736"&gt;comments on JSON and XML&lt;/a&gt;. He was wrong - mainly because he&amp;#8217;s only looking at structured data transfer, rather than anything else that XML is very good at like documents and semi-structured data. However he got me thinking about how easy it would be to process JSON in XQuery, which as &lt;a href="http://www.datadirect.com/products/xquery/index.ssp"&gt;Data Direct&lt;/a&gt; has shown is very good at manipulating all sorts of data formats.&lt;/p&gt;
&lt;p&gt;I headed over to &lt;a href="http://www.json.org/"&gt;json.org&lt;/a&gt; to take a look at the work that had already been done on converting JSON to and from XML. Then I googled, and read around. I even had an email conversation with Dimitre Novatchev of FXSL fame, who&amp;#8217;s written a &lt;a href="http://dnovatchev.spaces.live.com/blog/cns!44B0A32C2CCF7488!367.entry"&gt;JSON parser entirely in XSLT&lt;/a&gt;!&lt;/p&gt;
&lt;p&gt;All of the designs I looked at had at least one of the following problems:&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;They could only convert a subset of JSON - things like map keys that weren&amp;#8217;t valid NCNames would cause problems.&lt;/li&gt;
&lt;li&gt;They didn&amp;#8217;t specify a 1-1 mapping - in other cases map keys were munged to be valid NCNames using a function with no inverse. This would mean that I wouldn&amp;#8217;t be able to convert back to JSON from it&amp;#8217;s XML representation.&lt;/li&gt;
&lt;li&gt;They lost the JSON type information, like whether a value was null or an empty string - which is also a way in which the mapping is not 1-1.&lt;/li&gt;
&lt;/ol&gt;&lt;p&gt;So given nothing fitted I chose to come up with my own mapping from JSON to XML - which is, after all, the JSON way. So here it is, in all it&amp;#8217;s simplicity:&lt;/p&gt;
&lt;table border="1"&gt;&lt;tr&gt;&lt;th&gt;JSON&lt;/th&gt;&lt;th&gt;type(JSON)&lt;/th&gt;&lt;th&gt;toXML(JSON)&lt;/th&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;JSON&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;&amp;lt;json type=&amp;#8221;type(JSON)&amp;#8221;&amp;gt;toXML(JSON)&amp;lt;/json&amp;gt;&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;{ &amp;#8220;key1&amp;#8221;: value1, &amp;#8220;key2&amp;#8221;: value2 }&lt;/td&gt;
&lt;td&gt;object&lt;/td&gt;
&lt;td&gt;&amp;lt;pair name=&amp;#8221;key1&amp;#8221; type=&amp;#8221;type(value1)&amp;#8221;&amp;gt;toXML(value1)&amp;lt;/pair&amp;gt; &amp;lt;pair name=&amp;#8221;key2&amp;#8221; type=&amp;#8221;type(value2)&amp;#8221;&amp;gt;toXML(value2)&amp;lt;/pair&amp;gt;&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;[ value1, value2 ]&lt;/td&gt;
&lt;td&gt;array&lt;/td&gt;
&lt;td&gt;&amp;lt;item type=&amp;#8221;type(value1)&amp;#8221;&amp;gt;toXML(value1)&amp;lt;/item&amp;gt; &amp;lt;item type=&amp;#8221;type(value2)&amp;#8221;&amp;gt;toXML(value2)&amp;lt;/item&amp;gt;&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&amp;#8220;value&amp;#8221;&lt;/td&gt;
&lt;td&gt;string&lt;/td&gt;
&lt;td&gt;value&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;number&lt;/td&gt;
&lt;td&gt;number&lt;/td&gt;
&lt;td&gt;number&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;true / false&lt;/td&gt;
&lt;td&gt;boolean&lt;/td&gt;
&lt;td&gt;true / false&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;null&lt;/td&gt;
&lt;td&gt;null&lt;/td&gt;
&lt;td&gt;&lt;em&gt;empty&lt;/em&gt;&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;The table defines two abstract functions &amp;#8220;type&amp;#8221; and &amp;#8220;toXML&amp;#8221;, which are recursively defined on the structure of the input JSON. The extension functions to parse and serialize JSON are called xqilla:parse-json() and xqilla:serialize-json(), and will available in the next release of &lt;a href="http://xqilla.sourceforge.net/HomePage"&gt;XQilla&lt;/a&gt;.&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;xqilla:parse-json($xml as xs:string?) as element()?
xqilla:serialize-json($json-xml as element()?) as xs:string?&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The translation produces a simple generic XML document - as an example, here&amp;#8217;s a query to parse a sample of JSON (swiped from &lt;a href="http://en.wikipedia.org/wiki/JSON"&gt;wikipedia&lt;/a&gt;):&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;xqilla:parse-json('{
     "firstName": "John",
     "lastName": "Smith",
     "address": {
         "streetAddress": "21 2nd Street",
         "city": "New York",
         "state": "NY",
         "postalCode": 10021
     },
     "phoneNumbers": [
         "212 732-1234",
         "646 123-4567"
     ]
 }')&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;And here&amp;#8217;s its translation, the result of the query:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;&amp;lt;json type='object'&amp;gt;
  &amp;lt;pair name='firstName' type='string'&amp;gt;John&amp;lt;/pair&amp;gt;
  &amp;lt;pair name='lastName' type='string'&amp;gt;Smith&amp;lt;/pair&amp;gt;
  &amp;lt;pair name='address' type='object'&amp;gt;
    &amp;lt;pair name='streetAddress' type='string'&amp;gt;21 2nd Street&amp;lt;/pair&amp;gt;
    &amp;lt;pair name='city' type='string'&amp;gt;New York&amp;lt;/pair&amp;gt;
    &amp;lt;pair name='state' type='string'&amp;gt;NY&amp;lt;/pair&amp;gt;
    &amp;lt;pair name='postalCode' type='number'&amp;gt;10021&amp;lt;/pair&amp;gt;
  &amp;lt;/pair&amp;gt;
  &amp;lt;pair name='phoneNumbers' type='array'&amp;gt;
    &amp;lt;item type='string'&amp;gt;212 732-1234&amp;lt;/item&amp;gt;
    &amp;lt;item type='string'&amp;gt;646 123-4567&amp;lt;/item&amp;gt;
  &amp;lt;/pair&amp;gt;
&amp;lt;/json&amp;gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;One of the nice things about the XML format for JSON is that it&amp;#8217;s easy to navigate. If I want to get the city from the JSON object above, the XQuery for it would be:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;xqilla:parse-json("...")/pair[@name="address"]/pair[@name="city"]&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Or if I want to get both the phone numbers I could use:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;xqilla:parse-json("...")/pair[@name="phoneNumbers"]/item&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;Now I probably have to do a follow up post about all the cool things you can do in XQuery when you can parse JSON&amp;#8230;&lt;/p&gt;</description><link>http://john.snelson.org.uk/post/48547628468</link><guid>http://john.snelson.org.uk/post/48547628468</guid><pubDate>Fri, 15 Feb 2008 01:21:00 +0000</pubDate><category>json xquery xml xqilla</category></item><item><title>Latency vs Throughput</title><description>&lt;p&gt;I was helping a &lt;a href="http://www.oracle.com/database/berkeley-db/xml"&gt;Berkeley DB XML&lt;/a&gt; user recently who complained that his query took as long as ~55s to run. It turned out he was trying to run 40 concurrent queries, so I tried out the query on his data set using our concurrency testing framework. I was confused when it reported to me that I was getting ~2&amp;#160;ops/s, which is a completely different ballpark.&lt;/p&gt;
&lt;p&gt;It took me a while, but eventually I figured it out: When the user was saying that his query took ~55s what he meant was that a thread&amp;#8217;s view of how long a query takes can be as much as 55s. When I talked about getting ~2&amp;#160;ops/s, I was looking at the system as a whole. The problem was that he was talking about &lt;a href="http://en.wikipedia.org/wiki/Comparison_of_latency_and_throughput"&gt;latency, and I was talking about throughput&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Typically the way that a server gets smaller latency is to implement a &lt;a href="http://en.wikipedia.org/wiki/Thread_pool_pattern"&gt;thread pool and work queue&lt;/a&gt;. Since DB XML is an embedded library and does not spawn it&amp;#8217;s own threads, it is down to the application using DB XML to manage it&amp;#8217;s threads well.&lt;/p&gt;
&lt;p&gt;So I created a Java test program that used a thread pool to manage the queries being run through DB XML (in Java it&amp;#8217;s &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/concurrent/Executors.html"&gt;really&lt;/a&gt; &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html"&gt;easy&lt;/a&gt;). I created a test function that could run the query with arguments of how many threads to create, how many queries to run, and how many queries to start per second.&lt;/p&gt;
&lt;p&gt;I ran a number of tests - in all of the test runs I kept the number of queries run as constant, so that exactly the same amount of useful work was done in all cases. I measured &amp;#8220;workload&amp;#8221; time, which is the time from when the query is requested until it is completed - this is a measure of latency. I also measured the total time taken for all the queries, and the number of operation per second executed - this is a measure of throughput. Here are the actual figures I got:&lt;/p&gt;

&lt;table border="1"&gt;&lt;tr&gt;&lt;th&gt;Queries run&lt;/th&gt;&lt;th&gt;Queries per second&lt;/th&gt;&lt;th&gt;Threads&lt;/th&gt;&lt;th&gt;Latency (avg query time in seconds)&lt;/th&gt;&lt;th&gt;Throughput (queries per second)&lt;/th&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;80&lt;/td&gt;
&lt;td&gt;no delay&lt;/td&gt;
&lt;td&gt;40&lt;/td&gt;
&lt;td&gt;32.15&lt;/td&gt;
&lt;td&gt;1.70&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;80&lt;/td&gt;
&lt;td&gt;no delay&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;23.34&lt;/td&gt;
&lt;td&gt;1.96&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;80&lt;/td&gt;
&lt;td&gt;no delay&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;22.00&lt;/td&gt;
&lt;td&gt;1.89&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;80&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;18.51&lt;/td&gt;
&lt;td&gt;1.88&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;80&lt;/td&gt;
&lt;td&gt;5&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;13.87&lt;/td&gt;
&lt;td&gt;1.93&lt;/td&gt;
&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;80&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;td&gt;4&lt;/td&gt;
&lt;td&gt;0.90&lt;/td&gt;
&lt;td&gt;1.97&lt;/td&gt;
&lt;/tr&gt;&lt;/table&gt;&lt;p&gt;&lt;span&gt; &lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The first thing I noticed is that as the number of threads spawned decreased, latency decreases and throughput increases - this peaked around 4-5 threads on my system. Throughput increased because each thread has a processing overhead associated with it, so less threads means less overhead. Average latency decreased because instead of 5 queries each taking 50s (as an example), the first query takes 10s, and the last takes 50s:&lt;/p&gt;
&lt;p&gt;Average time for 5 queries in parallel: (50s + 50s + 50s + 50s + 50s) / 5 = 50s&lt;br/&gt;Average time for 5 queries in series: (10s + 20s + 30s + 40s + 50s) / 5 = 30s&lt;/p&gt;
&lt;p&gt;Surprise number one - adding more threads can actually increase your latency!&lt;/p&gt;
&lt;p&gt;Next I tried to add a little bit of realism to the simulation - it is very rare that 80 queries need to be executed at exactly the same time, so I added a little bit of a delay between starting each query. As the queries per second decreased throughput was more or less constant, but latency decreased dramatically. This is simple to explain - the queries spent less time in the work queue, when they aren&amp;#8217;t actually being executed:&lt;/p&gt;
&lt;p&gt;Average time for 5 queries executed at the same time: (10s + 20s + 30s + 40s + 50s) / 5 = 30s&lt;br/&gt;Average time for 5 queries executed with a 10s delay between each: (10s + 10s + 10s + 10s + 10s) / 5 = 10s&lt;/p&gt;
&lt;p&gt;So surprise number two - a more realistic workload can result in smaller latency!&lt;/p&gt;</description><link>http://john.snelson.org.uk/post/48547630059</link><guid>http://john.snelson.org.uk/post/48547630059</guid><pubDate>Fri, 25 Jan 2008 18:42:00 +0000</pubDate></item><item><title>Why DB XML Doesn't Do Path Indexes</title><description>&lt;p&gt;Every so often we have a &lt;a href="http://www.oracle.com/database/berkeley-db/xml"&gt;Berkeley DB XML&lt;/a&gt; user ask us if we implement path indexes. Or maybe they assume that we do implement them and are confused about why their index isn&amp;#8217;t working. It turns out that a lot of these users have come to us after using &lt;a href="http://exist.sourceforge.net/"&gt;eXist&lt;/a&gt;, which for a long time has only been able to specify path indexes.&lt;/p&gt;
&lt;p&gt;A path index is specified by describing the path to the nodes that you want to index - often with a subset of XPath. So you might want to index all &amp;#8220;firstname&amp;#8221; elements, but only if they are children of an &amp;#8220;author&amp;#8221; element - which you might write like this:&lt;/p&gt;
&lt;div class="CodeRay"&gt;
  &lt;div class="code"&gt;&lt;pre&gt;//author/firstname&lt;/pre&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;The good thing about path indexes is that they can be very small targeted indexes, which only record exactly the information that you want.&lt;/p&gt;
&lt;p&gt;The trouble with path indexes, I&amp;#8217;ve always explained, is that it&amp;#8217;s really hard to work out when you can use one in a query. You miss out on lots of potential optimisation opportunities because query analysis can&amp;#8217;t prove that an index is applicable. It&amp;#8217;s not surprising really - path indexes are a subset of &lt;a href="http://en.wikipedia.org/wiki/Materialized_view"&gt;materialised views&lt;/a&gt; which is known to be a very hard problem, in the general case.&lt;/p&gt;
&lt;p&gt;So it&amp;#8217;s not surprising to see that &lt;a href="http://atomic.exist-db.org/wiki/blogs/eXist/NewIndexing"&gt;recent work on eXist&lt;/a&gt; has added a new type of index which works in exactly the same way as DB XML&amp;#8217;s do. The author of the blog post even describes the problems that I have been telling our users about, and recommends that path indexes be used sparingly if at all.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s good to see other people coming to the same conclusion that I came to. DB XML may implement path indexes some day, but they won&amp;#8217;t be anywhere near as useful as some users think they should be.&lt;/p&gt;</description><link>http://john.snelson.org.uk/post/48547631180</link><guid>http://john.snelson.org.uk/post/48547631180</guid><pubDate>Fri, 18 Jan 2008 00:55:00 +0000</pubDate></item></channel></rss>
