2012-02-09 2 views
1

4 개의 필드 (DateTime, Enum, string, string)가있는 클래스가 있습니다. 필자는 XML 요소 또는 일련의 XML 요소를 컴팩트하게 직렬화하려고합니다. 예를 들어, 나는 이런 식으로 뭔가에 직렬화 수 있습니다 '내가'각 클래스의 인스턴스가 't'입니다소형 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

정확히 어떤 목적으로이 객체를 직렬화하고 있습니까? 그게 우리가 널 도울 수 있도록 도와 줄거야. – Zenexer

+0

사용중인 .NET 버전은 무엇입니까? DataContractSerializer를 사용하면 XML의 압축 된 이진 형식으로 직렬화 할 수 있습니다. –

답변

1

, 직접 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()); 
} 

다음과 같은 출력을 생성합니다 (I 라인이 명확하게 나누기 추가; 그들은 출력에 하지)입니다 : 당신이 정보를 다시 읽고 싶은 경우

<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

실제로 .NET 2.0 이후 Linq를 사용하지 않습니다. XmlReader를 작동시키고 빈 문자열이나 가비지 문자열을 검사하는 중 오류가 발생합니다. –

0

저는 개인적으로 StringBuilder을 사용합니다.

크기가 1 위인 경우 XML 대신 json 또는을 고려하십시오.

+0

내 관심사는 정보를 다시 읽는 가장 좋은 방법입니다. StringReader? XmlReader? XmlNodeList? 구현이 진정한 질문입니다. –

+0

'StringBuilder'를 사용하여 xml을 구성할까요? –

+0

일반적으로? 루트가 아닌 무언가를 작성하려면 (즉, 유효하지 않은 XML)? 아마. –

0

당신은 자신의 시리얼 라이저를 구현할 필요가 있다고 생각합니다. 즉 직렬화 후에 필요없는 것을 수동으로 제거 할 수 있습니다.

크기가 걱정되면 BinaryFormatter을 사용하여 2 진수로 직렬화해야합니다. 문자열로 저장해야하는 경우 항상 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 :

t를 사용하려면 xElem을 문자열로 변환 할 필요가 없습니다. 데이터가 간단한 경우 메모리에 모자 XML은