2013-06-20 2 views
1

xml 메시지를 받고 다른 형식으로 변환 한 다음 보내십시오. 메시지의 범위는 약 40 줄에서 600 줄 이상의 xml까지이며 평균 약 100 줄입니다. 초당 여러 개의 메시지를받을 수 있지만 무거운 시간은 평균 15-20 분 정도 걸립니다.일반 XML에서 개체로 매핑

xml은 기존 응용 프로그램에 대한 새로운 정보를 제공하므로 출력 XML의 구조를 모방 한 클래스를 만들었습니다. 객체는 변경된 항목 만 포함하여 출력 XML을 생성하며, 입력 용어를 소비 응용 프로그램이 이해할 수있는 언어로 변환합니다. 알아내는 데 어려움이있는 것은 들어오는 xml을 개체에 쉽게 매핑하는 방법입니다.

들어오는 XML은 각 노드의 형식을 결정하는 몇 가지 템플릿을 사용합니다. 나는 노드가 n이라면 객체 m으로 갈 필요가 있는지를 결정할 수있는 맵을 생성하려고한다. 아래는 내가하려는 일의 단순화 된 예입니다.

메시지 1

<Incoming> 
    <Name>Bob</Name> 
    <City>Seattle</City> 
    <Hobby>Fishing</Hobby> 
</Incoming> 

메시지 2

<Incoming> 
    <Name>Bob</Name> 
    <Employment> 
     <JobTitle>Sales</JobTitle> 
     <Manager>Jessica</Manager> 
    </Employment> 
    <Hobby>Reading</Hobby> 
</Incoming> 

이이 유사한 개체로 갈 것입니다 : 사람이 아이디어가 않습니다, 긴 스위치 케이스를 생성하지 않고

public Customer 
{ 
    public String Name{get; set;} 
    public Address CustomerAddress{get;set;} 
    public Employer CustomerEmployer{get;set;} 
    public List<String> Hobbies{get;set;} 
} 

public Address 
{ 
    public String StreetAddress{get;set;} 
    public String City{get;set;} 
    public String State{get;set;} 
    public String Zip{get;set;} 
} 

public Employer 
{ 
    public String Company{get;set;} 
    public String Position{get;set;} 
    public String Manager{get;set;} 
    public Address CompanyAddress{get;set;} 
} 

정보를 xml에서 객체로 가져 오는 가장 좋은 방법은 무엇입니까? 정보의 양 때문에, 나는 처리를위한 시간 비용을 조금 더 의식하고있다.

매핑을 생각해 보았습니다.

<Name>Customer:Name</Name> 
<City>Customer:Address:City</City> 

그러나 취미와 같이 목록에있는 항목을 매핑하는 방법에 대한 문제가 있습니다. 매핑을 빠르게 소비하는 방법에 대한 문제도 있습니다. 내가 생각할 수있는 유일한 방법은 각 객체가지도의 한 부분을 처리하여 경로를 결정하는 것입니다.하지만 이것은 비싸다고 들립니다.

서로 다른 레벨의 중복 주소가 너무 걱정되지 않습니다. 이 데이터는 한 예입니다. 내 실제 XML에서, 나는 중복이 있다고 생각하지 않는다.

나는 사람들에게 도움이나 아이디어를 제공해 주셔서 감사합니다. 미리 감사드립니다.

+0

내장 된 XML 직렬화가 작동하지 않는 이유가 있습니까? System.Xml.Serialization에서 MSDN을 참조하십시오. http://msdn.microsoft.com/en-us/library/system.xml.serialization.aspx –

+0

XML에 대한 XSD가 있습니까? 그렇다면 System.Xml.Serialization과 함께 XSD를 @MarcL로 사용하십시오. 제안했다. XSD를 사용하면 필수 필드가 아닌 필수 필드 등을 지정할 수 있습니다. 오브젝트에는 지정된 필드가 채워지고 다른 필드는 널 (NULL)이됩니다.직렬화 할 항목과 개체를 전달할 때 지정하지 않는 항목에 대한 사용자 지정 규칙을 적용 할 수도 있습니다. – Anton

+0

답변 해 주셔서 감사합니다. 개체에서 나가는 xml로 serialize하지 않는 이유는 소비하는 개체에서 처리하는 것을 저장하기 위해 변경된 값 (또는 개체) 만 포함한다는 것입니다. 들어오는 xml에서 serialize에 관해서는, 나는 변환 클래스를 generic으로 유지하려고 시도하기 때문에 임의의 명명 규칙을 사용하여 모든 형식의 XML을 사용할 수 있습니다. 이것이 내가 변환기가 소비 할 XML의 각 응용 프로그램에 매핑 XML을 사용하는 것이 좋은 방법이라고 생각한 이유입니다. 그것은 내가 예상했던 것보다 조금 더 까다 롭다는 것을 증명하는 것일뿐입니다. – Tim

답변

2

맵을 사용하여 속성에 액세스하기 위해 리플렉션과 재귀를 사용할 수있었습니다. 다음과 같이지도 경로를 설정했습니다.

map = new Dictionary<string, string>(); 
map.Add("Name", "Name"); 
map.Add("Street", "Address.Address"); 
map.Add("City", "Address.City"); 
map.Add("State", "Address.State"); 
map.Add("Zip", "Address.Zip"); 
map.Add("Activity", "*Hobbies.Hobby"); 
map.Add("Years", "*Hobbies.Years"); 

별표는 이것이 목록이고 키가 필요하다는 것을 나타냅니다. 처리 할 때 키를 추가하기 때문에 내가 보내는 전체 경로는 하이킹이 핵심 인 "* 하이킹. 취미. 예"와 같습니다. 이를 처리하는 방법은 다음과 같습니다.

private void SetValue(object source, String path, String value) 
{ 
    if (path.Contains('.')) 
    { 
     // If this is not the ending Property, continue recursing 
     int index = path.IndexOf('.'); 
     String property = path.Substring(0, index); 

     object nextSource; 
     if(property.Contains("*")) 
     { 
      path = path.Substring(index + 1); 
      index = path.IndexOf('.'); 
      String dictionaryName = path.Substring(0, index); 
      property = property.Substring(1); 

      IDictionary list = source.GetType().GetProperty(dictionaryName).GetValue(source, null) as IDictionary; 
      if (!list.Contains(property)) 
      { 
       Type[] arguments = list.GetType().GetGenericArguments(); 
       list.Add(property, Activator.CreateInstance(arguments[1])); 
      } 

      nextSource = list[property];      
     } 
     else 
      nextSource = source.GetType().GetProperty(property).GetValue(source, null); 

     SetValue(nextSource, path.Substring(index + 1), value); 
    } 
    else 
    { 
     PropertyInfo pi = source.GetType().GetProperty(path); 
     pi.SetValue(source, Convert.ChangeType(value, pi.PropertyType), null); 
    } 
} 

이 정보가 도움이되기를 바랍니다.

관련 문제