繁体   English   中英

在xQuery中在XML数据库中查找具有某些属性值的元素

[英]Finding element in XML database with certain attribute value in xQuery

我正面临以下问题陈述:

对于由两个或多个其他管理单位共同管理的每个管理单位,请验证:

  • 它通过使用managedBy关联角色来指代这些共同管理单位。
  • 这些共同管理单元中的每一个都通过使用coAdminister关联角色来引用提到的共同管理单元。

该数据库如下所示:

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

我编写了以下xQuery表达式:

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) })) 

但是,即使不是这样,我也总是得到“失败”的结果。

我相信问题出在以下陈述中:

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

因为$ coAdminVal似乎总是空的。

我尝试了几种其他方式来编写此语句,但事实证明都是错误的:

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

正确的方法是什么?

我同意,看来问题出在谓词的比较表达式中:

[@gml:id = $administerVal]

由于$administerVal本质上是au:administeredBy/@xlink:href属性,因此让我们看一下要比较的内容:

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

区别在于@xlink:href值前面带有#号。 为了解决这个问题,请将您的比较更改为:

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

您使用contains()其他方法失败,因为您正在询问是否类似NC.MT01402的值包含#NC.MT01402 反转参数即可。

同样适用于matches() -尽管请注意,此函数采用正则表达式模式,所以像这样的字符. 可以匹配任何字符,而不仅仅是文字字符。 要强制搜索立即数字符,您需要对其进行转义,例如matches("#NC.MT01402", "NC\\.MT01402")

考虑到matches()的额外复杂性(除非您真的想要模式匹配而不是文字比较),我想说用substring()或使用contains()修剪$administerVal是最好的方法。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM