获取schemaLocation以确定要加载哪个xsd以及返回哪种类型的正确方法?

时间:2013-10-08 18:01:39

标签: c# xml reflection xsd versioning

我正在学习如何做好"正确的"使用版本控制的未知(但已知)xml验证

我得到了它,但我不喜欢我这样做,我的问题是;我在这里走的是正确的道路吗?

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web;
using System.Xml;
using System.Xml.Schema;

namespace BLL.XML
{
    public class ValidateXML
    {
        //list of valid xsd files and the corresponding class
        private static List<KeyValuePair<string, string>> SchemaType;

        static ValidateXML()
        {
            SchemaType = new List<KeyValuePair<string, string>>();
            SchemaType.Add(new KeyValuePair<string, string>("sample.0.6.2.xsd", "BO.contentExchangeType, BO, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"));
            SchemaType.Add(new KeyValuePair<string, string>("sample.0.6.1.xsd", "BO.contentExchangeType11231321312, BO, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"));
        }

        //valid xml
        private bool valid;
        //list of errors found while validating
        private List<string> errors;
        //list of warnings found while validating
        private List<string> warnings;

        private ValidateXML()
        {
            errors = new List<string>();
            warnings = new List<string>();

            valid = true; //by default, the xml is valid
        }

        public static KeyValuePair<bool, List<string>> Validate(string xml, out Type XmlType)
        {
            var validate = new ValidateXML();
            string xsd = "";

            try
            {
                using (TextReader sr = new StringReader(xml))
                using (XmlReader xmlReader = XmlReader.Create(sr))
                {
                    if (xmlReader.MoveToContent() == XmlNodeType.Element)
                    {
                        //should look like this
                        //xsi:schemaLocation="http://sample.com/sample/contentExchange sample.0.6.2.xsd "
                        var schemaLocation = xmlReader.GetAttribute("xsi:schemaLocation");
                        if (!string.IsNullOrWhiteSpace(schemaLocation))
                        {
                            var part = schemaLocation.Split();
                            if (part.GetUpperBound(0) >= 1)
                            {
                                //get the actual xsd file name for validation
                                xsd = part[1];
                            }
                        }
                    }
                }

                //xsd found in the predefined list?
                if (SchemaType.Any(x => x.Key == xsd))
                {
                    var xsdFile = HttpContext.Current.Server.MapPath("~/bin/xsd/" + xsd);
                    if(File.Exists(xsdFile))
                    {
                        //prepare the return type
                        XmlType = Type.GetType(SchemaType.First(x => x.Key == xsd).Value);

                        //validate the xml based on the proper xsd
                        return validate.VerifyXmlFile(xml, xsdFile);
                    }
                    else
                    {
                        throw new Exception("Cannot find the file " + xsd );
                    }
                }
                else
                {
                    throw new Exception("Cannot find matching xsd value");
                }
            }
            catch (Exception ex)
            {
                validate.errors.Add("Exception.Message: " + ex.Message);
                XmlType = null;
                return new KeyValuePair<bool, List<string>>(false, validate.errors);
            }

        }

        private KeyValuePair<bool, List<string>> VerifyXmlFile(string xml, string PathXsd)
        {
            try
            {
                using (TextReader sr = new StringReader(xml))
                using (XmlReader xsd = XmlReader.Create(PathXsd))
                {
                    // configure the xmlreader validation to use inline schema.
                    XmlReaderSettings config = new XmlReaderSettings();
                    config.ValidationType = ValidationType.Schema;
                    config.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
                    config.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
                    config.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
                    config.ValidationFlags |= XmlSchemaValidationFlags.ProcessIdentityConstraints;
                    config.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);
                    config.Schemas.Add(null, xsd);

                    // Get the XmlReader object with the configured settings.
                    using (XmlReader reader = XmlReader.Create(sr, config))
                    {
                        // Parsing the file will cause the validation to occur.
                        while (reader.Read()) ;

                        return new KeyValuePair<bool, List<string>>(valid, errors);
                    }
                }
            }
            catch(Exception ex)
            {
                errors.Add("Exception.Message: " + ex.Message);
                return new KeyValuePair<bool, List<string>>(false, errors);
            }
        }

        private void ValidationCallBack(object sender, ValidationEventArgs vea)
        {
            if (vea.Severity == XmlSeverityType.Error)
            {
                valid = false;
                errors.Add("ValidationCallBack: " + vea.Message);
            }
            else if (vea.Severity == XmlSeverityType.Warning)
            {
                warnings.Add("ValidationCallBack: " + vea.Message);
            }
        }
    }
}

一样使用
var ValidXml = BLL.XML.ValidateXML.Validate(text, out XmlType);

if (ValidXml.Key)
{
    if (XmlType == typeof(contentExchangeType))
    {
        ProcessContentExchangeType062(text);
    }
    else if (XmlType == typeof(contentExchangeType11231321312))
    { 
        ProcessContentExchangeType061(text);             
    }
}

0 个答案:

没有答案