...
 
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' ...@@ -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 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 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 -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 -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 #interpreter tests
tests/test.sh utf8 -e 'substring("äbcd",1,3)' tests/test.sh utf8 -e 'substring("äbcd",1,3)'
......
...@@ -840,7 +840,7 @@ TExtraction = class(TDataProcessing) ...@@ -840,7 +840,7 @@ TExtraction = class(TDataProcessing)
extractExclude, extractInclude: TStringArray; extractExclude, extractInclude: TStringArray;
extractKind: TExtractionKind; extractKind: TExtractionKind;
templateUrl: string; extractBaseUri: string;
templateActions: TStringArray; templateActions: TStringArray;
defaultName: string; defaultName: string;
...@@ -1803,13 +1803,17 @@ var ...@@ -1803,13 +1803,17 @@ var
begin begin
if extract = '' then begin if extract = '' then begin
reader.read('extract', extract); //todo. option: extract-file 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); extract:=trim(extract);
if reader.read('extract-exclude', tempstr) then extractExclude := strSplit(tempstr, ',', false); 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('extract-include', tempstr) then extractInclude := strSplit(tempstr, ',', false);
if reader.read('template-file', tempstr) then begin if reader.read('template-file', tempstr) then begin
templateUrl := tempstr; extractBaseUri := tempstr;
extract := strLoadFromFileChecked(tempstr); extract := strLoadFromFileChecked(tempstr);
extractKind := ekMultipage; extractKind := ekMultipage;
end; end;
...@@ -2605,7 +2609,8 @@ begin ...@@ -2605,7 +2609,8 @@ begin
xpathparser.ParsingOptions.StringEntities:=xqseDefault; xpathparser.ParsingOptions.StringEntities:=xqseDefault;
parent.loadDataForQueryPreParse(data); parent.loadDataForQueryPreParse(data);
if extractQueryCache = nil then if extractQueryCache = nil then begin
if extractBaseUri <> '' then xpathparser.StaticContext.baseURI := fileNameExpandToURI(extractBaseUri);
case extractKind of case extractKind of
ekCSS: extractQueryCache := xpathparser.parseCSS3(extract); //todo: optimize ekCSS: extractQueryCache := xpathparser.parseCSS3(extract); //todo: optimize
ekXPath2: extractQueryCache := xpathparser.parseXPath2(extract, xpathparser.StaticContext); ekXPath2: extractQueryCache := xpathparser.parseXPath2(extract, xpathparser.StaticContext);
...@@ -2613,6 +2618,7 @@ begin ...@@ -2613,6 +2618,7 @@ begin
ekXPath3: extractQueryCache := xpathparser.parseXPath3(extract, xpathparser.StaticContext); ekXPath3: extractQueryCache := xpathparser.parseXPath3(extract, xpathparser.StaticContext);
ekXQuery3: extractQueryCache := xpathparser.parseXQuery3(extract, xpathparser.StaticContext); ekXQuery3: extractQueryCache := xpathparser.parseXQuery3(extract, xpathparser.StaticContext);
end; end;
end;
parent.loadDataForQuery(data, extractQueryCache); parent.loadDataForQuery(data, extractQueryCache);
if termContainsVariableDefinition(extractQueryCache.Term) then begin if termContainsVariableDefinition(extractQueryCache.Term) then begin
THtmlTemplateParserBreaker(htmlparser).closeVariableLog; THtmlTemplateParserBreaker(htmlparser).closeVariableLog;
...@@ -2632,7 +2638,7 @@ begin ...@@ -2632,7 +2638,7 @@ begin
multipage.internet := onPrepareInternet(parent.userAgent, parent.proxy, @parent.httpReact); multipage.internet := onPrepareInternet(parent.userAgent, parent.proxy, @parent.httpReact);
multipagetemp := TMultiPageTemplate.create(); multipagetemp := TMultiPageTemplate.create();
if extract = '' then raise Exception.Create('Multipage-action-template is empty'); 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.setTemplate(multipagetemp);
multipage.perform(templateActions); multipage.perform(templateActions);
end end
...@@ -2942,7 +2948,7 @@ begin ...@@ -2942,7 +2948,7 @@ begin
writeln(stderr, logged); writeln(stderr, logged);
end; end;
function loadModuleFromAtUrl(const at, base: string): IXQuery; forward;
procedure traceCall(pseudoSelf: tobject; sender: TXQueryEngine; value, info: IXQValue); procedure traceCall(pseudoSelf: tobject; sender: TXQueryEngine; value, info: IXQValue);
begin begin
...@@ -3310,6 +3316,24 @@ procedure variableRead(pseudoself: TObject; sender: TObject; const name, value: ...@@ -3310,6 +3316,24 @@ procedure variableRead(pseudoself: TObject; sender: TObject; const name, value:
else htmlparser.variableChangeLog.add(trim(temps), strCopyFrom(value, equalSign+1)); else htmlparser.variableChangeLog.add(trim(temps), strCopyFrom(value, equalSign+1));
end; end;
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 var
temps, tempurl: String; temps, tempurl: String;
...@@ -3352,7 +3376,7 @@ begin ...@@ -3352,7 +3376,7 @@ begin
currentContext.readNewAction(TExtraction.Create, cmdlineWrapper); currentContext.readNewAction(TExtraction.Create, cmdlineWrapper);
end else if (name = 'extract-file') then begin end else if (name = 'extract-file') then begin
if isStdin(value) then TCommandLineReaderBreaker(sender).overrideVar('extract', '-') 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); currentContext.readNewAction(TExtraction.Create, cmdlineWrapper);
end else if (name = 'template-file') then begin end else if (name = 'template-file') then begin
currentContext.readNewAction(TExtraction.Create, cmdlineWrapper); currentContext.readNewAction(TExtraction.Create, cmdlineWrapper);
...@@ -3383,6 +3407,8 @@ begin ...@@ -3383,6 +3407,8 @@ begin
tempurl := strSplitGet('=', temps); tempurl := strSplitGet('=', temps);
xpathparser.StaticContext.namespaces.add(TNamespace.create(temps, tempurl)); xpathparser.StaticContext.namespaces.add(TNamespace.create(temps, tempurl));
end; end;
end else if name = 'module' then begin
importModule(value);
end else if (name = '') or (name = 'data') then begin end else if (name = '') or (name = 'data') then begin
if (name = '') and (value = '[') then begin if (name = '') and (value = '[') then begin
pushCommandLineState; pushCommandLineState;
...@@ -3486,23 +3512,34 @@ end; ...@@ -3486,23 +3512,34 @@ end;
var baseContext: TProcessingContext; 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 var
ft: TFollowTo; q: IXQuery;
d: IData;
begin begin
if xpathparser.findModule(namespace) <> nil then exit; if xpathparser.findModule(namespace) <> nil then exit;
for i := 0 to high(at) do begin for i := 0 to high(at) do begin
d := nil; q := loadModuleFromAtUrl(at[i], context.baseURI);
try if q <> nil then begin
ft := TFollowTo.createFromRetrievalAddress(at[i]); xpathparser.registerModule(q);
d := ft.retrieve(baseContext, 0);
ft.free;
except
end;
if d <> nil then begin
xpathparser.registerModule(xpathparser.parseXQuery3(d.rawData));
exit exit
end; end;
end; end;
...@@ -3568,7 +3605,8 @@ begin ...@@ -3568,7 +3605,8 @@ begin
mycmdLine.declareString('xpath3', 'Abbreviation for --extract-kind=xpath3 --extract=...'); mycmdLine.declareString('xpath3', 'Abbreviation for --extract-kind=xpath3 --extract=...');
mycmdLine.declareString('xquery3', 'Abbreviation for --extract-kind=xquery3 --extract=...'); mycmdLine.declareString('xquery3', 'Abbreviation for --extract-kind=xquery3 --extract=...');
mycmdLine.declareFile('template-file', 'Abbreviation for --extract-kind=multipage --extract-file=...'); 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:'); mycmdLine.beginDeclarationCategory('Follow options:');
...@@ -3732,6 +3770,7 @@ begin ...@@ -3732,6 +3770,7 @@ begin
SetLength(baseContext.actions, 1); SetLength(baseContext.actions, 1);
baseContext.actions[0] := TExtraction.create; baseContext.actions[0] := TExtraction.create;
TExtraction(baseContext.actions[0]).extract := strLoadFromFileChecked(ParamStr(1)); TExtraction(baseContext.actions[0]).extract := strLoadFromFileChecked(ParamStr(1));
TExtraction(baseContext.actions[0]).extractBaseUri := ParamStr(1);
baseContext.silent := true; baseContext.silent := true;
end else begin end else begin
writeln(stderr, 'No actions given.'); writeln(stderr, 'No actions given.');
......