Как проверить файл кода XML хотя .NET? + Как бы я это сделал, если бы я использовал сериализацию XML? - PullRequest
3 голосов
/ 21 января 2010

Я хочу, чтобы пользователи могли экспортировать данные в виде файла XML. Конечно, я хочу, чтобы они потом могли импортировать тот же XML-файл, однако они всегда могли изменить его или это мог быть другой XML-файл.

Итак, я хочу проверить XML-файл, чтобы убедиться, что он в ожидаемом формате. Поэтому я думаю, что мне понадобится что-то вроде схемы, чтобы проверить, что это должно быть через код.

Так что, если я ожидаю

<Root>
 <Something>
    <SomethingElse> </SomethingElse>
 </Something>
</Root>

Я не хочу, чтобы в файле был какой-то другой формат, отличный от того, который я ожидал.

Кроме того, как бы я проверил поля? Например, я говорю, что между тегами должен быть какой-то текст. Если поле пустое, файл недействителен.

Так, как я мог сделать это?

Редактировать

Я решил использовать сериализацию XML, так что я знаю, что она будет проходить через исключение, если это неправильный формат, и игнорировать вещи, которые не работают. Однако я не уверен, должен ли я просто пройти через это и на C #, чтобы проверить каждую из записей, или я должен попытаться создать схему XML для этого.

Если бы я хотел сделать это с помощью XML-схемы с сериализацией XML, как бы это работало? Как я сначала делаю что-то, как я видел в ответах, а затем сериализую? Или как бы я это сделал?

Ответы [ 5 ]

10 голосов
/ 21 января 2010

Вот фрагмент кода, который вы можете использовать для этого:

using (FileStream stream = File.OpenRead(xsdFilepath))
{
    XmlReaderSettings settings = new XmlReaderSettings();

    XmlSchema schema = XmlSchema.Read(stream, OnXsdSyntaxError);
    settings.ValidationType = ValidationType.Schema;
    settings.Schemas.Add(schema);
    settings.ValidationEventHandler += OnXmlSyntaxError;

    using (XmlReader validator = XmlReader.Create(xmlPath, settings))
    {
        // Validate the entire xml file
        while (validator.Read()) ;
    }
}

Функция OnXmlSyntaxError будет вызываться при возникновении синтаксической ошибки.

9 голосов
/ 21 января 2010

Существует несколько способов проверки файлов XML. Ознакомьтесь с Как проверить документ XML с помощью DTD, XDR или XSD в Visual C # .NET

Также см. Проверка XML на XSD со ссылкой в ​​C # пример

Другим хорошим примером является Проверка XML на XSD с использованием кода во время выполнения в C #

Вот код из последнего поста:

public void ValidateXmlDocument(
    XmlReader documentToValidate, string schemaPath)
{
    XmlSchema schema;
    using (var schemaReader = XmlReader.Create(schemaPath))
    {
        schema = XmlSchema.Read(schemaReader, ValidationEventHandler);
    }

    var schemas = new XmlSchemaSet();
    schemas.Add(schema);

    var settings = new XmlReaderSettings();
    settings.ValidationType = ValidationType.Schema;
    settings.Schemas = schemas;
    settings.ValidationFlags =
        XmlSchemaValidationFlags.ProcessIdentityConstraints |
        XmlSchemaValidationFlags.ReportValidationWarnings;
    settings.ValidationEventHandler += ValidationEventHandler;

    using (var validationReader = XmlReader.Create(documentToValidate, 
           settings))
    {
        while (validationReader.Read()) { }
    }
}

private static void ValidationEventHandler(
    object sender, ValidationEventArgs args)
{
    if (args.Severity == XmlSeverityType.Error)
    {
        throw args.Exception;
    }
    Debug.WriteLine(args.Message);
}
2 голосов
/ 28 января 2010

Вы можете использовать LINQ to XML: http://msdn.microsoft.com/en-us/library/bb387037.aspx. На этой странице также показано, как сделать это вместе с источником для вывода любых недопустимых узлов: http://blogs.msdn.com/xmlteam/archive/2007/03/03/the-new-linq-to-xml-bridge-classes-to-system-xml.aspx

0 голосов
/ 29 января 2010

Вы можете использовать сериализацию xml в своих классах:

[XmlType("Root", Namespace = "http://example.com/Root")]
[XmlRoot(Namespace = "http://example.com/Root.xsd", ElementName = "Root", IsNullable = false)]
public class Root {
  [XmlElement("Something")] 
  public Something Something { get; set; }
}

public class Something {
  [XmlElement("SomethingElse")]
  public SomethingElse SomethingElse { get; set; }
}

public class SomethingElse {
  [XmlText]
  public string Text { get; set; }
}

Сериализуйте это так:

var serializer = new XmlSerializer(typeof(Root));
serializer.Serialize(outputStrem, myRoot);

Затем можно выполнить тестирование перед десериализацией, например ::10000

var serializer = new XmlSerializer(typeof(Root));
string xml = @"
  <Root xmlns='http://example.com/Root'>
    <Something>
      <SomethingElse>Yep!</SomethingElse>
    </Something>
  </Root>"; // remember to use the XML namespace!
Debug.Assert(serializer.CanDeserialize(new XmlTextReader(new StringReader(xml))));

А потом просто десериализовать:

Root newRoot = (Root)serializer.Deserialize(inputStream);

Ваш XSD неявный. Это соответствует вашим классам. Чтобы использовать более богатые XSD, вы можете обратиться к Поставщикам схем .

0 голосов
/ 21 января 2010
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...