我的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
以及多个ElementB
和ElementC
,但每个{{1}只有SetofB
和SetOfC
}}。
问题是SetOfBandC
有一个引用特定ElementD
的keyref,另一个引用该集合的SetOfBandC
,但是在检查ElementB
时是XML Validator它的有效性仅在 last ElementD->ElementB__Keyref
中搜索,而不是在所有这些中搜索,或者更好地在SetOfBandC
引用的那个中搜索。
因此,当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
其中tns是我的目标命名空间。我错过了什么?
PS:我的代码中的名称不同,其中没有<xs:key name="ElementB__Key">
<xs:selector xpath="tns:ElementB" />
<xs:field xpath="@elemB_name" />
</xs:key>
。
答案 0 :(得分:1)
我认为问题在于密钥的范围。
据我了解,节点不仅通过其节点名称进行全局标识,而且还通过属于的名称进行全局标识。因此,这是一个复合键:策略是指具有nffg名称的节点以及节点名称。在当前架构中,策略中的keyRef
仅相互独立地引用这两个键,因此XML Schema不知道它们是一起的。
可能一种方法是使用全局唯一的节点名称,该节点名称使用nffg键作为前缀,例如Nffg1-Node1
,并将其用作策略中的单个keyref。如果您还想确保链接引用同一个nffg 中的源节点和目标节点,则可能需要node
的两个关键定义:一个用于策略的全局{{1 s(在keyRef
下),一个本地的nffg(在allNffgsAndPolicies
下),用于链接nffg
。
稍微不同的替代方法是在节点中重复keyRef
属性,并将其与未更改的nffgName
属性一起用作节点的全局复合键 - 使用两个nodeName
密钥中的元素 - 您可以在策略中使用。您应该能够确保节点的本地xs:field
属性与父级nffg的属性匹配nffgname
和key
。
加分问题:它仍然无法解释为什么在原始实例和架构中,keyRef
被拒绝但其他值被接受。我原以为错误会抛出两个子树上的值。在specification中,子节点之间的冲突密钥将从节点表中删除,但在这种情况下,像Node3
这样的密钥会在两个子树上发生冲突,但不会与Node2
冲突。仅出现在第一个子树中。相反的情况发生在此处,并且只有最后一个子节点表似乎被认为包含在顶级节点表中。
答案 1 :(得分:1)
如果您能够使用XML Schema 1.1,则以下内容不应修改XML文档或架构结构本身。
删除keyRef
tns:policy
个{}
相反,在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
的策略引用的nffg中,您可以对该断言进行微调:
<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"/>