ما هي أفضل طريقة لتسلسل XML إلى الكائنات الملائمة عند تعيين إصدار من النطاقات؟

StackOverflow https://stackoverflow.com/questions/209502

سؤال

وسؤالي هو ما يلي.

ولدي XML التي تم تعيين إصدار من مساحة اسم. أريد أن تسلسل هذه تلقى أكس في الكائن المناسب، ولكن الطريقة الوحيدة التي أعرف أن تفعل هذا يعني لدي لمعالجة أكس مرتين. أول من اكتشف مساحة الاسم، ومن ثم من أجل تسلسل إلى كائن من النوع المناسب على أساس مساحة اكتشافها. هذا يبدو غير فعال بشكل مخيف بالنسبة لي، ويجب أن يكون هناك طريقة باستخدام الأدوية أو أي شيء للحصول على النوع المناسب من الكائن مرة أخرى دون وجود "إذا مساحة == س ثم serialze إلى أن" الاختيار.

وفيما يلي عينة من الطريقة الوحيدة التي يمكنني معرفته لتحقيق ذلك. هل هناك طريقة أفضل أو أكثر كفاءة؟

والشكر

using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Xml.Linq;
using System.Xml;
using System.Xml.Serialization;
using System.IO;

namespace TestProject1
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod3()
        {
            //Build up an employee object to xml
            Schema.v2.Employee employee = new Schema.v2.Employee { FirstName = "First", LastName = "Last" };
            string xml = employee.ObjectToXml<Schema.v2.Employee>();

            //Now pretend I don't know what type I am receiving.
            string nameSpace = GetNamespace(xml);
            Object newemp;
            if (nameSpace == "Employee.v2")
                newemp = XmlSerializationExtension.XmlToObject<Schema.v2.Employee>(null, xml);
            else
                newemp = XmlSerializationExtension.XmlToObject<Schema.v1.Employee>(null, xml);

            // Check to make sure that the type I got was what I made.
            Assert.AreEqual(typeof(Schema.v2.Employee), newemp.GetType());
        }

        public string GetNamespace(string s)
        {
            XDocument z = XDocument.Parse(s);
            var result = z.Root.Attributes().
                    Where(a => a.IsNamespaceDeclaration).
                    GroupBy(a => a.Name.Namespace == XNamespace.None ? String.Empty : a.Name.LocalName,
                            a => XNamespace.Get(a.Value)).
                    ToDictionary(g => g.Key,
                                 g => g.First());

            foreach (System.Xml.Linq.XNamespace item in result.Values)
                if (item.NamespaceName.Contains("Employee")) return item.NamespaceName;

            return String.Empty;
        }
    }

    public static class XmlSerializationExtension
    {
        public static string ObjectToXml<T>(this T Object)
        {
            XmlSerializer s = new XmlSerializer(Object.GetType());
            using (StringWriter writer = new StringWriter())
            {
                s.Serialize(writer, Object);
                return writer.ToString();
            }
        }
        public static T XmlToObject<T>(this T Object, string xml)
        {
            XmlSerializer s = new XmlSerializer(typeof(T));
            using (StringReader reader = new StringReader(xml))
            {
                object obj = s.Deserialize(reader);
                return (T)obj;
            }
        }
    } 
}

namespace Schema.v1
{
    [XmlRoot(ElementName = "Employee", Namespace= "Employee.v1", IsNullable = false)]
    public class Employee
    {
        [XmlElement(ElementName = "FirstName")]
        public string FirstName { get; set; }
        [XmlElement(ElementName = "LastName")]
        public string LastName { get; set; }
    }
}
namespace Schema.v2
{
    [XmlRoot(ElementName = "Employee", Namespace = "Employee.v2", IsNullable = false)]
    public class Employee
    {
        [XmlAttribute(AttributeName = "FirstName")]
        public string FirstName { get; set; }
        [XmlAttribute(AttributeName = "LastName")]
        public string LastName { get; set; }
    }
}
هل كانت مفيدة؟

المحلول

واقتراحين:

أولا، ربما لا تفعل ذلك على الإطلاق. إذا كنت تسلسل، ويفضل أسلوب واحد على الآخر ما لم يحدد المتصل مخطط.

وثانيا، لا تحليل XML لاكتشاف. مجرد القيام مطابقة السلسلة على "Employee.v2" و "Employee.v1" خلال (مثلا) 100 بايت الأولى من الملف (أو لكن الآن عليك أن تذهب للحصول على المعلومات). يجب أن تعمل، ما لم تكن تلك ستكون سلاسل المشتركة في البيانات الخاصة بك.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top