2016-09-22 1 views
0

ich folgendes Problem Aussage konfrontiert:Finding Element in XML-Datenbank mit bestimmten Attributwert in xQuery

Für jede Verwaltungseinheit verwaltet von zwei oder mehreren anderen Verwaltungseinheiten, stellen Sie sicher, dass:

  • Sie bezieht sich auf diese co-administrativen Einheiten, indem sie die associatedBy association role verwendet.
  • Jede dieser co-administrativen Einheiten bezieht sich auf die erwähnte gemeinsam verwaltete Einheit, indem sie die CoAdminister-Assoziationsrolle verwendet.

Die Datenbank sieht wie folgt aus:

<?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> 

Ich habe den folgenden XQuery-Ausdruck geschrieben:

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) then (
      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) then() else $administer 
      ) 

      return 
       if ($coAdminCheck) then $candidate else() 
     )   
     else() 


)[position() le $limitErrors] 
return 
(if ($featuresWithErrors) then 'FAILED' else 'PASSED', 
local:error-statistics('TR.featuresWithErrors', count($featuresWithErrors)), 
for $feature in $featuresWithErrors 
    order by $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) })) 

Ich bin aber immer als Ergebnis 'nicht bestanden' zu werden, auch wenn dieser shouldn‘ t sein.

Ich glaube, das Problem in der Aussage liegt:

let $coAdminVal := $administrativeUnits/au:AdministrativeUnit[@gml:id = $administerVal]/au:coAdminister/@xlink:href 

wie $ coAdminVal immer leer zu sein scheint.

Ich habe mehrere andere Möglichkeiten versucht, diese Aussage zu schreiben, aber alle entpuppen falsch sein:

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 

Was ist der richtige Weg, dies zu tun?

+0

Können Sie '$ features' definieren? – joewiz

Antwort

0

Ich bin damit einverstanden, sieht es aus wie das Problem in der Vergleichsausdruck in Ihrem Prädikat liegt:

[@gml:id = $administerVal] 

Da $administerVal ist im Wesentlichen das au:administeredBy/@xlink:href Attribut, schauen wir uns an, was Sie zu vergleichen:

gml:id="NC.MT01402" 
xlink:href="#NC.MT01310" 
xlink:href="#NC.MT01407" 

Der Unterschied ist, dass die @xlink:href Werte mit einem # Zeichen vorangestellt werden. Um dies zu berücksichtigen, ändern Sie Ihren Vergleich zu:

[@gml:id = substring-after($administerVal, "#")] 

Ihr anderer Ansatz der Verwendung schlug fehl, da Sie gefragt wurden, ob ein Wert wie NC.MT01402#NC.MT01402 enthalten. Das Umkehren der Parameter würde funktionieren.

Dasselbe gilt für matches() - obwohl diese Funktion reguläre Ausdrücke verwendet, so dass Zeichen wie . mit jedem Zeichen und nicht nur mit dem Literalzeichen übereinstimmen. Um eine Suche nach dem Zeichen für den Literalzeitraum zu erzwingen, müssen Sie diesen Code z. B. matches("#NC.MT01402", "NC\.MT01402").

die zusätzlichen Komplexität der matches() Given (es sei denn, Sie wirklich Muster anstatt wörtliche Vergleiche passende wollen), würde ich sagen $administerVal mit substring() oder mit ist der beste Ansatz trimmen.

+0

Danke, ich habe es jetzt herausgefunden. Es gab tatsächlich auch ein Problem im xPath-Ausdruck selbst. Dieser Ausdruck hat es funktioniert: 'let $ coAdminVal: = $ administrativeUnits [concat (' # ', string (@ gml: id)) = $ adminsVal]/au: coAdminister/@ xlink: href' –

+0

Freut mich ' auf dem richtigen Weg! – joewiz

Verwandte Themen