2009-10-01 3 views
1
을하는 클래스를 만드는 방법

나는 다음과 같은 XML 형식이 :XML로 시리얼

<FavouriteSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Customer> 
    <ID>12</ID> 
    <ID>2</ID> 
    <ID>5</ID> 
    </Customer> 

    <Supplier> 
    <ID>158</ID> 
    <ID>23</ID> 
    <ID>598</ID> 
    </Supplier> 
</FavouriteSettings> 

을 ========================= ====================================
나는 아래

class FavouriteList 
{ 
    public string Name; // this name will be "Customer" and "Supplier" 
    public List<int> aList; // to store those "ID" value 
} 

Class FavouriteSettings 
{ 
    public List<FavouriteList> bigList; 
} 
같은 클래스가됩니다

이 클래스를 XMLSerializer와 함께 사용하여 해당 형식과 같은 XML 파일을 생성하고 목록 및 클래스를 FavouriteList로 역 직렬화하도록하려면 어떻게해야합니까?

+0

(기존 유형의 LINQ-XML을 보여주는 두 번째 예) –

답변

0

XMLSerializer (일반)는 자체 일을하는 것처럼 좋으며 결과는 종종 추한 것입니다. IXmlSerializable을 구현하여 직렬화를 반 제어 할 수 있지만, 거기에 "List"와 같은 것이 있으면 .NET이이를 직렬화합니다.

나는 DataContractXmlSerializer를 사용하여 그 결과를 정확히 얻을 수 있다고 생각한다. 클래스에 [DataContract]로 태그를 지정하고 직렬화하려는 각 요소 위에 [DataMember]를 넣습니다.

+0

DataContractXmlSerializer? 그런 짐승이 있습니까? DataContractSerializer, otoh는 특정 XML에 적합하지 않습니다. 예를 들어, 속성과 같은 것을 거의 제어하지 못합니다. xml의 ​​경우'XmlSerializer'를 사용하거나'XDocument' 등으로 직접 작성하십시오. –

+0

감사하지만 XmlSerializer를 사용해야합니다. –

2

당신은 XmlSerializer를 직렬화하는과 함께 다음과 같은 클래스를 사용할 수 있습니다 /에 역 직렬화/원하는 XML에서 :

public class FavouriteSettings 
    { 
    public ID[] Customer 
    { 
     get; 
     set; 
    } 

    public ID[] Supplier 
    { 
     get; 
     set; 
    } 
    } 

    public class ID 
    { 
    [XmlText()] 
    public int Value 
    { 
     get; 
     set; 
    } 
    } 
+0

위대한 !! 이것을 지적하기 위해 ... 나는 그것에 대해 생각하지 않았습니다 ... –

3

XmlSerializer은 XML로 오브젝트의 매우 직접 번역 할 수 있도록 설계되어있다; 너 수 있습니다IXmlSerializable을 사용하지만, 거의 가치가있다. xml 구조를 미러링하는 객체를 만드는 것이 좋습니다. 또는, 간단한 - 사용 XSD는 당신을 위해 그것을 할 수 있습니다 :

xsd example.xml 
xsd example.xsd /classes 

또는 내가을 의심 일하는 것이 다음 (검증되지 않은) : 특히

using System.Collections.Generic; 
using System.Xml.Serialization; 
public class FavoriteSettings 
{ 
    [XmlArray("Customer")] 
    [XmlArrayItem("ID")] 
    public List<int> Customers { get; set; } 

    [XmlArray("Supplier")] 
    [XmlArrayItem("ID")] 
    public List<int> Suppliers { get; set; } 
} 

; 요소의 이름 ("고객"등)이 데이터 ("이름"등)에 따라 다를 경우 IXmlSerializable을 사용하거나 직접 XDocument (또는 이와 유사한 것)으로 쓰지 않는 한 hapopen하지 않습니다. 이와 같은 간단한 데이터의 경우 XDocument을 사용할 수 있습니까? 하지만 특히 비 직렬화 중에는 많은 추가 작업을해야합니다.


여기를 통해 기존 클래스를 사용하는 예입니다 LINQ - 투 - XML ​​:

static class Program 
{ 
    static void Main() { 
     var favs = new FavouriteSettings 
     { 
      bigList = new List<FavouriteList> 
      { 
       new FavouriteList { 
        Name = "Customer", 
        aList = new List<int>{ 
         12,2,5 
        } 
       }, new FavouriteList { 
        Name = "Supplier", 
        aList = new List<int>{ 
         158, 23, 598 
        } 
       } 
      } 
     }; 
     var el = new XElement("FavoriteSettings", 
      from fav in favs.bigList 
      select new XElement(fav.Name, 
       from item in fav.aList 
       select new XElement("ID", item))); 

     string xml = el.ToString(); 
     Console.WriteLine(xml); 

     el = XElement.Parse(xml); 
     favs = new FavouriteSettings 
     { 
      bigList = new List<FavouriteList>(
       from outer in el.Elements() 
       select new FavouriteList 
       { 
        Name = outer.Name.LocalName, 
        aList = new List<int>(
         from id in outer.Elements("ID") 
         select (int)id 
        ) 
       }) 
     }; 
    } 
} 
+0

실제로 XmlSerializer를 해킹하는 것이 가능합니다. XmlSerializer만을 사용할 수있는 공용 멤버를 추가하려는 경우 - 내 대답을 참조하십시오. 그래도 여전히 추한 것입니다. –

+0

훌륭한 예제와 전체 코드도 ... 감사합니다 MG –

1

당신은 같이 클래스 정의의 모든 기존 이름을 유지하고, 대한 클래스 계층 구조를 도입해야하는 경우 고객 및 공급 업체가 궁금한 점이 있다면 다음과 같은 해킹이 필요합니다.

public class FavouriteList 
{ 
    [XmlIgnore] 
    public string Name; // this name will be "Customer" and "Supplier" 

    [XmlElement("ID")] 
    public List<int> aList; // to store those "ID" value 
} 

public class FavouriteSettings 
{ 
    [XmlIgnore] 
    public List<FavouriteList> bigList; 

    [XmlElement("Customer")] 
    public FavouriteList[] Customers 
    { 
     get { return bigList.Where(fl => fl.Name == "Customer").ToArray(); } 
     set { bigList.AddRange(value); } 
    } 

    [XmlElement("Supplier")] 
    public FavouriteList[] Suppliers 
    { 
     get { return bigList.Where(fl => fl.Name == "Supplier").ToArray(); } 
     set { bigList.AddRange(value); } 
    } 
} 
+0

댓글 : 나는 그것이 "고객"/ "공급자"가 고정되어 있는지 아니면 동적인지, 즉 데이터를 기반으로하는지에 달려 있다고 생각합니다. –

+0

"유형"목록이 컴파일 타임에 고정되어 있는지 또는 런타임에 확장 가능합니까? –

+0

나는 매일 새로운 것들을 배운다 고 생각한다 ... 나는 단지 새로운 Linq이다. 감사합니다. PM –