2010-01-15 10 views
9

निम्नलिखित कोड में, मैं एक ऑब्जेक्ट स्ट्रिंग में एक ऑब्जेक्ट को क्रमबद्ध करता हूं।मुझे इस XML स्ट्रिंग को कैसे बदलना है ताकि XDocument.Parse इसे पढ़ सके?

लेकिन जब मैं XDocument.Parse के साथ एक XDocument में इस XML स्ट्रिंग पढ़ने की कोशिश, यह मेरे इस त्रुटि देता है: रूट स्तर पर

अमान्य डेटा।

एक्सएमएल है:

<?xml version="1.0" encoding="utf-8"?> 
<Customer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Id>1</Id> 
    <FirstName>Jim</FirstName> 
    <LastName>Jones</LastName> 
    <ZipCode>23434</ZipCode> 
</Customer> 

अद्यतन:

alt text http://www.deviantsart.com/upload/hhcvmu.png

क्या मैं इतना है कि यह में पढ़ता है इस XML करने के लिए मुझे क्या करना होगा: यहाँ हेक्स है एक त्रुटि के बिना XDocument?

using System; 
using System.Collections.Generic; 
using System.Xml.Serialization; 
using System.IO; 
using System.Xml; 
using System.Text; 
using System.Xml.Linq; 

namespace TestSerialize2342 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      List<Customer> customers = Customer.GetCustomers(); 

      Console.WriteLine("--- Serializing ------------------"); 

      foreach (var customer in customers) 
      { 
       Console.WriteLine("Serializing " + customer.GetFullName() + "..."); 
       string xml = XmlHelpers.SerializeObject<Customer>(customer); 

       XDocument xdoc = XDocument.Parse(xml); 

      } 

      Console.ReadLine(); 
     } 

    } 

    public static class StringHelpers 
    { 
     public static String UTF8ByteArrayToString(Byte[] characters) 
     { 
      UTF8Encoding encoding = new UTF8Encoding(); 
      String constructedString = encoding.GetString(characters); 
      return (constructedString); 
     } 

     public static Byte[] StringToUTF8ByteArray(String pXmlString) 
     { 
      UTF8Encoding encoding = new UTF8Encoding(); 
      Byte[] byteArray = encoding.GetBytes(pXmlString); 
      return byteArray; 
     } 
    } 

    public static class XmlHelpers 
    { 
     public static string SerializeObject<T>(object o) 
     { 
      MemoryStream ms = new MemoryStream(); 
      XmlSerializer xs = new XmlSerializer(typeof(T)); 
      XmlTextWriter xtw = new XmlTextWriter(ms, Encoding.UTF8); 
      xs.Serialize(xtw, o); 
      ms = (MemoryStream)xtw.BaseStream; 
      return StringHelpers.UTF8ByteArrayToString(ms.ToArray()); 
     } 

     public static T DeserializeObject<T>(string xml) 
     { 
      XmlSerializer xs = new XmlSerializer(typeof(T)); 
      MemoryStream ms = new MemoryStream(StringHelpers.StringToUTF8ByteArray(xml)); 
      XmlTextWriter xtw = new XmlTextWriter(ms, Encoding.UTF8); 
      return (T)xs.Deserialize(ms); 
     } 
    } 

    public class Customer 
    { 
     public int Id { get; set; } 
     public string FirstName { get; set; } 
     public string LastName { get; set; } 
     public string Street { get; set; } 
     public string Location { get; set; } 
     public string ZipCode { get; set; } 

     private int internalValue = 23; 

     public static List<Customer> GetCustomers() 
     { 
      List<Customer> customers = new List<Customer>(); 
      customers.Add(new Customer { Id = 1, FirstName = "Jim", LastName = "Jones", ZipCode = "23434" }); 
      customers.Add(new Customer { Id = 2, FirstName = "Joe", LastName = "Adams", ZipCode = "12312" }); 
      customers.Add(new Customer { Id = 3, FirstName = "Jack", LastName = "Johnson", ZipCode = "23111" }); 
      customers.Add(new Customer { Id = 4, FirstName = "Angie", LastName = "Reckar", ZipCode = "54343" }); 
      customers.Add(new Customer { Id = 5, FirstName = "Henry", LastName = "Anderson", ZipCode = "16623" }); 
      return customers; 
     } 

     public string GetFullName() 
     { 
      return FirstName + " " + LastName + "(" + internalValue + ")"; 
     } 

    } 
} 

उत्तर:

धन्यवाद एनड्रास, GetPreamble(), यह तय तो किसी और को इस से निपटने के लिए, यहाँ बीओएम की अपनी XML साफ करने के लिए एक छोटे से विधि है:

public static string RemoveUtf8ByteOrderMark(string xml) 
{ 
    string byteOrderMarkUtf8 = Encoding.UTF8.GetString(Encoding.UTF8.GetPreamble()); 
    if (xml.StartsWith(byteOrderMarkUtf8)) 
    { 
     xml = xml.Remove(0, byteOrderMarkUtf8.Length); 
    } 
    return xml; 
} 
+0

उस XML के साथ कुछ भी गलत नहीं है। क्या आप वाकई एक ही एक्सएमएल हैं जो अपवाद पैदा कर रहा है? –

+0

रूट स्तर, लाइन 1, वर्ण 1 पर अमान्य डेटा। जब मैं टेक्स्ट को नोटपैड ++ में कॉपी करता हूं, तो पहला अक्षर "?" होता है और अन्य संपादकों में कुछ नियंत्रण चरित्र ... –

+0

फिर आप कट और पेस्ट के दौरान खुले "<" खो गए। एक्सएमएल के साथ कुछ भी गलत नहीं है। –

उत्तर

15

ऐसा इसलिए है क्योंकि डेटा में स्ट्रीम की शुरुआत में यूनिकोड या utf8 BOM marks शामिल है।

आपको स्ट्रीम में किसी भी बाइट ऑर्डर मार्क्स को छोड़ना होगा - आप इन्हें System.Text.Encoding.GetPreamble() विधि से पहचान सकते हैं।

+0

नोटपैड में एक्सएमएल फाइलें बनाते समय आपको अक्सर यह समस्या मिलती है। वीएस उन्हें कभी-कभी भी जोड़ सकता है। –

+0

GetPreamble() का उपयोग कारण के बजाय परिणामों को हल करने का प्रयास है। कृपया मेरा जवाब देखें। – Restuta

+0

हां यह एक अच्छा जवाब है - और यह काम करता है, अगर एन्कोडिंग हमेशा यूटीएफ 8 है। हालांकि, GetPreamble विधि का उपयोग कर आप एक फ़ाइल की एन्कोडिंग ऑटो का पता लगा सकते हैं, जिसका अर्थ है कि आप सिर्फ एक से बंधा नहीं कर रहे हैं। एक बार चुने जाने के बाद आप किसी भी एन्कोडिंग को समायोजित करने के लिए अपना कोड नमूना समायोजित कर सकते हैं। –

1

आप एक StreamReader उपयोग करने के बजाय एक स्ट्रिंग के लिए MemoryStream में डेटा परिवर्तित करने के लिए से आपकी समस्या का समाधान कर सकते हैं:

public static string SerializeObject<T>(object o) 
{ 
    using (MemoryStream ms = new MemoryStream()) 
    { 
     XmlSerializer xs = new XmlSerializer(typeof(T)); 
     using (XmlWriter xtw = XmlWriter.Create(ms)) 
     { 
      xs.Serialize(xtw, o); 
      xtw.Flush(); 
      ms.Seek(0, SeekOrigin.Begin); 
      using (StreamReader reader = new StreamReader(ms)) 
      { 
       return reader.ReadToEnd(); 
      } 
     } 
    } 
} 
+0

-1: 'XmlTextWriter' को बहिष्कृत किया गया है। इसके बजाय 'XmlWriter.Create' का उपयोग करें। –

+0

@ जॉन: संकलक मुद्दों 'XmlTextWriter' बारे में कोई जानकारी बहिष्कृत किया जा रहा। मुझे 'XmlWriter.Create' सिफारिश के बारे में पता है, लेकिन मैं इस मुद्दे को हल करने के लिए आवश्यक से अधिक ओपी कोड को बदलना नहीं चाहता था। फिर भी, सिफारिश का पालन करने के लिए मेरे कोड नमूना अद्यतन किया। –

-1

उपरोक्त सभी सही है, और यहाँ एक कोड है कि आप के बजाय का उपयोग करना चाहिए है छोड़ बीओएम:

public static string SerializeObject<T>(object o) 
     { 
      MemoryStream ms = new MemoryStream(); 
      XmlSerializer xs = new XmlSerializer(typeof(T)); 
      //here is my code 
      UTF8Encoding encoding = new UTF8Encoding(false); 
      XmlTextWriter xtw = new XmlTextWriter(ms, encoding); 
      //XmlTextWriter xtw = new XmlTextWriter(ms, Encoding.UTF8); 
      xs.Serialize(xtw, o); 
      ms = (MemoryStream)xtw.BaseStream; 
      return StringHelpers.UTF8ByteArrayToString(ms.ToArray()); 
     } 

निर्माता में झूठी निर्दिष्ट करके आप कहते हैं कि "बीओएम प्रदान नहीं की है।" का आनंद लें! =)

+0

-1, -1, -1: आप 'चारों ओर' MemoryStream' और 'XmlWriter' डाल करने के लिए using' ब्लॉक की जरूरत है। आपको 'XmlTextWriter' का उपयोग नहीं करना है, जिसे .NET 2.0 के बाद से हटा दिया गया है - इसके बजाय' XmlWriter.Create' का उपयोग करें। 'ओ 'पैरामीटर प्रकार' टी' होना चाहिए; अन्य बातों के अलावा, इस अपने कॉल निर्दिष्ट नहीं करने की अनुमति होगी - यह अक्सर पैरामीटर के प्रकार के अनुसार लगाए गए कर दिया जाएगा। –

+0

सहमत, लेकिन यह केवल एक संशोधन के साथ मूल कोड की एक प्रति है, तो यह उसकी समीक्षा करेंगे और छेद और डिजाइन मुद्दों को खोजने के लिए अपने लक्षित नहीं था। यदि आप इस चर्चा को पढ़ने की कोशिश करेंगे, तो शायद आप देखेंगे कि मैंने जिस समस्या को हल किया है, उसे हल किया है। तो अपने "-1" बाहर ले लो, महोदय। – Restuta

संबंधित मुद्दे

 संबंधित मुद्दे