2009-08-18 14 views
28

Bir XDocument ileterek XmlSerializer.Deserialize'u çağırmak istiyorum. Bir Stream, bir XmlReader veya bir TextReader alabilir.XDocument, XmlSerializer.Deserialize için kaynak olarak mı kullanılıyor?

XDocument'dan XDocument'u aslında MemoryStream gibi bir ara depoya dökmeden yukarıdakilerden birini oluşturabilir miyim?

Göründüğüm, bir XDocument ile çalışan bir XmlReader uygulamasıdır. Yine de bir tane bulamıyorum.

+0

asla bunun için bir çözüm bulmak için umuyordum da http://stackoverflow.com/q/7901558/11912 –

cevap

43

XDocument'un içeriğini okuyan bir XmlReader oluşturmak için XDocument.CreateReader()'u kullanabilirsiniz.

Eşdeğerde, aşağıdakiler de çalışacaktır.

XmlSerializer serializer = new XmlSerializer(typeof(MyObject)); 
XmlReader reader = xmlDocumentToDeserialize.CreateReader(); 

o zaman aramalısınız:

XmlReader GetReader(XDocument doc) 
{ 
    return doc.Root.CreateReader(); 
} 
0

Sadece ben XmlReader oluşturulduktan sonra, yani eklemek gerektiğini düşündüm

reader.MoveToContent(); 

çünkü aksi takdirde okuyucu olmaz "nokta" için İlk düğüm, boş bir okuyucunun ortaya çıkmasına neden oluyor! Sonra güvenle deserialize arayabilirsiniz:

MyObject myObject = (MyObject)serializer.Deserialize(reader); 
9

İşte serialize ve XDocument için/nesneleri serisini bir yarar var. İşte

XDocument doc = SerializationUtil.Serialize(foo); 
Foo foo = SerializationUtil.Deserialize<Foo>(doc); 

sınıf var:

public static class SerializationUtil 
{ 
    public static T Deserialize<T>(XDocument doc) 
    { 
     XmlSerializer xmlSerializer = new XmlSerializer(typeof(T)); 

     using (var reader = doc.Root.CreateReader()) 
     { 
      return (T)xmlSerializer.Deserialize(reader); 
     } 
    } 

    public static XDocument Serialize<T>(T value) 
    { 
     XmlSerializer xmlSerializer = new XmlSerializer(typeof(T)); 

     XDocument doc = new XDocument(); 
     using (var writer = doc.CreateWriter()) 
     { 
      xmlSerializer.Serialize(writer, value); 
     } 

     return doc; 
    } 
} 
3

Bildiğim kadarıyla kolayca hareket ettirmeden XDocument ile kullanabileceğiniz XmlReader hiçbir uygulama yoktur gördüğünüz gibi (Steve Guidi cevabı Ek)

XML içeriğinin XML içeriği ve gibi tüm aralıkları destekleyen gibi bir ara depodan, örneğin System.Xml.XmlNodeReader desteklediği.

(a System.Xml.Linq.XNodeReader, bir iç sınıf olan) XDocument.CreateReader tarafından döndürülen okuyucu bir XmlReader ve çoğu XML belge için ancak ikili veri elemanlarına sahip belgeler ile çalıştığı için onun uygulanması does not support Base64 or BinHex data:

Base64 ve BinHex verileri desteklenmiyor. bu tür verileri almayı denerseniz (örneğin, ReadElementContentAsBase64 çağırarak), okuyucu NotSupportedException öğesini atar. Bu okuyucu XDocument.CreateReader().CanReadBinaryContent için

System.Xml.XmlNodeReader aksine false olup.bu program bir istisna atar Örneğin

: string olarak XML ayıklanması ve serileştiriciye TextReader olarak geçen, ancak

public class SomeTest 
{ 
    public byte[] BinaryTest { get; set; } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     XDocument document = new XDocument(
      new XElement("SomeTest", 
       new XElement("BinaryTest", "VGVzdA=="))); 

     using (var reader = document.CreateReader()) 
     { 
      var serializer = new XmlSerializer(typeof(SomeTest)); 
      var someTest = serializer.Deserialize(reader) as SomeTest; 
      // NotSupportedException here (as inner exception) 
     } 
    } 
} 

çalışır:

 using (var reader = new StringReader(document.ToString())) 

Ben de eğer ilgi olacağını İlk önce bir dizeye dönüştürmeden, ikili verileri içeren bir XDocument'u serileştirmenin başka bir yolu vardır.

+0

bakınız. İkili veri içeren bazı xml içeriğim var, bu da her şeyi çok daha yavaş hale getirecek. Bir dize yuvarlak açma, çıldırmış gibi görünüyor. Performans isabetini almak yerine bayt [] içeriğini tamamen bırakmayı deneyebilirim. – Jim

0

@Simon_Weaver'ın en iyi cevabını seviyorum. Bu benim özetidir Buna dayanarak:

using System; 
using System.Xml.Linq; 
using System.Xml.Serialization; 

namespace XDocSerialization 
{ 
    [TestClass] 
    public class Tests 
    { 
     [TestMethod] 
     public void Tests_SerializeToXDoc() 
     { 
      var sheep = new Animal 
      { 
       Name = "Sheep", Legs = 4, Nutrition = Nutrition.Herbivore 
      }; 
      var xdoc = sheep.SerializeToXDoc(); 
      var ser = "<Animal " + 
         "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " + 
         "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\r\n " + 
         "<Name>Sheep</Name>\r\n <Legs>4</Legs>\r\n " + 
         "<Nutrition>Herbivore</Nutrition>\r\n</Animal>"; 

      Assert.AreEqual(xdoc.ToString(), ser); 
      Assert.IsInstanceOfType(xdoc, typeof(XDocument)); 
     } 

     [TestMethod] 
     public void Tests_DeserializeFromXDoc() 
     { 
      var Sheep = new Animal 
      { 
       Name = "Sheep", Legs = 4, Nutrition = Nutrition.Herbivore 
      }; 
      var des = Sheep.SerializeToXDoc().DeserializeFromXDoc<Animal>(); 

      Assert.AreEqual(des.Name, Sheep.Name); 
      Assert.AreEqual(des.Nutrition, Sheep.Nutrition); 
      Assert.AreEqual(des.Legs, Sheep.Legs); 
      Assert.AreNotSame(des, Sheep); 
     } 
    } 

    public static class ExtensionMethods 
    { 
     public static T DeserializeFromXDoc<T>(this XDocument source) 
     { 
      if (source == null || source.Root == null) 
       return default(T); 

      using (var reader = source.Root.CreateReader()) 
       return (T)new XmlSerializer(typeof(T)).Deserialize(reader); 
     } 

     public static XDocument SerializeToXDoc<T>(this T source) 
     { 
      if (source == null) 
       return null; 

      var doc = new XDocument(); 
      using (var writer = doc.CreateWriter()) 
       new XmlSerializer(typeof(T)).Serialize(writer, source); 

      return doc; 
     } 
    } 

    [Serializable] 
    public class Animal 
    { 
     public string Name { get; set; } 
     public int Legs { get; set; } 
     public Nutrition Nutrition { get; set; } 
    } 

    public enum Nutrition 
    { 
     Herbivore, 
     Carnivore, 
     Omnivore 
    } 
} 
İlgili konular