Проверка XmlDocument с помощью XSD - PullRequest
4 голосов
/ 22 июля 2010

Я занимаюсь разработкой системы, которая будет получать XML (XmlDocument) через веб-сервис. У меня не будет этого XML (XmlDocument) на жестком диске. Будет управляться по памяти.

У меня есть файл XSD для проверки XML (XmlDocument), который я получаю от моего WebService. Я пытаюсь сделать пример, как проверить этот XML.

Мой XML:

<?xml version="1.0"?>
<note>
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
</note>

также у меня есть XSD:

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.w3schools.com"
xmlns="http://www.w3schools.com"
elementFormDefault="qualified">
  <xs:element name="note">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="to" type="xs:string"/>
        <xs:element name="from" type="xs:string"/>
        <xs:element name="heading" type="xs:string"/>
        <xs:element name="body" type="xs:int"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Как мы видим, поле body , которое я поставил как int , просто для имитации ошибки.

Ну, чтобы попытаться получить ошибку, у меня есть следующий код:

//event handler to manage the errors
private static void verifyErrors(object sender, ValidationEventArgs args)
{
    if (args.Severity == XmlSeverityType.Warning)
        MessageBox.Show(args.Message);
}

По нажатию кнопки у меня есть:

        private void button1_Click(object sender, EventArgs e)
        {

            try
            {
                // my XmlDocument (in this case I will load from hardisk)
                XmlDocument xml = new XmlDocument();
                // load the XSD schema.. is this right?
                xml.Schemas.Add("http://www.w3schools.com", "meuEsquema.xsd");

                // Load my XML from hardisk
                xml.Load("meusDados.xml");

                // event handler to manage the errors from XmlDocument object
                ValidationEventHandler veh = new ValidationEventHandler(verificaErros);

                // try to validate my XML.. and the event handler verifyError will show the error
                xml.Validate(veh);
            }
            catch {
              // do nothing.. just to test
            }
        }

Проблема в том, что я изменил поле body на int , но в этом поле есть строковое значение, и я не получаю ошибку.

Ответы [ 2 ]

6 голосов
/ 22 июля 2010

Проблема в пространствах имен XML.

В вашем XSD вы определяете targetNamespace= и xmlns= для обоих: "http://www.w3schools.com":

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

Однако - ваш документ XML не содержит какие-либо пространства имен XML.

<?xml version="1.0"?>
<note>
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
</note>

По сути, XSD вообще не проверяет этот XML .

Вам нужночтобы удалить эти пространства имен из вашего XSD:

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

или, альтернативно, добавьте пространство имен XML по умолчанию (без префикса), определенное в вашем XSD, к вашему XML:

<?xml version="1.0"?>
<note xmlns="http://www.w3schools.com">
  <to>Tove</to>
  <from>Jani</from>
  <heading>Reminder</heading>
  <body>Don't forget me this weekend!</body>
</note>

Если выУ вас есть пространства имен XML в вашем XSD, они также должны присутствовать в XML - и наоборот.

Как только вы выполните одно или другое решение, вы должны получить ошибку проверки, например:

Validation error: The 'body' element is invalid - The value 'Don't forget me this weekend!' is invalid according to its datatype
'http://www.w3.org/2001/XMLSchema:int' - The string 'Don't forget me this weekend!' is not a valid Int32 value.
0 голосов
/ 22 июля 2010

Я надеюсь, что смогу помочь вам здесь. У меня была похожая проблема (с ложными срабатываниями Xml).

Я обнаружил две ошибки в моей конкретной ситуации, одна из которых действительно может иметь значение. Вы должны подписаться на различные проверки XML через XmlReaderSettings. Вот простое использование (взято из поста выше)

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"); }); 

// obviously you don't need to read Xml from file, 
// just skip the load bit and supply raw DOM object
XmlReader reader = XmlReader.Create (xmlFileName, settings); 
while (reader.Read ()) { } 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...