Query (c) fails because $intdoc/alist selects nothing. $intdoc is an <alist> element and it does not have an <alist> child. You want $intdoc/self::alist rather than $intdoc/child::alist. (It's a common mistake to think of a sequence as if it is somehow the parent of the items within the sequence).
 
(d) fails for the same reason.
 
(b), (e), and (f) do not have this bug.
 
Michael Kay
http://www.saxonica.com/
 


From: saxon-help-bounces@lists.sourceforge.net [mailto:saxon-help-bounces@lists.sourceforge.net] On Behalf Of Cecil New
Sent: 15 December 2007 17:47
To: saxon-help; cecil.new@gmail.com
Subject: [saxon] Iterating over a collection

I have thousands of small XML files that I wanted to get some basic metrics on.  I used an intermediate document to do so.  But in the process I found something that looks like it may be a bug.  Here are the details using a simplified case.
 
a) each xml file looks like these two:
<archive ssid="258070" name="eship-20010919" size="20" >
<annotation>
anot1
</annotation>
</archive>
 
 
b) This query works ok.  the query is followed by the output

let $intdoc :=
<alist>
{
for $doc in
 collection("file:///d:/Users/asrdcnt/misc/xquery/Collections/bug?select=f*.xml;on-error=fail ")
let $ssid := $doc/archive/@ssid
let $size := $doc/archive/@size
return
 <ssid id="{$ssid}" size="{$size}" />
}
</alist>

return
<total>
{$intdoc}
</total>

<?xml version="1.0" encoding="UTF-8"?>
<total>
   <alist>
      <ssid id="258070" size="20"/>
      <ssid id="258070" size="10"/>
   </alist>
</total>
{$intdoc}
</total>

 c) This query fails (output follows):

let $intdoc :=
<alist>
{
for $doc in
 collection("file:///d:/Users/asrdcnt/misc/xquery/Collections/bug?select=f*.xml;on-error=fail ")
let $ssid := $doc/archive/@ssid
let $size := $doc/archive/@size
return
 <ssid id="{$ssid}" size="{$size}" />
}
</alist>

return
<total>
{$intdoc/alist}
</total>

 <?xml version="1.0" encoding="UTF-8"?>
<total/>
d) This also fails with same empty root <total/>.

let $intdoc :=
<alist>
{
for $doc in
 collection("file:///d:/Users/asrdcnt/misc/xquery/Collections/bug?select=f*.xml;on-error=fail ")
let $ssid := $doc/archive/@ssid
let $size := $doc/archive/@size
return
 <ssid id="{$ssid}" size="{$size}" />
}
</alist>

return
<total>
{$intdoc/alist/ssid}
</total>

 e) Finally, and surprisingly, this works:

let $intdoc :=
<alist>
{
for $doc in
 collection("file:///d:/Users/asrdcnt/misc/xquery/Collections/bug?select=f*.xml;on-error=fail ")
let $ssid := $doc/archive/@ssid
let $size := $doc/archive/@size
return
 <ssid id="{$ssid}" size="{$size}" />
}
</alist>

return
<total>
{$intdoc//ssid}
</total>

 <?xml version="1.0" encoding="UTF-8"?>
<total>
   <ssid id="258070" size="20"/>
   <ssid id="258070" size="10"/>
</total>

f) And finally, summing all sizes works using the version that works

let $intdoc :=
<alist>
{
for $doc in
 collection("file:///d:/Users/asrdcnt/misc/xquery/Collections/bug?select=f*.xml;on-error=fail ")
let $ssid := $doc/archive/@ssid
let $size := $doc/archive/@size
return
 <ssid id="{$ssid}" size="{$size}" />
}
</alist>

return
<total>
{sum($intdoc//ssid/@size)}
</total>

 <?xml version="1.0" encoding="UTF-8"?>
<total>30</total>

Regards