我想請XmlSerializer.Deserialize
通過它XDocument
。它可以採取Stream
,XmlReader
或TextReader
。使用XDocument作爲XmlSerializer.Deserialize的源代碼?
我可以在沒有將XDocument
實際轉儲到某個中間商店(如MemoryStream
)的情況下生成XDocument
中的上述一個嗎?
看來,我所追求的是XmlReader
的實施,它與XDocument
一起使用。我找不到一個。
我想請XmlSerializer.Deserialize
通過它XDocument
。它可以採取Stream
,XmlReader
或TextReader
。使用XDocument作爲XmlSerializer.Deserialize的源代碼?
我可以在沒有將XDocument
實際轉儲到某個中間商店(如MemoryStream
)的情況下生成XDocument
中的上述一個嗎?
看來,我所追求的是XmlReader
的實施,它與XDocument
一起使用。我找不到一個。
您可以使用XDocument.CreateReader()
創建一個讀取XDocument
的內容的XmlReader
。
等效地,下面也會起作用。
XmlReader GetReader(XDocument doc)
{
return doc.Root.CreateReader();
}
只是想我要補充一點,在創建的XmlReader後,即:
XmlSerializer serializer = new XmlSerializer(typeof(MyObject));
XmlReader reader = xmlDocumentToDeserialize.CreateReader();
那麼你應該叫:
reader.MoveToContent();
,否則讀者會不會 「點」第一個節點,導致空讀者的外觀!然後你可以安全地調用Deserialize:
MyObject myObject = (MyObject)serializer.Deserialize(reader);
這裏有一個實用程序來序列化和反序列化XDocument的對象。
XDocument doc = SerializationUtil.Serialize(foo);
Foo foo = SerializationUtil.Deserialize<Foo>(doc);
這裏的類:
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;
}
}
(附錄史蒂夫·圭迪的答案)
至於我可以看到有沒有XmlReader
實現,你可以輕鬆地與XDocument
使用,而無需移動通過中間商店的XML內容,如XML和的字符串表示,支持所有類型,例如System.Xml.XmlNodeReader
支持的所有類型。
由XDocument.CreateReader
返回(這是一個System.Xml.Linq.XNodeReader
,一個內部類)的讀者是一個XmlReader
並適用於大多數的XML文檔,但不能與具有二進制數據元素的文檔,因爲它的實現does not support Base64 or BinHex data:
Base64和BinHex數據不受支持。如果您嘗試檢索 這些類型的數據(例如,通過調用 ReadElementContentAsBase64),讀者將拋出 NotSupportedException。
對於此讀者XDocument.CreateReader().CanReadBinaryContent
是false
與System.Xml.XmlNodeReader
相反。
例如該程序會拋出異常:
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)
}
}
}
然而,提取XML作爲string
,並把它當作TextReader
串行化器的工作原理:
using (var reader = new StringReader(document.ToString()))
我會感興趣,以及如果還有另一種方法來反序列化包含二進制數據的XDocument
,而不先將其轉換爲字符串。
看,我希望能找到這個決議。我有一些xml內容與二進制數據,這將使一切慢得多。一輪跳到一個字符串似乎瘋了。我想我可能會嘗試和談判放棄字節[]內容,而不是採取性能命中。 – Jim 2016-03-03 12:31:30
我喜歡@Simon_Weaver的回答最好。基於這是我的總結:
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
}
}
也http://stackoverflow.com/q/7901558/11912 – 2013-01-05 15:00:50