Disappointment with XQueryX 1.0, 2001-06-07

This message is to express my disappointment with the XQueryX 1.0 draft (2001-06-07).  This document only furthers my concern that the XQuery WG does not take the requirement for an XML query syntax seriously.  I am seriously worried that this document recommends an XML query syntax that will be so marginalised and ridiculed that it will not be implemented.

While the XQuery requirements ask for a human readable syntax, there is no suggestion the document has to be read with Notepad, Emacs, or vi.  XSL-T already uses an XML syntax, is widely used and understood, and comparable to FLWR in readability when read using an XML editor (i.e. an editor which displays the tree structure rather than the angle brackets).  The XQueryX 1.0 syntax not only minimises readability, but it is not even useful for programmers, because even programmers have to be able to understand the queries that they are generating, and the proposed syntax makes that unlikely.  It is not acceptable for XQueryX to be an XML syntax that forces programmers to use FLWR as the last resort.  I do not want our company to have to use the FLWR syntax for XML queries, and do not consider it appropriate for the XQuery WG to essentially force users to do so.  At the very least, a W3C specification relating to XML should not be seen to suggest that XML is next to useless for do!
!
ing
anything serious.

That said, it is too easy just to criticise, so I wish to provide suggestions as to what XQueryX could look like, and to demonstrate that there is no need at all for XQueryX to be so arcane.  Of course, to come up with a proper XML syntax, it might be necessary to reconsider FLWR, but that is what you get for trying to leave the XML syntax until last.  I will be referring to the examples in

http://www.w3.org/TR/2001/WD-xqueryx-20010607

========
Example 0:
FOR $b IN document("bib.xml")//book
WHERE $b/publisher = "Morgan Kaufmann" AND $b/year = "1998"
RETURN
    $b/title

I would propose that a readable XML equivalent would be

<q:for-each select = "document('bib.xml')//book[publisher = 'Morgan Kaufmann' and year = '1998']">
  <q:copy select = "title"/>
</q:for-each>

or

<q:for-each name = "b" select = "document('bib.xml')//book[publisher = 'Morgan Kaufmann' and year = '1998']">
  <q:copy select = "$b/title"/>
</q:for-each>
========

========
Example 1:
FOR $p IN distinct(document("bib.xml")//publisher)
LET $a := avg(document("bib.xml")//book[publisher = $p]/price)
RETURN
    <publisher>
        <name>{ $p/text() }</name>
        <avgprice>{ $a }</avgprice>
    </publisher>

I would propose

<q:variable name = "publishers" select = "distinct(document('bib.xml')//publisher)"/>
<q:for-each name = "p" select = "$publishers">
  <q:variable name = "a" select = "avg(document('bib.xml')//book[publisher = $p]/price)"/>
  <publisher>
    <name>
      <q:value-of select = "$p/text()"/>
    </name>
    <avgprice>
      <q:value-of select = "$a"/>
    </avgprice>
  </publisher>
</q:for-each>

or

<q:variable name = "publishers" select = "distinct(document('bib.xml')//publisher)"/>
<q:for-each name = "p" select = "$publishers">
  <q:variable name = "a" select = "avg(document('bib.xml')//book[publisher = $p]/price)"/>
  <publisher>
    <name>{$p/text()}</name>
    <avgprice>{$a}</avgprice>
  </publisher>
</q:for-each>
========

========
Example 2:
<author_list>
  {
    FOR $a IN distinct(document("bib.xml")//author)
    RETURN
        <author>
            <name>{ $a/text() }</name>
               {
                FOR $b IN document("bib.xml")//book[author = $a]
                RETURN $b/title
               }
        </author>
  }
</author_list>

I would suggest

<author_list>
  <q:for-each name = "a" select = "distinct(document('bib.xml')//author)">
    <author>
      <name>
        <q:value-of select = "$a/text()"/>
      </name>
      <q:for-each select = "document('bib.xml')//book[author = $a]">
        <q:copy select = "title"/>
      </q:for-each>
    </author>
  </q:for-each>
</author_list>

or

<author_list>
  <q:for-each name = "a" select = "distinct(document('bib.xml')//author)">
    <author>
      <name>{$a/text()}</name>
      <q:for-each select = "document('bib.xml')//book[author = $a]">
        <q:copy select = "title"/>
      </q:for-each>
    </author>
  </q:for-each>
</author_list>
========

========
Example 3:
<publisher_list>{
    FOR $p IN distinct(document("bib.xml")//publisher)
    RETURN
        <publisher>
            <name>{ $p/text() }</name>
            {
                FOR $b IN document("bib.xml")//book[publisher = $p]
                RETURN
                    <book>
                        { $b/title }
                        { $b/price }
                    </book>
                SORTBY(price DESCENDING)
            }
        </publisher>
    SORTBY(name)
}</publisher_list>

I would suggest

<publisher_list>
  <q:for-each name = "p" select = "sort(distinct(document('bib.xml')//publisher), name)">
    <publisher>
      <name>
        <q:value-of select = "$p/text()"/>
        <q:for-each name = "b" select = "sort(document('bib.xml')//book[publisher = $p], price, 'descending')">
          <book>
            <q:copy select = "$b/title"/>
            <q:copy select = "$b/price"/>
          </book>
        </q:for-each>
      </name>
    </publisher>
  </q:for-each>
</publisher_list>

or

<publisher_list>
  <q:variable name = "publishers" select = "distinct(document('bib.xml')//publisher"/>
  <q:for-each name = "p" select = "sort($publishers), name)">
    <publisher>
      <name>{$p/text()}</name>
     <q:variable name = "books" select = "document('bib.xml')//book[publisher = $p]"/>
      <q:for-each name = "b" select = "sort($books, price, 'descending')">
        <book>
          <q:copy select = "$b/title"/>
          <q:copy select = "$b/price"/>
        </book>
      </q:for-each>
    </publisher>
  </q:for-each>
</publisher_list>
========

========
Example 4:
FUNCTION depth (ELEMENT $e) RETURNS xsd:integer
{
    IF empty($e/*)
    THEN 1
    ELSE max(depth($e/*)) + 1
}

depth(document("partlist.xml"))

I would suggest

<q:template name = "depth" type = "xsd:integer">
  <q:param name = "e" type = "element"/>
  <q:choose>
    <q:when test = "$e/*">
      <q:value-of select = "1"/>
    </q:when>
    <q:otherwise>
    <!-- "apply-template" return the array of results after applying the template to each of the selected -->
      <q:variable name = "d">
        <q:apply-template name = "depth" select = "$e/*"/>
      </q:variable>
      <q:value-of select = "max($d) + 1"/>
    </q:otherwise>
  </q:choose>
</q:template>

<q:call-template name = "depth">
  <q:with-param name = "e" select = "document('partlist.xml')"/>
</q:call-template>
========

Understand that these are just examples.  I am not suggesting that what I have presented here is anything like a complete (or even consistent) syntax for XQueryX, but it does make the point that the suggested syntax is unnecessarily verbose and obtuse, and certainly not in the best interests of XML as a syntax for dealing with XML (which is the kind of symmetry that makes XML work where other character-based formats do not).  I would welcome your comments, and would be happy to discuss any limitations that you see in my suggestions.  I am sure that such limitations can be addressed without resorting to the XQueryX 1.0 syntax.

     Cheers,
          Tony.
========
Anthony B. Coates
Leader of XML Architecture & Design
Chief Technology Office
Reuters Plc, London.
tony.coates@reuters.com
========



-----------------------------------------------------------------
        Visit our Internet site at http://www.reuters.com

Any views expressed in this message are those of  the  individual
sender,  except  where  the sender specifically states them to be
the views of Reuters Ltd.

Received on Monday, 2 July 2001 16:31:31 UTC