|
next
|
 Subject: XQuery on all XML Files in a Directory? Author: Ivan Pedruzzi Date: 14 Mar 2005 11:25 AM
|
Neal
XQuery doesn't expose direct access to file system.
There are differen approach to solve the problem:
1) define an external variable and let caller fill it with
a sequence of strings that represent the file paths
2) Assuming the file have some name + postfix index like
books001.xml, books002.xml, etc you could write
for $row in 1 to 4
return doc(concat('books00', xs:string($row), '.xml'))
3) use an extension function; here a quick example that concatenates
all .xml files in the simpleMappings directory
---------------------------------------------
FileUtils.java
import java.net.*;
import java.io.*;
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>
Hope this helps
Ivan
|
next
|
 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.
Thanks so much for getting me started with this!
Neal Walters
http://Biztalk-Training.com
http://XML-Online-Training.com
http://VBScript-Training.com
|
|
|
|