...
 
module namespace foobar2 = "pseudo://test-module2";
import module namespace foo = "pseudo://test-module" at "module.xq";
declare variable $foobar2:def := $foo:abc * 1000 ;
import module namespace foobar2 = "pseudo://test-module2" at "../../tests/module2.xqm";
$foobar2:def
......@@ -412,7 +412,15 @@ tests/test.sh moduleVars -e 'declare variable $a:=123; ()' -e '$a'
tests/test.sh moduleFunc1 -e 'declare variable $a:=123; declare function local:xyz(){456}; 8' -e 'local:xyz()+$a'
tests/test.sh moduleFunc2 -e 'declare variable $a:=123; declare function local:xyz(){456}; ()' -e 'declare function local:abc(){$a*1000}; local:xyz() + local:abc()'
tests/test.sh moduleFuncImport -e 'import module namespace foobar = "pseudo://test-module" at "tests/module.xq"; ()' -e '$foobar:abc'
tests/test.sh moduleFuncImport --module tests/module.xq -e '$foobar:abc'
tests/test.sh moduleFuncImport2 -e 'import module namespace rename = "pseudo://test-module" at "tests/module.xq"; ()' -e 'rename:test()'
tests/test.sh moduleFuncImport2 --module tests/module.xq -e 'foobar:test()'
tests/test.sh moduleFuncImport2 --module rename=tests/module.xq -e 'rename:test()'
tests/test.sh moduleFuncImportRel --module tests/module2.xqm -e '$foobar2:def'
tests/test.sh moduleFuncImportRel -e 'import module namespace rename = "pseudo://test-module2" at "tests/module2.xqm"; $rename:def'
tests/test.sh moduleFuncImportRel --extract-file tests/subdir/test.xq
tests/test.sh moduleFuncImportRel tests/subdir/test.xq
#interpreter tests
tests/test.sh utf8 -e 'substring("äbcd",1,3)'
......
......@@ -840,7 +840,7 @@ TExtraction = class(TDataProcessing)
extractExclude, extractInclude: TStringArray;
extractKind: TExtractionKind;
templateUrl: string;
extractBaseUri: string;
templateActions: TStringArray;
defaultName: string;
......@@ -1803,13 +1803,17 @@ var
begin
if extract = '' then begin
reader.read('extract', extract); //todo. option: extract-file
if not cgimode and strBeginsWith(extract, '@') then extract := strLoadFromFileChecked(strCopyFrom(extract, 2));
if not cgimode and strBeginsWith(extract, '@') then begin
extractBaseUri := strCopyFrom(extract, 2);
extract := strLoadFromFileChecked(extractBaseUri);
end;
extract:=trim(extract);
if reader.read('extract-exclude', tempstr) then extractExclude := strSplit(tempstr, ',', false);
if reader.read('extract-include', tempstr) then extractInclude := strSplit(tempstr, ',', false);
if reader.read('template-file', tempstr) then begin
templateUrl := tempstr;
extractBaseUri := tempstr;
extract := strLoadFromFileChecked(tempstr);
extractKind := ekMultipage;
end;
......@@ -2605,7 +2609,8 @@ begin
xpathparser.ParsingOptions.StringEntities:=xqseDefault;
parent.loadDataForQueryPreParse(data);
if extractQueryCache = nil then
if extractQueryCache = nil then begin
if extractBaseUri <> '' then xpathparser.StaticContext.baseURI := fileNameExpandToURI(extractBaseUri);
case extractKind of
ekCSS: extractQueryCache := xpathparser.parseCSS3(extract); //todo: optimize
ekXPath2: extractQueryCache := xpathparser.parseXPath2(extract, xpathparser.StaticContext);
......@@ -2613,6 +2618,7 @@ begin
ekXPath3: extractQueryCache := xpathparser.parseXPath3(extract, xpathparser.StaticContext);
ekXQuery3: extractQueryCache := xpathparser.parseXQuery3(extract, xpathparser.StaticContext);
end;
end;
parent.loadDataForQuery(data, extractQueryCache);
if termContainsVariableDefinition(extractQueryCache.Term) then begin
THtmlTemplateParserBreaker(htmlparser).closeVariableLog;
......@@ -2632,7 +2638,7 @@ begin
multipage.internet := onPrepareInternet(parent.userAgent, parent.proxy, @parent.httpReact);
multipagetemp := TMultiPageTemplate.create();
if extract = '' then raise Exception.Create('Multipage-action-template is empty');
multipagetemp.loadTemplateFromString(extract, ExtractFileName(templateUrl), ExtractFileDir(templateUrl));
multipagetemp.loadTemplateFromString(extract, ExtractFileName(extractBaseUri), ExtractFileDir(extractBaseUri));
multipage.setTemplate(multipagetemp);
multipage.perform(templateActions);
end
......@@ -2942,7 +2948,7 @@ begin
writeln(stderr, logged);
end;
function loadModuleFromAtUrl(const at, base: string): IXQuery; forward;
procedure traceCall(pseudoSelf: tobject; sender: TXQueryEngine; value, info: IXQValue);
begin
......@@ -3310,6 +3316,24 @@ procedure variableRead(pseudoself: TObject; sender: TObject; const name, value:
else htmlparser.variableChangeLog.add(trim(temps), strCopyFrom(value, equalSign+1));
end;
end;
procedure importModule(value: string);
var
q: IXQuery;
namespace: INamespace;
i: integer;
prefix: String;
begin
i := pos('=', value);
if i > 0 then prefix := strSplitGet('=', value)
else prefix := '';
q := loadModuleFromAtUrl(value, xpathparser.StaticContext.baseURI);
if q = nil then raise Exception.Create('Failed to load module ' + value);
xpathparser.registerModule(q);
namespace := (q as TXQuery).getStaticContext.moduleNamespace;
if xpathparser.staticContext.importedModules = nil then xpathparser.staticContext.importedModules := TXQMapStringObject.Create;
if prefix = '' then prefix := namespace.getPrefix;
xpathparser.staticContext.importedModules.AddObject(prefix, q as txquery);
end;
var
temps, tempurl: String;
......@@ -3352,7 +3376,7 @@ begin
currentContext.readNewAction(TExtraction.Create, cmdlineWrapper);
end else if (name = 'extract-file') then begin
if isStdin(value) then TCommandLineReaderBreaker(sender).overrideVar('extract', '-')
else TCommandLineReaderBreaker(sender).overrideVar('extract', strLoadFromFileChecked(value));
else TCommandLineReaderBreaker(sender).overrideVar('extract', '@' + value);
currentContext.readNewAction(TExtraction.Create, cmdlineWrapper);
end else if (name = 'template-file') then begin
currentContext.readNewAction(TExtraction.Create, cmdlineWrapper);
......@@ -3383,6 +3407,8 @@ begin
tempurl := strSplitGet('=', temps);
xpathparser.StaticContext.namespaces.add(TNamespace.create(temps, tempurl));
end;
end else if name = 'module' then begin
importModule(value);
end else if (name = '') or (name = 'data') then begin
if (name = '') and (value = '[') then begin
pushCommandLineState;
......@@ -3486,23 +3512,34 @@ end;
var baseContext: TProcessingContext;
function loadModuleFromAtUrl(const at, base: string): IXQuery;
var d: IData;
ft: TFollowTo;
url, oldBaseUri: String;
begin
url := strResolveURI(at, base);
try
ft := TFollowTo.createFromRetrievalAddress(url);
d := ft.retrieve(baseContext, 0);
ft.free;
except
exit(nil);
end;
oldBaseUri := xpathparser.StaticContext.baseURI;
xpathparser.StaticContext.baseURI := url;
result := xpathparser.parseXQuery3(d.rawData);
xpathparser.StaticContext.baseURI := oldBaseUri;
end;
procedure importModule(pseudoSelf: tobject; sender: TXQueryEngine; const namespace: string; const at: array of string);
procedure importModule(pseudoSelf: tobject; sender: TXQueryEngine; context: TXQStaticContext; const namespace: string; const at: array of string);
var
ft: TFollowTo;
d: IData;
q: IXQuery;
begin
if xpathparser.findModule(namespace) <> nil then exit;
for i := 0 to high(at) do begin
d := nil;
try
ft := TFollowTo.createFromRetrievalAddress(at[i]);
d := ft.retrieve(baseContext, 0);
ft.free;
except
end;
if d <> nil then begin
xpathparser.registerModule(xpathparser.parseXQuery3(d.rawData));
q := loadModuleFromAtUrl(at[i], context.baseURI);
if q <> nil then begin
xpathparser.registerModule(q);
exit
end;
end;
......@@ -3568,7 +3605,8 @@ begin
mycmdLine.declareString('xpath3', 'Abbreviation for --extract-kind=xpath3 --extract=...');
mycmdLine.declareString('xquery3', 'Abbreviation for --extract-kind=xquery3 --extract=...');
mycmdLine.declareFile('template-file', 'Abbreviation for --extract-kind=multipage --extract-file=...');
mycmdLine.declareString('template-action', 'Select which action from the multipage template should be run (multiple actions are allowed with comma separated values)');
mycmdLine.declareString('template-action', 'Select which action from the multipage template should be run (multiple actions separated by commas)');
mycmdLine.declareFile('module', 'Imports an xpath/xquery module');
mycmdLine.beginDeclarationCategory('Follow options:');
......@@ -3732,6 +3770,7 @@ begin
SetLength(baseContext.actions, 1);
baseContext.actions[0] := TExtraction.create;
TExtraction(baseContext.actions[0]).extract := strLoadFromFileChecked(ParamStr(1));
TExtraction(baseContext.actions[0]).extractBaseUri := ParamStr(1);
baseContext.silent := true;
end else begin
writeln(stderr, 'No actions given.');
......