- From: Michael Kay <mike@saxonica.com>
- Date: Wed, 12 Nov 2008 21:23:38 -0000
- To: "'Matt Knowles'" <MattK@LacksValley.com>, <xmlschema-dev@w3.org>
> > I'm new to XML and keep getting the feeling that everything > is upside-down from my normal understanding of scope. I have to confess that I suffer from serious brain-ache whenever a key and a keyref have different scope, and when elements are nested recursively it gets even worse. In this case, I think it's possible to define a rule that the "ref" must refer to an "id" at EVERY level, but I can't see a way to define the rule that it must refer to an "id" at SOME level. I think there's a fundamental reason for this. To determine whether a Section is valid according to your rules, you need to look outside that Section. That means that the rule applies to something larger than a Section; but Section is the outermost element in your model, so there is nothing larger than a Section. Or to put it another way, the rules for the outermost section are different from the rules for inner sections, and therefore they have different types. Even with assertions in XSD 1.1, I think you would need to have different types for the outermost Section and for inner Sections; the outermost Section could have an assertion: every $ref in .//Refer satisfies exists($ref/ancestor::Section/Define[@id eq $ref/@Refer]) You couldn't define this assertion on inner Section elements because one of the rules of assertions is that only the subtree under the current node is visible; the ancestor axis wouldn't see anything outside this Section, so the condition would not be true. Michael Kay http://www.saxonica.com/ > > I have a Schema defined: > > <?xml version="1.0" encoding="utf-8"?> > <xs:schema id="XMLSchema2" > targetNamespace="http://tempuri.org/XMLSchema2.xsd" > elementFormDefault="qualified" > xmlns:s="http://tempuri.org/XMLSchema2.xsd" > xmlns:xs="http://www.w3.org/2001/XMLSchema"> > <xs:element name="Section" type="s:SectionType"> > <xs:key name="DefinitionKey"> > <xs:selector xpath="s:Define"/> > <xs:field xpath="@name"/> > </xs:key> > <xs:keyref name="DefinitionRef" > refer="s:DefinitionKey"> > <xs:selector xpath="s:Refer"/> > <xs:field xpath="@ref"/> > </xs:keyref> > </xs:element> > <xs:complexType name="SectionType" mixed="true"> > <xs:sequence minOccurs="1" maxOccurs="1"> > <xs:sequence minOccurs="0" > maxOccurs="unbounded"> > <xs:element name="Define" > type="s:DefineType"/> > </xs:sequence> > <xs:choice minOccurs="0" > maxOccurs="unbounded"> > <xs:element name="Refer" > type="s:ReferType"/> > <xs:element ref="s:Section"/> > </xs:choice> > </xs:sequence> > </xs:complexType> > <xs:complexType name="DefineType"> > <xs:complexContent> > <xs:extension base="s:SectionType"> > <xs:attribute name="name" > type="xs:string"/> > </xs:extension> > </xs:complexContent> > </xs:complexType> > <xs:complexType name="ReferType"> > <xs:complexContent> > <xs:extension base="s:SectionType"> > <xs:attribute name="ref" > type="xs:string"/> > </xs:extension> > </xs:complexContent> > </xs:complexType> > </xs:schema> > > I have the following instance document: > > <?xml version="1.0" encoding="utf-8" ?> > <Section xmlns="http://tempuri.org/XMLSchema2.xsd"> > <Define name="one"/> > <Refer ref="one"/> <!-- Allow: defined in current node. --> > <Refer ref="two"/> <!-- Error: not defined in current > or ancestor node. --> > <Section> > <Define name="two"/> > <Refer ref="one"/> <!-- Allow: defined in > ancestor node. --> > <Refer ref="two"/> <!-- Allow: defined in > current node. --> > </Section> > </Section> > > I would like to define the keys and keyrefs in the schema > such that I can enforce the rules in the comments above, but > I'm not finding a way to do this. > > Basically, I'm thinking of a node and all it's child nodes as > my scope, and would like to Refer to anything Defined in the > same scope, but disallow any References to things Defined out > of scope. > > The closest I've been able to come is the reverse, where I > can Refer to anything Defined in the current or any > descendant node, by changing: > > <xs:key name="DefinitionKey"> > <xs:selector xpath=".//s:Define"/> > <xs:field xpath="@name"/> > </xs:key> > > Am I hopelessly stuck in a mindset that just doesn't work > with XML? Or is there an obvious solution I'm just overlooking? > > Any help would be greatly appreciated. > > Thanks, > Matt Knowles > > >
Received on Wednesday, 12 November 2008 21:24:19 UTC