diff --git a/compile.xqm b/compile.xqm
index 1632c17..abc750f 100644
--- a/compile.xqm
+++ b/compile.xqm
@@ -91,11 +91,10 @@ declare function compile:pattern($pattern as element(sch:pattern))
else
let $function-id := compile:function-id($pattern)
return
- ('declare function ' || compile:function-name($pattern) || '(){' ||
- serialize(
+ ('declare function ' || compile:function-name($pattern) || '(){',
+
{$pattern/(@id, @name, @role)}
- ) || ',',
- 'local:rules((' ||
+ , ', local:rules((' ||
string-join(for $rule in $pattern/sch:rule
return ' ' || compile:function-name($rule) || '#0', ',') || '))',
'};',
@@ -114,12 +113,11 @@ declare function compile:pattern-documents($pattern as element(sch:pattern))
'let ' || $compile:SUBORDINATE_DOC_URIS || ':=' ||
$compile:INSTANCE_DOC || '/(' || $pattern/@documents => util:escape() || ')' ||
'let ' || $compile:SUBORDINATE_DOC || ' as document-node()* :=' ||
- $compile:SUBORDINATE_DOC_URIS || '!' || 'doc(.) return (' ||
- serialize(
{$pattern/(@id, @name, @role)}
- ) || ',',
- 'local:rules((' ||
+ , ', local:rules((' ||
string-join(
for $rule in $pattern/sch:rule
return compile:function-name($rule) || '#1',
@@ -135,53 +133,53 @@ declare function compile:rule-documents($rule as element(sch:rule))
{
let $function-name := compile:function-name($rule)
let $assertions as element()+ := $rule/(sch:assert|sch:report)
- return
- 'declare function ' || $function-name || '(' || $compile:SUBORDINATE_DOC ||
- ' as document-node()){' ||
- string-join(util:local-variable-decls($rule/sch:let), ' ') ||
- (if($rule/sch:let) then ' return ' else ()) ||
- util:declare-variable(
- $compile:RULE_CONTEXT_NAME,
- $compile:SUBORDINATE_DOC || '/(' || $rule/@context => util:escape() || ')'
- ) ||
- ' return if(' || $compile:RULE_CONTEXT || ') then (' ||
- serialize(
-
- {$rule/(@id, @name, @context, @role, @flag)}
-
- ) || ', ' || $compile:RULE_CONTEXT || '! (' ||
- string-join(
- for $assertion in $assertions
- return compile:function-name($assertion, true()) || '(.,' || serialize($assertion) || ')',
- ','
- )
- || ')) else ()};' || string-join($assertions ! compile:assertion(., true()))
+ return (
+ 'declare function ' || $function-name || '(' || $compile:SUBORDINATE_DOC ||
+ ' as document-node()){' ||
+ string-join(util:local-variable-decls($rule/sch:let), ' ') ||
+ (if($rule/sch:let) then ' return ' else ()) ||
+ util:declare-variable(
+ $compile:RULE_CONTEXT_NAME,
+ $compile:SUBORDINATE_DOC || '/(' || $rule/@context => util:escape() || ')'
+ ) ||
+ ' return if(' || $compile:RULE_CONTEXT || ') then (',
+
+ {$rule/(@id, @name, @context, @role, @flag)}
+ ,
+ ', ' || $compile:RULE_CONTEXT || '! (',
+ string-join(
+ for $assertion in $assertions
+ return compile:function-name($assertion, true()) || '(.)',
+ ','
+ )
+ || ')) else ()};' || string-join($assertions ! compile:assertion(., true()))
+ )
};
declare function compile:rule($rule as element(sch:rule))
{
let $function-name := compile:function-name($rule)
let $assertions as element()+ := $rule/(sch:assert|sch:report)
- return
- 'declare function ' || $function-name || '(){' ||
- string-join(util:local-variable-decls($rule/sch:let), ' ') ||
- (if($rule/sch:let) then ' return ' else ()) ||
- util:declare-variable(
- $compile:RULE_CONTEXT_NAME,
- $compile:INSTANCE_DOC || '/(' || $rule/@context => util:escape() || ')'
- ) ||
- ' return if(' || $compile:RULE_CONTEXT || ') then (' ||
- serialize(
+ return (
+ 'declare function ' || $function-name || '(){' ||
+ string-join(util:local-variable-decls($rule/sch:let), ' ') ||
+ (if($rule/sch:let) then ' return ' else ()) ||
+ util:declare-variable(
+ $compile:RULE_CONTEXT_NAME,
+ $compile:INSTANCE_DOC || '/(' || $rule/@context => util:escape() || ')'
+ ) ||
+ ' return if(' || $compile:RULE_CONTEXT || ') then (',
- {$rule/(@id, @name, @context, @role, @flag, @document)}
-
- ) || ', ' || $compile:RULE_CONTEXT || '! (' ||
- string-join(
- for $assertion in $assertions
- return compile:function-name($assertion) || '(.,' || serialize($assertion) || ')',
- ','
- )
- || ')) else ()};' || string-join($assertions ! compile:assertion(., false()))
+ {$rule/(@id, @name, @context, @role, @flag)}
+ ,
+ ', ' || $compile:RULE_CONTEXT || '! (' ||
+ string-join(
+ for $assertion in $assertions
+ return compile:function-name($assertion) || '(.)',
+ ','
+ )
+ || ')) else ()};' || string-join($assertions ! compile:assertion(., false()))
+ )
};
declare function compile:assertion(
@@ -193,7 +191,7 @@ declare function compile:assertion(
then error() (:shouldn't happen if schema is valid:)
else
'declare function ' || compile:function-name($assertion, $distinct-name) ||
- '(' || string-join(($compile:RULE_CONTEXT, $compile:ASSERTION), ',') || '){' ||
+ '(' || $compile:RULE_CONTEXT || '){' ||
string-join(compile:pattern-variables($assertion/../../sch:let), ' ') ||
string-join(util:local-variable-decls($assertion/../sch:let), ' ') || ' ' ||
util:declare-variable(
@@ -218,7 +216,8 @@ as element()
}
{
attribute{'location'}{'{path($Q{http://www.andrewsales.com/ns/xqs}context)}'},
- $assertion/(@id, @role, @flag, @test),
+ $assertion/(@id, @role, @flag),
+ attribute{'test'}{$assertion/@test => replace('\{', '{{') => replace('\}', '}}')},
$assertion/root()//sch:diagnostic[@id = tokenize($assertion/@diagnostics)]
!
@@ -274,9 +273,9 @@ declare %private function compile:function-id($element as element())
};
declare function compile:assertion-message-content($content as node()*)
-(: as element(svrl:text) :)
+as element(svrl:text)
{
- element{QName("http://purl.oclc.org/dsdl/svrl", "text")}{(:TODO attributes:)
+ {(:TODO attributes:)
for $node in $content
return
typeswitch($node)
@@ -294,7 +293,7 @@ declare function compile:assertion-message-content($content as node()*)
case element(sch:span)
return output:assertion-child-elements($node)
default return $node
- }
+ }
};
(:~ Builds the string of variable declarations in the prolog, for initial
diff --git a/test/test-compile.xqm b/test/test-compile.xqm
index c0a4590..f9ca049 100644
--- a/test/test-compile.xqm
+++ b/test/test-compile.xqm
@@ -516,13 +516,39 @@ declare %unit:test function _:assertion-message-braces()
)
let $result := xquery:eval(
$compiled,
- map{$_:DOC_PARAM:document{}}
+ map{$_:DOC_PARAM:document{{{}}}}
)
return (
unit:assert(count($result/svrl:successful-report) = 2)
)
};
+declare %unit:test function _:test-message-braces()
+{
+ let $compiled := compile:schema(
+
+
+
+
+
+
+
+ ,
+ ''
+ )
+ let $result := xquery:eval(
+ $compiled,
+ map{$_:DOC_PARAM:document{{{}}}}
+ )
+ return (
+ unit:assert($result/svrl:successful-report),
+ unit:assert-equals(
+ count($result/svrl:successful-report),
+ 2
+ )
+ )
+};
+
(:DOCUMENTS ATTRIBUTE:)
declare %unit:test function _:pattern-documents()
diff --git a/utils.xqm b/utils.xqm
index 29b3deb..828c874 100644
--- a/utils.xqm
+++ b/utils.xqm
@@ -83,13 +83,15 @@ as xs:QName
)
};
-(:~ Escape ampersands in dynamically-evaluated queries.
+(:~ Escape ampersands and braces in dynamically-evaluated queries.
: @param query the string of the query to escape
:)
declare function util:escape($query as xs:string)
as xs:string
{
- replace($query, '&', '&')
+ replace($query, '&', '&')
+ => replace('\{', '{')
+ => replace('\}', '}')
};
declare function util:declare-variable(