Вопрос

У меня есть XML-файл, который загружается на страницу ASP.Net с помощью обычного элемента управления загрузкой файлов.Когда он запускается, я пытаюсь проверить и десериализовать XML.Однако приведенный ниже код действительно очень удобен для проверки XML-файла, который ссылается на XSD следующим образом:

xsi:schemaLocation="someurl ..\localSchemaPath.xsd"

Однако, если я загружу этот XML-файл, будет загружен только XML-файл, так что ..\localSchemaPath.xsd не существует, поэтому он не может быть проверен.

Даже если бы я сохранил XSD локально, это все равно было бы не совсем правильно, поскольку XML-файл мог быть записан с таким расположением схемы, как:

xsi:schemaLocation="someurl ..\localSchemaPath.xsd"

или xsi:schemaLocation="someurl localSchemaPath.xsd" или xsi:schemaLocation="someurl ..................\ localSchemaPath.xsd" если он того пожелает.

Дилемма!

(Для целей этого вопроса я вырезал приведенный ниже код из: Проверка XML на соответствие ссылочному XSD в C#)

using System.Xml;
using System.Xml.Schema;
using System.IO;

public class ValidXSD
{
    public static void Main()
    {
        // Set the validation settings.
        XmlReaderSettings settings = new XmlReaderSettings();
        settings.ValidationType = ValidationType.Schema;
        settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
        settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
        settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
        settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);

        // Create the XmlReader object.
        XmlReader reader = XmlReader.Create("inlineSchema.xml", settings);

        // Parse the file. 
        while (reader.Read()) ;
    }

    // Display any warnings or errors.
    private static void ValidationCallBack(object sender, ValidationEventArgs args)
    {
        if (args.Severity == XmlSeverityType.Warning)
            Console.WriteLine("\tWarning: Matching schema not found.  No validation occurred." + args.Message);
        else
            Console.WriteLine("\tValidation error: " + args.Message);
    }
}
Это было полезно?

Решение

Вот фрагмент кода, который я использую для проверки xml с помощью локальной схемы:

string errors = string.Empty;

try
{
    XmlSchemaSet schemas = new XmlSchemaSet();
    schemas.Add(string.Empty, Page.MapPath("~/xml/Schema.xsd"));
    XmlDocument doc = new XmlDocument();
    doc.Schemas = schemas;
    doc.Load(Page.MapPath("~/xml/sampleXML.xml"));
    //use this line instead of the one above for a string in memory.
    //doc.InnerXml = xmlToValidate;  
    ValidationEventHandler validator = delegate(object send, ValidationEventArgs ve)
                                           {
                                               errors += "\n" + ve.Severity + ": " + ve.Message;
                                           };

    doc.Validate(validator);
}
catch (XmlException xe)
{
    errors += "\n" + xe.Message;
}
catch (XmlSchemaValidationException xe)
{
    errors += "\n" + xe.Message;
}

Другие советы

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

Если это последнее, то сделайте схему общедоступной в Интернете и попросите людей ссылаться на нее по URI.

Если это первое, то я бы предложил следующее:

  • Сначала пользователь загружает XML-файл.
  • Проанализируйте XML-файл для получения ссылки на схему.Скажите им: "Ссылки на yourSchema.xsd были найдены;пожалуйста, загрузите этот файл ниже" с новым полем для загрузки.
  • Затем проверьте файл на соответствие загруженной схеме.Чтобы сделать это, измените Schemas собственность вашего settings объект, вместо того чтобы изменять ValidationFlags собственность.
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top