RE: Keys and Scope

Thanks very much for the reply Michael.  I'm more than happy to have different types for the outermost Section and then for child Sections.  It sounds like I'll be able to make this work using assertions.

My only question is:  do I continue to use xmlns:xs="http://www.w3.org/2001/XMLSchema" or do I need to refer to a different version?

Thanks again,
Matt

-----Original Message-----
From: Michael Kay [mailto:mike@saxonica.com]
Sent: Wednesday, November 12, 2008 3:24 PM
To: Matt Knowles; xmlschema-dev@w3.org
Subject: RE: Keys and Scope

>
> 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 Friday, 14 November 2008 16:56:42 UTC