Finding element in XML database with certain attribute value in xQuery -
i facing following problem statement:
for each administrative unit co-administered 2 or more other administrative units, verify that:
- it refers these co-administrative units using administeredby association role.
- each of these co-administrative units refers mentioned co-administered unit using coadminister association role.
the database looks follows:
<?xml version "1.0" ?> <wfs:featurecollection xmlns:au="http://inspire.ec.europa.eu/schemas/au/4.0" xmlns:gts="http://www.isotc211.org/2005/gts" xmlns:gco="http://www.isotc211.org/2005/gco" xmlns:ns1="http://www.w3.org/1999/xhtml" xmlns:hfp="http://www.w3.org/2001/xmlschema-hasfacetandproperty" xmlns:gml="http://www.opengis.net/gml/3.2" xmlns:gn="http://inspire.ec.europa.eu/schemas/gn/4.0" xmlns:gss="http://www.isotc211.org/2005/gss" xmlns:gsr="http://www.isotc211.org/2005/gsr" xmlns:base="http://inspire.ec.europa.eu/schemas/base/3.3" xmlns:gmd="http://www.isotc211.org/2005/gmd" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xmlns:wfs="http://www.opengis.net/wfs/2.0" xsi:schemalocation="http://inspire.ec.europa.eu/schemas/au/4.0 http://inspire.ec.europa.eu/schemas/au/4.0/administrativeunits.xsd http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0/wfs.xsd" numbermatched="274" numberreturned="274" timestamp="2016-03-29t18:12:51.630+02:00"> <wfs:member> <au:administrativeunit gml:id="nc.mt01402"> <au:administeredby xlink:href="#nc.mt01310"/> <au:administeredby xlink:href="#nc.mt01407"/> <au:coadminister nilreason="unpopulated"/> </au:administrativeunit> </wfs:member> <wfs:member> <au:administrativeunit gml:id="nc.mt01310"> <au:administeredby nilreason="unpopulated" xsi:nil="true"/> <au:coadminister xlink:href="#nc.mt01402"/> </au:administrativeunit> </wfs:member> <wfs:member> <au:administrativeunit gml:id="nc.mt01407"> <au:upperlevelunit xlink:href="#nc.mt0xxxx"/> <au:administeredby nilreason="unpopulated" xsi:nil="true"/> <au:coadminister xlink:href="#nc.mt01402"/> </au:administrativeunit> </wfs:member> </wfs:featurecollection>
i have written following xquery expression:
let $administrativeunits := $features[self::*:administrativeunit] let $featureswitherrors := (for $candidate in $administrativeunits let $administeredby := $candidate/au:administeredby/@xlink:href let $candidateval := string($candidate/@gml:id) return if (count($administeredby) >= 2) ( let $coadmincheck := (for $administer in $administeredby let $administerval := string($administer) let $coadminval := $administrativeunits/au:administrativeunit[@gml:id = $administerval]/au:coadminister/@xlink:href return if (string($coadminval) = $candidateval) () else $administer ) return if ($coadmincheck) $candidate else () ) else () )[position() le $limiterrors] return (if ($featureswitherrors) 'failed' else 'passed', local:error-statistics('tr.featureswitherrors', count($featureswitherrors)), $feature in $featureswitherrors order $feature/@gml:id return local:addmessage('tr.nocoadministered', map { 'filename': local:filename($feature), 'featuretype': local-name($feature), 'gmlid': string($feature/@gml:id), 'adminby' : string($feature/au:administeredby[1]/@xlink:href) }))
i getting 'failed' result, if shouldn't be.
i believe problem lies in statement:
let $coadminval := $administrativeunits/au:administrativeunit[@gml:id = $administerval]/au:coadminister/@xlink:href
as $coadminval seems empty.
i have tried several other ways write statement, turn out wrong:
let $coadminval := $administrativeunits/au:administrativeunit[matches(@gml:id, $administerval)]/au:coadminister/@xlink:href let $coadminval := $administrativeunits/au:administrativeunit[contains(@gml:id, $administerval)]/au:coadminister/@xlink:href let $coadminval := $administrativeunits/au:administrativeunit[string(@gml:id) = $administerval]/au:coadminister/@xlink:href
what correct way this?
i agree, looks problem lies in comparison expression in predicate:
[@gml:id = $administerval]
since $administerval
au:administeredby/@xlink:href
attribute, let's @ you're comparing:
gml:id="nc.mt01402" xlink:href="#nc.mt01310" xlink:href="#nc.mt01407"
the difference @xlink:href
values prepended #
sign. account this, change comparison to:
[@gml:id = substring-after($administerval, "#")]
your other approach of using contains()
failed because asking if value nc.mt01402
contained #nc.mt01402
. reversing parameters work.
the same applies matches()
- although aware function takes regular expressions patterns, characters .
match character rather literal period character. force search literal period character, need escape it, e.g., matches("#nc.mt01402", "nc\.mt01402")
.
given additional complexities of matches()
(unless want pattern matching rather literal comparisons), i'd trimming $administerval
substring()
or using contains()
best approach.
Comments
Post a Comment