XMLReader obter elemento padrão de esquema
Pergunta
Esta é provavelmente uma pergunta ingênua sobre XmlReader
, mas eu não ter aparecido uma resposta nos docs MSDN.
Suponha que eu tenho XSD SchemaTest.xsd
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<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>
bem formado XML
documento SchemaTest.xml
em conformidade com esse esquema
<?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>
e que eu tento ler este documento com um XmlReader
como segue.
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();
}
}
Atualmente eu estou recebendo um System.FormatException
indicando que o conteúdo no elemento width
não está no formato correto. Parece que reader
está tentando ler o conteúdo do elemento e não está inadimplente com o valor padrão especificado no esquema. O que é a maneira correta de lidar com isso?
Além disso, é meu entendimento que para os elementos, o esquema só fornece um valor padrão se um elemento aparece com conteúdo vazio, mas que não fornece um valor padrão se o elemento está faltando. Isto implica que não há nenhuma maneira de obter um valor padrão para elementos opcionais que estão faltando?
Solução
Quanto a trabalhar com os elementos vazios, conjunto settings.ValidationType = ValidationType.Schema
e você deve obter o valor padrão conforme desejado.
Quanto elementos em falta, aqueles são considerados, bem, faltando ;-) e, portanto, não tem um valor padrão. Teoricamente, você pode analisar o esquema (por exemplo, usando o modelo de objeto de esquema) para obter o valor padrão. Mas isso seria contra o spec.
Você considerou usando atributos, como <pageSettings height="55"/>
? Nesse cenário, você deve obter os valores padrão para atributos faltando.