2012-01-04 23 views
11

मैं एक ऑब्जेक्ट को क्रमबद्ध करने की कोशिश कर रहा हूं & इसे एक एसक्यूएल सर्वर 2008 एक्सएमएल फ़ील्ड में सेव करें। मेरे पास कुछ deserialization कोड भी है जो ऑब्जेक्ट को फिर से हाइड्रेट करता है। मैं & को क्रमशः डीबी में सहेजने में सक्षम हूं, लेकिन "रूट तत्व अनुपलब्ध" अपवाद प्राप्त करें।सी # एक्सएमएल सीरियलाइजेशन और Deserialization

[XmlRoot("Patient")] 
public class PatientXml 
{ 
    private AddressXml _address = null; 
    private EmergencyContactXml _emergencyContact = null; 
    private PersonalXml _personal = null; 

    [XmlElement] 
    public PersonalXml Personal 
    { 
     get { return _personal; } 
     set { _personal = value; } 
    } 

    [XmlElement] 
    public AddressXml Address 
    { 
     get { return _address; } 
     set { _address = value; } 
    } 

    [XmlElement] 
    public EmergencyContactXml EmergencyContact 
    { 
     get { return _emergencyContact; } 
     set { _emergencyContact = value; } 
    } 

    public PatientXml(){} 
    public PatientXml(Patient patient) 
    { 
     _address = new AddressXml(patient.Address); 
     _emergencyContact = new EmergencyContactXml(patient.EmergencyInfo); 
     _personal = new PersonalXml(patient); 
    } 
} 

public class PersonalXml 
{ 
    private string _firstName = string.Empty, _lastName = string.Empty, _dateOfBirth = string.Empty, _phone = string.Empty; 

    [XmlAttribute] 
    public string FirstName 
    { 
     get { return _firstName; } 
     set { _firstName = value; } 
    } 

    [XmlAttribute] 
    public string LastName 
    { 
     get { return _lastName; } 
     set { _lastName = value; } 
    } 

    [XmlAttribute] 
    public string DateOfBirth 
    { 
     get { return _dateOfBirth; } 
     set { _dateOfBirth = value; } 
    } 

    [XmlAttribute] 
    public string Phone 
    { 
     get { return _phone; } 
     set { _phone = value; } 
    } 

    public PersonalXml(){} 
    public PersonalXml(Patient patient) 
    { 
     _firstName = patient.FirstName; 
     _lastName = patient.LastName; 
     _dateOfBirth = patient.DateOfBirth.ToShortDateString(); 
     _phone = patient.Phone; 
    } 
} 

public class AddressXml 
{ 
    private string _address1 = string.Empty, _address2 = string.Empty, _city = string.Empty, _state = string.Empty, _zip = string.Empty; 

    [XmlAttribute] 
    public string Address1 
    { 
     get { return _address1; } 
     set { _address1 = value; } 
    } 

    [XmlAttribute] 
    public string Address2 
    { 
     get { return _address2; } 
     set { _address2 = value; } 
    } 

    [XmlAttribute] 
    public string City 
    { 
     get { return _city; } 
     set { _city = value; } 
    } 

    [XmlAttribute] 
    public string State 
    { 
     get { return _state; } 
     set { _state = value; } 
    } 

    [XmlAttribute] 
    public string Zip 
    { 
     get { return _zip; } 
     set { _zip = value; } 
    } 

    public AddressXml(){} 
    public AddressXml(Address address) 
    { 
     _address1 = address.Address1; 
     _address2 = address.Address2; 
     _city = address.City; 
     _state = address.State; 
     _zip = address.ZipCode; 
    } 
} 

public class EmergencyContactXml 
{ 
    private string _name = string.Empty, _phone = string.Empty, _relationship = string.Empty; 

    [XmlAttribute] 
    public string Name 
    { 
     get { return _name; } 
     set { _name = value; } 
    } 

    [XmlAttribute] 
    public string Phone 
    { 
     get { return _phone; } 
     set { _phone = value; } 
    } 

    [XmlAttribute] 
    public string Relationship 
    { 
     get { return _relationship; } 
     set { _relationship = value; } 
    } 

    public EmergencyContactXml(){} 
    public EmergencyContactXml(EmergencyContact contact) 
    { 
     _name = contact.ContactName; 
     _phone = contact.Phone; 
     _relationship = contact.Relationship; 
    } 
} 

धारावाहिक XML आउटपुट:

<Patient 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Personal FirstName="Test" LastName="User 1" DateOfBirth="3/13/1966" Phone="6304449866" /> 
    <Address Address1="123 Some St" City="Bartlett" State="CT" Zip="60111" /> 
    <EmergencyContact Name="Dr Chanduwarthana" Phone="6309769484" Relationship="Father" /> 
</Patient> 

Serization & Deserialization कोड:

public static class XmlSerializer 
{ 
    public static string Serialize<T>(T item) 
    { 
     MemoryStream memStream = new MemoryStream(); 
     using (XmlTextWriter textWriter = new XmlTextWriter(memStream, Encoding.Unicode)) 
     { 
      System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(T)); 
      serializer.Serialize(textWriter, item); 

      memStream = textWriter.BaseStream as MemoryStream; 
     } 
     if (memStream != null) 
      return Encoding.Unicode.GetString(memStream.ToArray()); 
     else 
      return null; 
    } 

    public static T Deserialize<T>(string xmlString) 
    { 
     if (string.IsNullOrWhiteSpace(xmlString)) 
      return default(T); 

     using (MemoryStream memStream = new MemoryStream()) 
     { 
      using (XmlTextWriter textWriter = new XmlTextWriter(memStream, Encoding.Unicode)) 
      { 
       memStream.Position = 0; 
       System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(T)); 
       return (T)serializer.Deserialize(memStream); 
      } 
     } 
    } 
} 

उत्तर

11

अपने अक्रमांकन कोड में आप एक MemoryStream और XmlTextWriter बना रहे हैं लेकिन आप इसे स्ट्रिंग deserialize के लिए नहीं दे रहे हैं: d एक वैकल्पिक पैरामीटर है कि कारण होगा इस जोड़े जाने के लिए स्वीकार करने के लिए अपने serialize विधि को संशोधित।

using (MemoryStream memStream = new MemoryStream()) 
{ 
    using (XmlTextWriter textWriter = new XmlTextWriter(memStream, Encoding.Unicode)) 
    { 
     // Omitted 
    } 
} 

आप स्मृति धारा बाइट्स गुजरती हैं और पूरी तरह XmlTextWriter के साथ भाग कर सकते हैं।

using (MemoryStream memStream = new MemoryStream(Encoding.Unicode.GetBytes(xmlString))) 
{ 
    System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(T)); 
    return (T)serializer.Deserialize(memStream); 
} 
+1

यह काम किया !! बस जिज्ञासा ... TextWriter के साथ क्या चल रहा था? – Skadoosh

+2

@ केपी। XmlTextWriter deserialization के लिए आवश्यक नहीं है क्योंकि आप कोई एक्सएमएल नहीं बना रहे हैं। इस मामले में इसे मेमोरीस्ट्रीम के संदर्भ के साथ बनाया गया था और यूनिकोड का उपयोग करने का निर्देश दिया गया था लेकिन इसकी रचना से परे संदर्भित नहीं किया गया था। मैंने यह भी देखा कि धारावाहिक कोड में मेमोरीस्ट्रीम का निपटारा नहीं किया गया है। आपको शायद इसे इस्तेमाल करने वाले ब्लॉक में लपेटने के लिए कोड को संशोधित करने पर विचार करना चाहिए। –

0

मुझे विश्वास है कि आप Xml शीर्ष जोड़ने की जरूरत:

<?xml version="1.0" encoding="utf-8" ?> 

आप coul

public static string Serialize<T>(T item, bool includeHeader = false) 
{ 
    MemoryStream memStream = new MemoryStream(); 
    using (XmlTextWriter textWriter = new XmlTextWriter(memStream, Encoding.Unicode)) 
    { 
     System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(typeof(T)); 
     serializer.Serialize(textWriter, item); 

     memStream = textWriter.BaseStream as MemoryStream; 
    } 
    if (memStream != null) 
     if (includeHeader) 
     { 
      return @"<?xml version=""1.0"" encoding=""utf-8"" ?>" + Environment.NewLine + Encoding.Unicode.GetString(memStream.ToArray()); 
     } 
     else 
     { 
      return Encoding.Unicode.GetString(memStream.ToArray()); 
     } 
    else 
     return null; 
} 
+0

मैं यह कैसे कर सकता हूं? जब मैं ऑब्जेक्ट को क्रमबद्ध करता हूं तो एक्सएमएल कोड उत्पन्न होता था। – Skadoosh

+0

आपको इसे धारावाहिक विधि के आउटपुट में जोड़ने में सक्षम होना चाहिए। –

1

ऐसा लगता है कि एक्सएमएल को serializing पर एक संभाल मिल गया है, तो मेरी सलाह लेते हैं, एक स्ट्रिंग क्षेत्र में एक्सएमएल (varchar, nvarchar, पाठ, ntext) और नहीं एक विशेष क्षेत्र की दुकान।

यदि आप वह छोटा स्विच करते हैं तो आप जाने के लिए तैयार होंगे ... कोई और संशोधन आवश्यक नहीं है।

एक्सएमएल फ़ील्ड मान्यताओं के अधीन है, और कुछ सिरदर्द से अधिक है, और यदि आपका एप्लिकेशन केवल उस क्षेत्र का निर्माता और उपभोक्ता है, तो आप उस शॉर्टकट को भी ले सकते हैं। SQL2008 (यहां तक ​​कि 2005) उन संसाधनों की क्षतिपूर्ति करने के लिए पर्याप्त मजबूत है जो आप xml फ़ील्ड को संकलित करके सहेज सकते हैं।

हाउवर, मैं आपके कोड को थोड़ा सा अनुकूलित कर दूंगा, ऐसा लगता है कि आपने जितना अधिक कोड लिखा था उससे अधिक कोड लिखा था। उदाहरण के लिए, यदि आप अब उदाहरण के लिए, अपनी संपत्ति से डाटा स्टोर करने के लिए एक निजी क्षेत्र बनाने की जरूरत:

public PersonalXml Personal { get ; set ; } 

कुछ और भी है: यदि आप इसे पसंद लिखा

public PersonalXml Personal 
{ 
    get { return _personal; } 
    set { _personal = value; } 
} 

ठीक काम करेंगे वसा आप काट सकता है ...

+0

मैंने सोचा कि SQL सर्वर 2008 में xml फ़ील्ड xml क्वेरी के लिए अधिक अनुकूलित है। या क्या मैं अन्य क्षेत्रों जैसे वर्चर, नवराकर इत्यादि का भी उपयोग कर सकता हूं? – Skadoosh