재우니의 블로그

 

c# ExpandoObject 함수와 XElement 비교하기

 

ExpandoObject 함수를 사용해 보자

 

이 함수가 없기 전까진 아래와 같이 xml 클래스를 사용해야 했죠.

 

XElement contactXML =
   
new XElement(“Contact”,
       
new XElement(“Name”, “Patrick Hines”),
       
new XElement(“Phone”, “206-555-0144″),
       
new XElement(“Address”,
           
new XElement(“Street1″, “123 Main St”),
           
new XElement(“City”, “Mercer Island”),
           
new XElement(“State”, “WA”),
           
new XElement(“Postal”, “68042”)
        )
    );

 

 

구현한 코드에서 특정 node 의 값을 가져오기 위해 아래와 같이 구현합니다.

 

Console.WriteLine((string)contactXML.Element(“Address”).Element(“State”));

 

======================================================

 

 

ExpandoObject 함수를 통해 구현하면 가독성 있게 구현이 가능합니다.

 

dynamic contact = new ExpandoObject();

contact.Name =
“Patrick Hines”;

contact.Phone = “206-555-0144″;

contact.Address =
new ExpandoObject();

contact.Address.Street =
“123 Main St”;
contact.Address.City =
“Mercer Island”;
contact.Address.State =
“WA”;
contact.Address.Postal =
“68402”;

 

 

특정 node 값을 가져오는 방법도 심플하죠?

 

Console.WriteLine(contact.Address.State);

 

 

좀 더 복잡한 구조로 볼까요?

 

 

XElement contactsXML =

    new XElement(“Contacts”,
        new XElement(“Contact”,
            new XElement(“Name”, “Patrick Hines”),
            new XElement(“Phone”, “206-555-0144″)
        ),
        new XElement(“Contact”,
            new XElement(“Name”, “Ellen Adams”),
            new XElement(“Phone”, “206-555-0155″)
        )
    );

 

 

//Name 노드값들을 출력하는 방법

foreach (var c in contactsXML.Descendants(“Name”)) {
    Console.WriteLine((string)c);

}

 

//조건 특정 노드 가져오기

var phonesXML = from c in contactsXML.Elements(“Contact”)
                where c.Element(“Name”).Value == “Patrick Hines”
               
select c.Element(“Phone”).Value;

 

 

//노드값을 제거하기

contactsXML.Elements(“Contact”).Elements(“Phone”).Remove();

 

 

이를 ExpandoObject() 로 변환해 보죠.

 

 

dynamic contacts = new List<dynamic>(); 

contacts.Add(new ExpandoObject());

contacts[0].Name = “Patrick Hines”;
contacts[0].Phone = “206-555-0144″;

contacts.Add(new ExpandoObject());


contacts[1].Name = “Ellen Adams”;
contacts[1].Phone = “206-555-0155″;

 

 

//배열로 지정하여 쉽게 Name 노드값을 얻을 수 있죠.

foreach (var c in contacts) {
    Console.WriteLine(c.Name);

}

 

 

linq 구문으로도 조건을 설정하여 가져올 수 있습니다.

 

var phones = from c in (contacts as List<dynamic>)
             where c.Name == “Patrick Hines”
            
select c.Phone;

 

 

특정 노드 제거할때 IDictionary 로 삭제 처리 합니다.

 

foreach (var person in contacts) {
    ((IDictionary<String, Object>)person).Remove(“Phone”);

}

 

 

아래 함수는 ExpandoObject 함수를 xml 구조로 변환시켜 주는 convert 입니다.

 

 

private static XElement expandoToXML(dynamic node, String nodeName)
{
    XElement xmlNode = new XElement(nodeName);

    foreach (var property in (IDictionary<String, Object>)node)
    {

 

        if (property.Value.GetType() == typeof(ExpandoObject))
            xmlNode.Add(expandoToXML(property.Value, property.Key));

        else
            if
(property.Value.GetType() == typeof(List<dynamic>))
                foreach (var element in (List<dynamic>)property.Value)
                    xmlNode.Add(expandoToXML(element, property.Key));
            else
               
xmlNode.Add(new XElement(property.Key, property.Value));
    }

    return xmlNode;
}