Subject:XQuery on all XML Files in a Directory? Author:Neal Walters Date:11 Mar 2005 03:23 PM
Does XQuery have any support to read all files in a directory
(or a mask such as ABC*.xml)
and "peel off" one or two XML elements from each file?
So for example, I have a directory with 300 XML orders in it.
I want to create a unique list of credit card types, or create
a single XML file that contains for example order number
and order amount (for all orders in that directory).
public class FileUtils
{
public static String listFiles(String root) throws URISyntaxException
{
File f = new File(new URI(root));
String[] list = f.list();
StringBuffer sb = new StringBuffer();
for(int i = 0; i < list.length ; i++){
if(sb.length()>0)
sb.append(",");
sb.append(list[i]);
}
return sb.toString();
}
}
---------------------------------
FileDir.xquery
declare namespace ext = "FileUtils";
declare function ext:listFiles($path as xs:string) as xs:string* external;
declare variable $root as xs:string := "file:///c:/Program%20Files/Stylus%20Studio%20XML%20Professional%20Edition/examples/simpleMappings";
<root>
{
for $file in fn:tokenize(ext:listFiles($root), ",")[fn:matches(., ".xml")]
return
<file>{doc(fn:concat($root, "/", $file)) } </file>
}
</root>
Subject:XQuery on all XML Files in a Directory? Author:Neal Walters Date:15 Mar 2005 02:24 PM
I really want to use Xquery, not XSLT for it's join features.
Although I'm a SCJP (Sun Cert. Java Programmer),
I haven't used Java much in about 2 years.
I just spent an hour or two reinstalling the SDK on my laptop which
I have had for almost a year without touching Java.
I would like to share this XQuery with other people, but I the Java
install might be a "kill-joy".
I kind of like your "external variable" idea.
I hope to play with that later. I could run a VBScript
which could build the value of the external variable, then
copy/paste that value. The only problem is that this would be
a manual step that would have to be done any time new files are
added to the directory (and if the directory had 2 or 3 thousand
files in it, that would be a rather large variable value).
Here's some variations of your code that I are working for me:
declare namespace ext = "FileUtils";
declare function ext:listFiles($path as xs:string) as xs:string* external;
declare variable $dirname as xs:string := "file:///c:/Documents%20and%20Settings/nwalters/My%20Documents/Altura/TestDir/";
<root>
{
for $filename in fn:tokenize(ext:listFiles($dirname), ",")
[fn:matches(., ".xml")]
return
<filename>{$filename}</filename>
}
</root>
The above works fine, and displays the filenames.
Your code also worked which displayed the entire doc.
I did change some of your names to make more sense to me.
Below is a fancier version that I then created to
pick off the XML elements/attributes that I was interested
in showing.
declare namespace ext = "FileUtils";
declare function ext:listFiles($path as xs:string) as xs:string* external;
declare variable $dirname as xs:string := "file:///c:/Documents%20and%20Settings/nwalters/My%20Documents/Altura/TestDir/";
<OrderReport>
{
for $filename in fn:tokenize(ext:listFiles($dirname), ",")
[fn:matches(., ".xml")]
, $rootel in doc(fn:concat($dirname, "/", $filename))/CC_TRANSMISSION
return
<filename name='{$filename}'>
<orderNo>{$rootel/CC_ORDER/@ORDER_NO/text()}</orderNo>
<orderAmt>{$rootel/CC_ORDER/TOTALS/TL_TOTAL/text()}</orderAmt>
</filename>
}
</OrderReport>
One of the "gotchas" was that the dirname value must have the %20
instead of blanks. I copied a filename from another place on
Windows, and started getting strange errors.
Subject:XQuery on all XML Files in a Directory? Author:Neal Walters Date:01 Aug 2006 05:27 PM
Hi Ivan,
It's over a year later - and I'm trying this type of code again at another client.
I have found that if the filenames contains braces such as this:
{003D81D1-39CA-4A85-9C63-F5570E9EAA29}.xml
then I get the following error:
Invalid argument to fn:doc function [err: FODC0005]
So is there a replace or something I can do in the Xquery code that will switch left curly to it's hex equivalent? Would that work?
Subject:XQuery on all XML Files in a Directory? Author:Neal Walters Date:01 Aug 2006 06:21 PM
I'm running in the IDE - just a one-time job or a model for future jobs that developers will run (will not go to production).
I was using Built-In, but just now tried switching to Saxon, but then it has trouble with the Java FileUtils.
Error on line 2 column 66 of file:///c:/myquery.xquery
XPST0003:XQuery syntax error in #...tring) as xs:string* exteranl;#;
Saxon does not allow external functions to be declared.
Also, where can one quickly find a list of all the available functions in Xquery (which are the same as XSLT and Xpath, correct?). Is there a function section in Stylus Studio help, or do I need to look elsewhere.
I have gone to Stylus Studio Doc, Search, fn:Concat for example, and do not find anything.
Subject:XQuery on all XML Files in a Directory? Author:Neal Walters Date:02 Aug 2006 03:29 PM
Thanks again for the tip. Here's how I used it:
declare namespace ext = "FileUtils";
declare function ext:listFiles($path as xs:string) as xs:string* external;
declare variable $dirname as xs:string := "file:///c:/xmltest";
<Sample>
{
for $filename in fn:tokenize(ext:listFiles($dirname), ",")
[fn:matches(., ".xml")]
, $rootel in doc(fn:concat($dirname, "/", fn:encode-for-uri($filename)))
return
<filename name='{$filename}'>
<root>{$rootel//*[local-name()='AdminError']/*[local-name()='CorrelationId'][1]}</root>
</filename>
}
</Sample>