xs:key, why is validation passing when key value is not member of key reference?

前端 未结 2 1363
不思量自难忘°
不思量自难忘° 2021-01-20 06:12

I am interested in defining a key constraint in my Xsd. It is my understanding that using xs:key should constrain the value used to a member of a referenced list of values.<

相关标签:
2条回答
  • 2021-01-20 06:51

    As usual, after a good night's rest and a fresh look, spotted no fewer than 2 errors in this exercise.

    1. First error, validating identity constraints is an explicit process, induced via XmlSchemaValidationFlags.ProcessIdentityConstraints set by XmlReaderSettings.ValidationFlag, and
    2. second error, msdn sample contains an error in schema, <xs:selector xpath="part"/> should read <xs:selector xpath="r:part"/>.

    Full working sample is as follows,

    <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 sample

    <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>
    

    simple validator

    [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 讨论(0)
  • 2021-01-20 06:55

    I guess you should use ValidationEventHandler :

    settings.ValidationEventHandler += new ValidationEventHandler (ValidationCallBack);
    
    private static void ValidationCallBack (object sender, ValidationEventArgs args) {}
    
    0 讨论(0)
提交回复
热议问题