1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
(:**************************************************************:)
(: Test: functx-functx-dynamic-path-4 :)
(: Written by: Priscilla Walmsley (Frans Englich is maintainer) :)
(: Date: 2008-05-16+02:00 :)
(:**************************************************************:)
declare namespace functx = "http://www.example.com/";
(:~
: Dynamically evaluates a simple XPath path
:
: @author Priscilla Walmsley, Datypic
: @version 1.0
: @see http://www.xqueryfunctions.com/xq/functx_dynamic-path.html
: @param $parent the root to start from
: @param $path the path expression
:)
declare function functx:dynamic-path
( $parent as node() ,
$path as xs:string ) as item()* {
let $nextStep := functx:substring-before-if-contains($path,'/')
let $restOfSteps := substring-after($path,'/')
for $child in
($parent/*[functx:name-test(name(),$nextStep)],
$parent/@*[functx:name-test(name(),
substring-after($nextStep,'@'))])
return if ($restOfSteps)
then functx:dynamic-path($child, $restOfSteps)
else $child
} ;
(:~
: Whether a name matches a list of names or name wildcards
:
: @author Priscilla Walmsley, Datypic
: @version 1.0
: @see http://www.xqueryfunctions.com/xq/functx_name-test.html
: @param $testname the name to test
: @param $names the list of names or name wildcards
:)
declare function functx:name-test
( $testname as xs:string? ,
$names as xs:string* ) as xs:boolean {
$testname = $names
or
$names = '*'
or
functx:substring-after-if-contains($testname,':') =
(for $name in $names
return substring-after($name,'*:'))
or
substring-before($testname,':') =
(for $name in $names[contains(.,':*')]
return substring-before($name,':*'))
} ;
(:~
: Performs substring-after, returning the entire string if it does not contain the delimiter
:
: @author Priscilla Walmsley, Datypic
: @version 1.0
: @see http://www.xqueryfunctions.com/xq/functx_substring-after-if-contains.html
: @param $arg the string to substring
: @param $delim the delimiter
:)
declare function functx:substring-after-if-contains
( $arg as xs:string? ,
$delim as xs:string ) as xs:string? {
if (contains($arg,$delim))
then substring-after($arg,$delim)
else $arg
} ;
(:~
: Performs substring-before, returning the entire string if it does not contain the delimiter
:
: @author Priscilla Walmsley, Datypic
: @version 1.0
: @see http://www.xqueryfunctions.com/xq/functx_substring-before-if-contains.html
: @param $arg the string to substring
: @param $delim the delimiter
:)
declare function functx:substring-before-if-contains
( $arg as xs:string? ,
$delim as xs:string ) as xs:string? {
if (contains($arg,$delim))
then substring-before($arg,$delim)
else $arg
} ;
let $in-xml := <authors>
<author test="abc">
<first>Kate</first>
<last>Jones</last>
</author>
<author>
<first>John</first>
<a:last xmlns:a="http://a">Doe</a:last>
</author>
</authors>
return (functx:dynamic-path(
$in-xml,'author/a:last'))
|