繁体   English   中英

XML模式:对层次结构较低元素的keyref

[英]XML Schema: keyref to hierarchically lower element

我的XML结构如下:

ROOT
   |_ SetOfBandC (*)
   |               |_ SetOfB (1)
   |               |           |_ ElementB (*)
   |               |           |_ ElementB__Key 
   |               |_ SetOfC (1)
   |                           |_ ElementC (*)
   |                           |_ ElementC__Key 
   |_ ElementD (*)
   |
   |_ SetOfBandC__Key
   |_ ElementD__Key
   |
   |_ ElementD->SetOfBandC__Keyref
   |_ ElementD->ElementB__Keyref

在这种结构中我可以有多个SetOfBandC以及多个ElementBElementC ,但只有1个SetofBSetOfC每个SetOfBandC

问题是, ElementD有keyref引用特定SetOfBandC ,另一个引用ElementB那一套的,但对于检查时,XML验证ElementD->ElementB__Keyref的有效性。它仅仅查找在最后 SetOfBandC ,而不是在所有的它们,或者更好的是,在ElementD->SetOfBandC__Keyref引用的ElementD->SetOfBandC__Keyref 所以,当ElementD->ElementB__Keyref引用了ElementB这是不是在最后SetOfBandC ,验证将无法正常工作。

这是我的ElementD->ElementB__Keyref

<xs:keyref name="ElementD->ElementB__Keyref" refer="tns:ElementB__Key ">
    <xs:selector xpath="tns:ElementD" />
    <xs:field xpath="@elementD_ref" />
</xs:keyref>

还有我的ElementB__Key

<xs:key name="ElementB__Key">
    <xs:selector xpath="tns:ElementB" />
    <xs:field xpath="@elemB_name" />
</xs:key>

其中tns是我的目标名称空间。 我想念什么?

PS:我的代码中的名称不同,并且没有->

我认为问题在于密钥的范围。

据我了解,一个节点不仅可以通过其节点名称进行全局标识,还可以通过所属的nffg名称进行全局标识。 因此,这在全局上是一个复合键:策略指的是具有nffg名称和节点名称的节点。 但是,在当前模式中,策略中的keyRef仅相互独立地引用这两个键,因此XML Schema不知道它们是一起使用的。

也许一种解决方法是使用全局唯一的节点名称,该名称由节点密钥加上nffg密钥(例如Nffg1-Node1 ,并将其用作策略中的单个keyref。 如果还希望确保链接引用同一nffg中的源节点和目标节点,则可能需要为node两个键定义:一个是策略keyRef的全局keyRef (在allNffgsAndPolicies下),一个在allNffgsAndPolicies本地(在下面) nffg )的链接keyRef

一种稍有不同的替代方法是在节点中重复nffgName属性,并将其与未更改的nodeName属性一起用作节点的全局复合键(通过在键中使用两个xs:field元素),可以在策略中使用它。 您应该能够确保节点的本地nffgname属性与具有key s和keyRef的父级nffg匹配。

额外的问题 :它仍然不能解释为什么在原始实例和模式下,拒绝Node3但接受其他值。 我本来希望在两个子树上存在的值上引发错误。 规范中 ,跨子节点的冲突键已从节点表中删除,但是在这种情况下,像Node2这样的键会因为在两个子Node3都发生冲突而不会发生冲突,因为只有在第一个子树中出现的Node3才发生冲突。 但是,这里发生了相反的情况,似乎只有最后一个孩子的节点表才被考虑包含在顶级节点表中。

如果您能够使用XML Schema 1.1,则以下内容无需修改XML文档或架构结构本身即可使用。

  • 删除tns:policy两个keyRef

  • 而是对allNffgsAndPolicies使用复杂类型的allNffgsAndPolicies

     <xs:element name="allNffgsAndPolicies"> <xs:complexType> <xs:sequence> <!-- same content as in original schema --> </xs:sequence> <xs:assert test="every $i in tns:policy satisfies $i/@srcNode = tns:nffg/tns:nodes/tns:node/@nodeName and $i/@destNode = tns:nffg/tns:nodes/tns:node/@nodeName"/> </xs:complexType> <!-- other keys and keyRefs, only keep the first three --> </xs:element> 

我可以在oXygen中成功测试:它可以验证原始文档,如果使用不存在的源或目标节点名称,则验证失败。

要激活XML Schema 1.1,请在xs:schema元素中添加以下属性:

xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning" vc:minVersion="1.1"

要加倍努力:如果最重要的是,您还想确保节点名称存在于策略使用nffgRef引用的nffgRef ,则可以微调断言:

<xs:assert test="
  every $i in tns:policy satisfies
  $i/@srcNode = tns:nffg[@nffgName eq $i/@nffgRef]/tns:nodes/tns:node/@nodeName
  and
  $i/@destNode = tns:nffg[@nffgName eq $i/@nffgRef]/tns:nodes/tns:node/@nodeName"/>

暂无
暂无

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

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