xs: clave, por eso se pasa la validación cuando el valor de clave no es miembro de referencia clave?

StackOverflow https://stackoverflow.com/questions/2861232

  •  30-09-2019
  •  | 
  •  

Pregunta

Estoy interesado en la definición de una restricción de clave en mi Xsd. Es mi entender que el uso de xs:key debe limitar el valor usado para un miembro de una referencia lista de valores.

Si se asume que estamos utilizando la muestra 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 de ejemplo,

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

y, por ejemplo, algunos simples de validación

[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 ()) { }
}

¿cómo es, validación todavía tiene éxito cuando uso malos valores de 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>

es uno cualquiera o todos los Xsd, XML, o validación anterior incorrecto? O tengo no he entendido bien la finalidad prevista del xs:key?

¿Fue útil?

Solución

Como de costumbre, después de una noche de descanso de buena y una nueva mirada, vio a no menos de 2 errores en este ejercicio.

  1. En primer error, la validación de las limitaciones de identidad es un proceso explícito, inducida a través de conjunto XmlSchemaValidationFlags.ProcessIdentityConstraints por XmlReaderSettings.ValidationFlag, y
  2. segundo error, MSDN muestra contiene un error en el esquema, <xs:selector xpath="part"/> debe leer <xs:selector xpath="r:part"/>.

Ejemplo de trabajo completa es la siguiente:

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

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

validador sencilla

[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()) { }
}

Otros consejos

Creo que se debe utilizar ValidationEventHandler:

settings.ValidationEventHandler += new ValidationEventHandler (ValidationCallBack);

private static void ValidationCallBack (object sender, ValidationEventArgs args) {}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top