Pergunta

Eu tenho um arquivo XML que está sendo carregado em uma página do ASP.NET através do controle normal de upload do arquivo. Quando se levanta, estou tentando validar e desserializar o XML. No entanto, o código abaixo é realmente muito útil para validar um arquivo XML que faz referência ao XSD como este:

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

No entanto, se eu enviar esse arquivo XML, apenas o arquivo XML será carregado, então .. Localschemapath.xsd não existe, para que não possa validar.

Mesmo se eu armazenasse o XSD localmente, ainda não estaria certo, pois o arquivo XML poderia ser escrito com um local de esquema como:

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

ou xsi: schemalocation = "Someurl LocalsChemapath.xsd" ou xsi: schemalocation = "Someurl .................. Localschemapath.xsd" se assim o desejava.

Dilema!

(Para os propósitos desta pergunta, eu belisquei o código abaixo de: Validando um XML contra o XSD referenciado em 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);
    }
}
Foi útil?

Solução

Aqui está um pedaço de código que eu uso para validar XML com um esquema local:

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

Outras dicas

Não consigo entender se você está tentando um schema genérico de validate-contra-referenciado, ou se você tem um esquema específico contra o qual você valida todas as vezes e não sabe ao certo como lidar com as referências.

Se for o último, faça o esquema público na Internet e diga às pessoas para fazer referência a Uri.

Se for o primeiro, então eu sugeriria o seguinte:

  • Primeiro, o usuário carrega um arquivo XML.
  • Analise o arquivo XML para uma referência de esquema. Diga a eles "referências a yourSchema.xsd foram achados; Faça o upload deste arquivo abaixo "com uma nova caixa de upload.
  • Em seguida, valide o arquivo em relação ao esquema carregado. Para fazer isso, modifique o Schemas propriedade do seu settings objeto, em vez de modificar o ValidationFlags propriedade.
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top