跳转到内容

XQuery/验证层次结构

来自维基教科书,开放的书籍,开放的世界

虽然模式验证能检查模型有效性的某些方面,但业务规则通常比能用 XML 模式表示的规则更复杂。XQuery 是描述更复杂规则的一门功能强大的语言。

其中一个规则是关系应当定义树结构,例如员工和经理之间的关系。

考虑以下员工集合

<company>
  <emp>
      <name>Fred</name>
      <mgr>Bill</mgr>
      </emp>
    <emp>
        <name>Joe</name>
        <mgr>Bill</mgr>
    </emp>
    <emp>
        <name>Alice</name>
        <mgr>Joe</mgr>
    </emp>
    <emp>
        <name>Bill</name>
     </emp>
</company>


有效层次结构的标准是

  1. 一个根(老板);
  2. 每位员工最多只有一位经理;
  3. 每位员工最终汇报给老板;
  4. 没有循环

在 XQuery 中,我们可以将从老板到员工的管理层次结构定义为 

declare function local:management($emp as element(emp) ,
       $hierarchy as element(emp)* ) as element(emp)*  {
     if ($emp = $hierarchy )  (: cycle detected :)
     then ()
     else 
       let $mgr :=  $emp/../emp[name=$emp/mgr]
       return
          if (count($mgr) > 1)  
          then ()  
          else
              if (empty ($mgr))  (: reached the root :)
              then ($emp,$hierarchy)
              else local:management($mgr, ($emp,$hierarchy))
};

该函数最初被调用为

 local:managment($emp,())

将层次结构建立为一个允许检测循环的参数。

最终,管理结构成为树的条件是

declare function local:management-is-tree($company)) {
    let $boss := $company/emp[empty(mgr)]
    return 
       count($boss) = 1
            and
      (every $emp in $company/emp
          satisfies $boss = local:management($emp,())[1]
      )
};

华夏公益教科书