My XML structure is the following:
ROOT
|_ SetOfBandC (*)
| |_ SetOfB (1)
| | |_ ElementB (*)
| | |_ ElementB__Key
| |_ SetOfC (1)
| |_ ElementC (*)
| |_ ElementC__Key
|_ ElementD (*)
|
|_ SetOfBandC__Key
|_ ElementD__Key
|
|_ ElementD->SetOfBandC__Keyref
|_ ElementD->ElementB__Keyref
In this structure I can have multiple SetOfBandC as well as multiple ElementB and ElementC, but only 1 SetofB and SetOfC for each SetOfBandC.
The problem is that ElementD has a keyref referencing a particular SetOfBandC and another one referencing a ElementB of that set, but the XML Validator when checking for the ElementD->ElementB__Keyref's validity it only searches in the last SetOfBandC, and not in all of them or, better, in the one referenced by ElementD->SetOfBandC__Keyref.
So when ElementD->ElementB__Keyref references an ElementB which is not in the last SetOfBandC, validation won't work.
Here is my 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>
And my ElementB__Key:
<xs:key name="ElementB__Key">
<xs:selector xpath="tns:ElementB" />
<xs:field xpath="@elemB_name" />
</xs:key>
Where tns is my target namespace. What am I missing?
PS: names in my code are different and there are not -> in them.
I think the issue is with the scope of the keys.
As far as I understand, a node is globally identified not only by its node name, but also by the name of the nffg is belongs to. This is thus globally a compound key: a policy refers to a node with an nffg name as well as a node name. In the current schema, the
keyRefs in policies however only refer to these two keys independently from each other, so XML Schema doesn't know that they go together.Maybe a way out would be to use globally unique node names made of prefixing the node key with the nffg key, like
Nffg1-Node1, and to use this instead as a single keyref in the policy. If you also want to make sure that a link refers to a source and destination node within the same nffg, you may need two key definitions fornode: one global for the policykeyRefs (underallNffgsAndPolicies), one local to an nffg (undernffg) for the linkkeyRefs.A slightly different alternative is to repeat the
nffgNameattribute in nodes, and use this together with the unchangednodeNameattribute as a global compound key for nodes -- by using twoxs:fieldelements in the key -- that you can use in policies. You should be able to ensure that a node's localnffgnameattribute matches that of the parent nffg withkeys andkeyRefs as well.Bonus question: it still does not explain why, with the original instance and schema,
Node3is rejected but other values are accepted. I would have expected the error to be thrown on a value present on both subtrees. In the specification, conflicting keys across children are removed from the node table, however in this case a key likeNode2would be conflicting as it is on both subtrees, but notNode3as it only appears in the first subtree. The contrary happens here though and only the last child's node table seems to be considered for inclusion in the top-level node table.