views:

523

answers:

1

This is probably a naive question about XmlReader, but I haven't turned up an answer in the MSDN docs.

Suppose that I have XSD SchemaTest.xsd

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"&gt;
  <xs:element name="pageSettings">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="width" type="xs:decimal" default="8.5" minOccurs="0"/>
        <xs:element name="height" type="xs:decimal" default="11" minOccurs="0"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

well-formed XML document SchemaTest.xml conforming to this schema

<?xml version="1.0" encoding="utf-8" ?>
<pageSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="SchemaTest.xsd">
  <width/>
  <height>11</height>
</pageSettings>

and that I try to read this document with an XmlReader as follows.

static void Main(string[] args) {
    decimal width;
    decimal height;

    XmlReaderSettings settings = new XmlReaderSettings();
    settings.IgnoreWhitespace = true;
    settings.Schemas.Add(null, "C:\\Projects\\SchemaTest\\SchemaTest\\SchemaTest.xsd");
    using (XmlReader reader = XmlReader.Create("C:\\Projects\\SchemaTest\\SchemaTest\\SchemaTest.xml", settings)) {
        reader.ReadStartElement();
        if (reader.Name == "width") {
            width = reader.ReadElementContentAsDecimal("width", "");
            // if fail, width = default from schema
        }
        if (reader.Name == "height") {
            height = reader.ReadElementContentAsDecimal("height", "");
            // if fail, height = default from schema
        }
        reader.ReadEndElement();
    }
}

Currently I am receiving a System.FormatException indicating that the content on the element width is not in the correct format. It appears that reader is trying to read the content in the element and is not defaulting to the default value specified in the schema. What is the correct way to handle this?

Further, it is my understanding that for elements, the schema only provides a default value if an element appears with empty content but that it does not provide a default value if the element is missing. Does this imply that there is no way to obtain a default value for optional elements that are missing?

+1  A: 

As for working with empty elements, set settings.ValidationType = ValidationType.Schema and you should get the default value as desired.

Regarding missing elements, those are considered, well, missing ;-) and thus do not have a default value. Theoretically, you could parse the schema (e.g. using the Schema Object Model) to get the default value. But that would be against the spec.

Have you considered using attributes, like <pageSettings height="55"/>? In that scenario, you should get the default values for missing attributes.

Sven Künzler
settings.ValidationType = ValidationType.Schema did the trick. Thank you.
Jason