Richtige Verwendung des Schlüssels in xsd

Ich schreibe ein XSD-Schema für ein Projekt, an dem ich arbeite. Das folgende Schema ist eines, das ich einem Microsoft-Beispiel entnommen und leicht modifiziert habe.

Ich versuche, mithilfe von key und keyref einen eindeutigen Schlüssel für einen Satz von Elementen zu deklarieren und dann in einem anderen Abschnitt auf diesen Schlüssel zu verweisen.

Ich konnte es lange nicht zum Laufen bringen. Ich würde das Schema schreiben und ein Testdokument einrichten, das die Validierung aufgrund von (1) doppelten Schlüsseln und (2) Refkeys, die auf nicht vorhandene Schlüssel verweisen, jedoch weiterhin bestehen, nicht bestehen sollte.

Nachdem ich ein paar Mal an einem Beispiel herumgebastelt und es ausgearbeitet hatte, ging es an die Arbeit. Also habe ich versucht, es auf das zu beschränken, was in dem Beispiel funktioniert hat, aber es hat dazu geführt, dass es in meinem ursprünglichen Versuch nicht funktioniert hat.

Ich überprüfe mit .NET XmlDocument und XmlSchema. Ich werde meinen Test-Validierungscode unten einfügen.

Meine Frage ist, warum funktioniert der Schlüssel, wenn er wie unten deklariert ist, aber nicht, wenn er wie im Kommentar deklariert ist?

XSD:

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

<xs:element name="root">
  <xs:complexType>
    <xs:sequence>
      <xs:element name="A" type="r:AType" 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:BType"/>
    </xs:sequence>
  </xs:complexType>

  <!-- This works. -->
  <xs:key name="pNumKey">
    <xs:selector xpath="r:B/r:part"/>
    <xs:field xpath="@key-number"/>
  </xs:key>
  <!--
  This doesn't work.

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

<xs:complexType name="AType">
  <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="BType">
  <xs:sequence>
    <xs:element name="part" maxOccurs="unbounded">
      <xs:complexType>
        <xs:attribute name="key-number" type="xs:integer"/>
      </xs:complexType>
    </xs:element>
  </xs:sequence>
</xs:complexType>
</xs:schema>

Zahlungscode:

    private static void ValidateXml(string root, string xsdFileName, string xmlFileName)
    {
        ValidationEventHandler veh = new ValidationEventHandler(Program_ValidationEventHandler);
        XmlSchema schema = XmlSchema.Read(new XmlTextReader(root + xsdFileName), veh);

        XmlDocument xdoc = new XmlDocument();
        XmlReaderSettings settings = new XmlReaderSettings();
        settings.Schemas.Add(schema);

        settings.ValidationType = ValidationType.Schema;

        settings.ValidationEventHandler +=
            new ValidationEventHandler(Program_ValidationEventHandler);

        XmlReader reader = XmlReader.Create(root + xmlFileName, settings);

        xdoc.Load(reader);

        Console.WriteLine(xdoc.SchemaInfo.Validity);
    }

    private static void Program_ValidationEventHandler(object sender, ValidationEventArgs e)
    {
        Console.WriteLine(string.Format("-Message:{0}", e.Message));
    }

Antworten auf die Frage(1)

Ihre Antwort auf die Frage