2010-05-18 4 views
3

내 Xsd에서 키 제약 조건을 정의하는 데 관심이 있습니다. It is my understanding that using xs:key should constrain the value used to a member of a referenced list of values.xs : key, 키 값이 키 참조의 멤버가 아닐 때 유효성 검사가 통과하는 이유는 무엇입니까?

우리가 샘플 XSD를 사용하는 가정,

<xs:schema 
     xmlns:xs="http://www.w3.org/2001/XMLSchema" 
     targetNamespace="namespace1" 
     xmlns:r="namespace1" 
     elementFormDefault="qualified"> 

    <xs:element name="root"> 
    <xs:complexType> 
     <xs:sequence> 

     <xs:element name="A" type="r:A" maxOccurs="unbounded"> 
      <xs:keyref name="dummy" refer="r:pNumKey"> 
      <xs:selector xpath="part"/> 
      <xs:field xpath="@ref-number"/> 
      </xs:keyref> 
     </xs:element> 

     <xs:element name="B" type="r:B"/> 

     </xs:sequence> 
    </xs:complexType> 

    <xs:key name="pNumKey"> 
     <xs:selector xpath="r:B/r:part"/> 
     <xs:field xpath="@key-number"/> 
    </xs:key> 

    </xs:element> 

    <xs:complexType name="A"> 
    <xs:sequence> 
     <xs:element name="part" maxOccurs="unbounded"> 
     <xs:complexType> 
      <xs:simpleContent> 
      <xs:extension base="xs:string"> 
       <xs:attribute name="ref-number" type="xs:integer"/> 
      </xs:extension> 
      </xs:simpleContent> 
     </xs:complexType> 
     </xs:element> 
    </xs:sequence> 
    </xs:complexType> 

    <xs:complexType name="B"> 
    <xs:sequence> 
     <xs:element name="part" maxOccurs="unbounded"> 
     <xs:complexType> 
      <xs:simpleContent> 
      <xs:extension base="xs:string"> 
       <xs:attribute name="key-number" type="xs:integer"/> 
      </xs:extension> 
      </xs:simpleContent> 
     </xs:complexType> 
     </xs:element> 
    </xs:sequence> 
    </xs:complexType> 

</xs:schema> 

샘플 XML,

<root xmlns="namespace1"> 
    <A> 
    <!-- 
     if the ref-number is not equal to one of the key-number, 
     the validation will give error 
    --> 
    <part ref-number="1"/> 
    </A> 
    <A> 
    <!-- 
     if the ref-number is not equal to one of the key-number, 
     the validation will give error 
    --> 
    <part ref-number="2"/> 
    </A> 
    <B> 
    <part key-number="1"/> 
    <part key-number="2"/> 
    <part key-number="3"/> 
    </B> 
</root> 

하고, 말,

[TestMethod] 
public void Test_Schema() 
{ 
    string schemaFileName = @"sampleSchema.xsd"; 
    string xmlFileName = @"sampleXml.xml"; 
    XmlReaderSettings settings = new XmlReaderSettings 
    { 
     ValidationType = ValidationType.Schema, 
     ValidationFlags = 
      XmlSchemaValidationFlags.ProcessInlineSchema | 
      XmlSchemaValidationFlags.ProcessSchemaLocation | 
      XmlSchemaValidationFlags.ReportValidationWarnings, 
    }; 
    settings.Schemas.Add (schema); 
    settings.ValidationEventHandler += 
     (o, e) => { throw new Exception("CRASH"); }; 

    XmlSchema schema = 
     XmlSchema.Read (
     File.OpenText (schemaFileName), 
     (o, e) => { throw new Exception ("BOOM"); }); 

    XmlReader reader = XmlReader.Create (xmlFileName, settings); 
    while (reader.Read()) { } 
} 

어떻게 그것을, 검증 여전히 몇 가지 간단한 검증 A/part[@ref-number]에 잘못된 값을 사용하면 성공할 수 있습니까?

<root xmlns="namespace1"> 
    <A> 
    <!-- doesn't go CRASH BOOM bang! why not? :(--> 
    <part ref-number="5"/> 
    </A> 
    <B> 
    <part key-number="1"/> 
    <part key-number="2"/> 
    <part key-number="3"/> 
    </B> 
</root> 

위의 Xsd, Xml 또는 유효성 검사 중 하나 또는 모두가 잘못 되었습니까? 아니면 xs:key의 의도 된 목적을 오해 했습니까?

답변

4

가, 좋은 밤의 휴식과 신선한 모습 후,이 연습에 더 미만 이 오류를 발견하지 않습니다.

  1. 우선 에러 신원 제약 검증하는 msdn sample 스키마에 오류가 포함 XmlReaderSettings.ValidationFlag 설정 XmlSchemaValidationFlags.ProcessIdentityConstraints
  2. 초 오차로 인한, 명시 적 과정, <xs:selector xpath="part"/><xs:selector xpath="r:part"/>를 판독한다. 다음과 같이

전체 작업 예제는

<xs:schema 
     xmlns:xs="http://www.w3.org/2001/XMLSchema" 
     targetNamespace="namespace1" 
     xmlns:r="namespace1" 
     elementFormDefault="qualified"> 
    <xs:element name="root"> 
    <xs:complexType> 
     <xs:sequence> 
     <xs:element name="A" type="r:A" maxOccurs="unbounded"> 
      <xs:keyref name="dummy" refer="r:pNumKey"> 
      <!-- without 'r:' below, key was not recognized, boo-urns msdn! --> 
      <xs:selector xpath="r:part"/> 
      <xs:field xpath="@ref-number"/> 
      </xs:keyref> 
     </xs:element> 
     <xs:element name="B" type="r:B"/> 
     </xs:sequence> 
    </xs:complexType> 
    <xs:key name="pNumKey"> 
     <xs:selector xpath="r:B/r:part"/> 
     <xs:field xpath="@key-number"/> 
    </xs:key> 
    </xs:element> 

    <xs:complexType name="A"> 
    <xs:sequence> 
     <xs:element name="part" maxOccurs="unbounded"> 
     <xs:complexType> 
      <xs:simpleContent> 
      <xs:extension base="xs:string"> 
       <xs:attribute name="ref-number" type="xs:integer"/> 
      </xs:extension> 
      </xs:simpleContent> 
     </xs:complexType> 
     </xs:element> 
    </xs:sequence> 
    </xs:complexType> 

    <xs:complexType name="B"> 
    <xs:sequence> 
     <xs:element name="part" maxOccurs="unbounded"> 
     <xs:complexType> 
      <xs:simpleContent> 
      <xs:extension base="xs:string"> 
       <xs:attribute name="key-number" type="xs:integer"/> 
      </xs:extension> 
      </xs:simpleContent> 
     </xs:complexType> 
     </xs:element> 
    </xs:sequence> 
    </xs:complexType> 
</xs:schema> 

XML을 샘플

<root xmlns="namespace1"> 
    <A> 
    <!-- goes CRASH BOOM bang! failure for the win! --> 
    <part ref-number="5"/> 
    </A> 
    <B> 
    <part key-number="1"/> 
    <part key-number="2"/> 
    <part key-number="3"/> 
    </B> 
</root> 

간단한 검증

[TestMethod] 
public void Test_Schema() 
{ 
    string schemaFileName = @"sampleSchema.xsd"; 
    string xmlFileName = @"sampleXml.xml"; 

    XmlSchema schema = 
     XmlSchema.Read(
     File.OpenText(schemaFileName), 
     (o, e) => { throw new Exception("BOOM"); }); 

    XmlReaderSettings settings = new XmlReaderSettings 
    { 
     ValidationType = ValidationType.Schema, 
     ValidationFlags = 
      XmlSchemaValidationFlags.ProcessInlineSchema | 
      XmlSchemaValidationFlags.ProcessSchemaLocation | 
      XmlSchemaValidationFlags.ReportValidationWarnings | 

      // d'oh! explicit flag for processing identity constraints! 
      XmlSchemaValidationFlags.ProcessIdentityConstraints, 
    }; 
    settings.Schemas.Add(schema); 
    settings.ValidationEventHandler += 
     (o, e) => { throw new Exception("CRASH"); }; 

    XmlReader reader = XmlReader.Create(xmlFileName, settings); 
    while (reader.Read()) { } 
} 
+0

'ProcessIdentityConstraints'는 [MSDN] (http://msdn.microsoft.com/en-us/library/system.xml.xmlreader.aspx)에 따라 기본적으로 활성화되어 있습니다. 'System.Xml.Schema'의 확장 메소드'XDocument.Load (inputXmlPath) .Validate (schemas, null)'은 잘 동작합니다. – ilyaigpetrov

0

나는 당신의 ValidationEventHandler를 사용해야합니다 같아요

평소처럼
settings.ValidationEventHandler += new ValidationEventHandler (ValidationCallBack); 

private static void ValidationCallBack (object sender, ValidationEventArgs args) {} 
+0

좋은 생각하지만, 아니입니다. 여전히 유효성 검사를 통과합니다. 설정 개체에 명시적인 유효성 검사 이벤트 처리기를 포함시키기 위해 내 게시물을 수정했습니다. –