1

I'm trying to validate XML nodes or fragments against an XML schema. I have read this article:

Validating xml nodes, not the entire document

but the chosen solution doesn't look like to work for me.

private void ValidateSubnode(XmlNode node, XmlSchema schema)
{
  XmlTextReader reader = new XmlTextReader(node.OuterXml, XmlNodeType.Element, null);

  XmlReaderSettings settings = new XmlReaderSettings();
  settings.ConformanceLevel = ConformanceLevel.Fragment;
  settings.Schemas.Add(schema);
  settings.ValidationType = ValidationType.Schema;
  settings.ValidationEventHandler += new ValidationEventHandler(XSDValidationEventHandler);

  XmlReader validationReader = XmlReader.Create(reader, settings);

  while (validationReader.Read())
  {
  }
}

private void XSDValidationEventHandler(object sender, ValidationEventArgs args)
{
  errors.AppendFormat("XSD - Severity {0} - {1}", 
                  args.Severity.ToString(), args.Message);
}

wich is, as far as I can see, the code for validate a full document, but with "ConformanceLevel.Fragment"

Thus, for example, having a schema as simple as this:

<xsd:schema xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
<xsd:element name="Customer">
  <xsd:complexType>
    <xsd:sequence>
      <xsd:element name="Address">
        <xsd:complexType>
          <xsd:sequence>
            <xsd:element name="Line1" type="xsd:string" />
            <xsd:element name="Line2" type="xsd:string" />
          </xsd:sequence>
       </xsd:complexType>
      </xsd:element>
    </xsd:sequence>
  </xsd:complexType>
</xsd:element>
</xsd:schema>

A 'root' node validates OK

<Customer>
  <Address>
    <Line1>Foo</Line1>
    <Line2>Foo2</Line2>
  </Address>
</Customer>

But any inner node doesn't validate

  <Address>
    <Line1>Foo</Line1>
    <Line2>Foo2</Line2>
  </Address>

I receive the error: "'Address' element is not declared"

Is there something I am missing?

Community
  • 1
  • 1
Kaikus
  • 1,001
  • 4
  • 14
  • 26
  • 2
    FYI, you should not use `new XmlTextReader()` or `new XmlTextWriter()`. They have been deprecated since .NET 2.0. Use `XmlReader.Create()` or `XmlWriter.Create()` instead. – John Saunders Oct 07 '13 at 18:37

2 Answers2

0

Your schema does not allow stand-alone Address elements, and so when you pass only that the validation fails.

Modify your schema like this:

<xsd:schema xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
  <xsd:element name="Address">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="Line1" type="xsd:string" />
        <xsd:element name="Line2" type="xsd:string" />
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
  <xsd:element name="Customer">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element ref="Address"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

Validation of fragments of XML with a XSD does not really work: the same element can be valid or not - or have different valid structures - depending on where it is in a document that matches the XSD, so validating a stand-alone element is not (in general) possible.

MiMo
  • 11,793
  • 1
  • 33
  • 48
  • So, do I have to change the XSD to partially validate nodes? There is no other solution?. This was just an example, but the original schema is quite more complicated, with a single root element. http://www.iso20022.org/message_archive.page?#PaymentsInitiation3 This XSD is intended to validate only full documents, but I wanted to develop a tool to create XML compilant documents using TDD, so I wanted to be able to individually test every element as I develop... :( – Kaikus Oct 07 '13 at 19:20
  • 1
    You have to change the XSD...there is no general solution, see my expanded answer. – MiMo Oct 07 '13 at 20:11
0

Following the recomendation of MiMo, to solve the problem I modify IN RUNTIME the schema. I load it in memory and change it there. I posted my solution here:

Validate XML nodes against a schema using accesory XSD files

Community
  • 1
  • 1
Kaikus
  • 1,001
  • 4
  • 14
  • 26