2012-02-09 9 views
1

4つのフィールド(DateTime、Enum、string、string)を持つクラスがあります。私はそれをXML要素または一連のXML要素との間でコンパクトに直列化したいと考えています。例えば、私はこのような何かにそれをシリアライズかもしれません:「i」は各クラスのインスタンスである「t」はDateTimeのティックであるコンパクトXMLをシリアライズ

<i t='234233' a='3'><u>Username1</u><s1>This is a string</s1></i> 
<i t='234233' a='4'><u>Username2</u><s1>This is a string</s1></i> 
<i t='223411' a='1'><u>Username3</u><s1>This is a string</s1></i> 

、「」列挙型の値であり、要素は文字列です。

私はルート要素を持っていない方がいいですが、もし私がそれを持っていれば、できるだけ小さくしたいと思います。

XmlWriterSettingsクラスでXmlSerializerを使用しようとしましたが、名前空間とルート要素を削除できません。

これを行う最善の方法は何ですか?私はファイルに保存していません、私はメモリ内の文字列を読み書きしています。

+1

XMLは整形式にルート要素が必要です。したがって、ほとんどのツールは1つを生成しません。 –

+1

これらのオブジェクトをどのような目的でシリアライズしていますか?それは私たちがあなたを助けるのに役立ちます。 – Zenexer

+0

使用している.NETのバージョンは何ですか? DataContractSerializerを使用すると、コンパクトなバイナリ形式のXMLにシリアル化できます。 –

答えて

1

でハットXMLデータは簡単、あなたが直接XmlWriterを使用できることである場合:このプログラムを実行する

class Data { 
    public DateTime Date { get; set; } 
    public int Code { get; set; } 
    public string First { get; set; } 
    public string Last { get; set; } 
} 

static void Main() { 
    var sb = new StringBuilder(); 
    var xws = new XmlWriterSettings(); 
    xws.OmitXmlDeclaration = true; 
    xws.Indent = false; 
    var elements = new[] { 
     new Data { Date = DateTime.Now, First = "Hello", Last = "World", Code = 2} 
    , new Data { Date = DateTime.UtcNow, First = "Quick", Last = "Brown", Code = 4} 
    }; 
    using (var xw = XmlWriter.Create(sb, xws)) { 
     xw.WriteStartElement("root"); 
     foreach (var d in elements) { 
      xw.WriteStartElement("i"); 
      xw.WriteAttributeString("t", ""+d.Date); 
      xw.WriteAttributeString("a", "" + d.Code); 
      xw.WriteElementString("u", d.First); 
      xw.WriteElementString("s1", d.Last); 
      xw.WriteEndElement(); 
     } 
     xw.WriteEndElement(); 
    } 
    Console.WriteLine(sb.ToString()); 
} 

は、次の出力を生成し(私は明確にするために改行を追加しました。彼らは出力にない)です:あなたが戻って情報を読みたい場合は

<root> 
<i t="2/9/2012 3:16:56 PM" a="2"><u>Hello</u><s1>World</s1></i> 
<i t="2/9/2012 8:16:56 PM" a="4"><u>Quick</u><s1>Brown</s1></i> 
</root> 

あなたはそのルート要素が必要です。最も便宜的な方法は、LINQ2XMLを使用します。

var xdoc = XDocument.Load(new StringReader(xml)); 
var back = xdoc.Element("root").Elements("i").Select(
    e => new Data { 
     Date = DateTime.Parse(e.Attribute("t").Value) 
    , Code = int.Parse(e.Attribute("a").Value) 
    , First = e.Element("u").Value 
    , Last = e.Element("s1").Value 
    } 
).ToList(); 
+0

それは私のためのコンパクトな文字列を書くのは良い仕事です。私はXmlReader.Createを同様の方法でクラスに読み込むことを前提としていますか? –

+0

@Moozhe LINQ2XMLを使用してそれを読み取る方法の例を追加しました。 – dasblinkenlight

+0

実際にLinqを使用していないのは、.NET 2.0です。私はXmlReaderを動作させ、空またはガベージ文字列のエラーをチェックすることに取り組んでいます。 –

0

私はちょうどStringBuilderを個人的に使用します。

サイズが#1の場合は、XMLの代わりにjsonまたはyamlとしてください。

+0

私の主な関心事は、情報を読み取る最良の方法です。 StringReader? XmlReader? XmlNodeList?実装は本当の問題です。 –

+0

'StringBuilder'を使ってXMLを作成しますか? –

+0

一般的に?いいえ。ルートなしで何かを書くには(つまり、無効なXML)?多分。 –

0

独自のシリアライザを実装する必要がありますが、これは苦痛になると思います。つまり、シリアライズ後に必要としないものを手動で取り除くことができます。これはうまくいく可能性があります。

サイズが問題になる場合は、BinaryFormatterを使用してバイナリにシリアル化する必要があります。文字列として格納する必要がある場合は、常にbase-64でエンコードできます。 (出力はきれいにフォーマットXMLのではなく、生のバイナリである以外BinaryFormatterは、ちょうどXmlSerializerのようにほとんど機能します。)

2

System.Xml.Linq

XElement xElem = new XElement("r"); 
for (int i = 0; i < 3; i++) 
{ 
    xElem.Add(
     new XElement("i", 
       new XAttribute("t", "234233"), 
       new XAttribute("a", "3"), 
       new XElement("u", "UserName"), 
       new XElement("s1", "This is a string") 
     ) 
    ); 
} 
var str = xElem.ToString(); 

と読むこと

XElement xElem2 = XElement.Load(new StringReader(str)); 
foreach(var item in xElem2.Descendants("i")) 
{ 
    Console.WriteLine(item.Attribute("t").Value + " " + item.Element("u").Value); 
} 

PS:

xElemを文字列に変換する必要はありません。メモリ

関連する問題