3

Xsd で重要な制約を定義することに関心があります。usingは、参照される値のリストのメンバーに使用される値を制限する必要があることを理解しています。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

2 に答える 2

4

いつものように、おやすみなさいと新鮮な表情をした後、この演習で2つ以上のエラーを見つけました。

  1. 最初のエラー、ID制約の検証は明示的なプロセスであり、によってXmlSchemaValidationFlags.ProcessIdentityConstraints設定されたXmlReaderSettings.ValidationFlag、および
  2. 2番目のエラーであるmsdnサンプルには、スキーマにエラーが含まれています。<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()) { }
}
于 2010-05-19T14:29:27.713 に答える
0

ValidationEventHandlerを使用する必要があると思います:

settings.ValidationEventHandler += new ValidationEventHandler (ValidationCallBack);

private static void ValidationCallBack (object sender, ValidationEventArgs args) {}
于 2010-05-18T22:09:09.457 に答える