2016-10-14 1 views
1

XML 문서를 스트리밍하는 코드에서 XElements 대신 강력하게 형식화 된 객체를 반환하고 싶습니다. 말 질문에서 XML 문서는 다음과 같습니다XML 문서를 스트리밍 할 때 XElements 대신 강력하게 형식이 지정된 객체를 반환하는 방법

<?xml version="1.0" encoding="utf-8" ?> 
<People> 
    <Person> 
    <FirstName>John</FirstName> 
    <LastName>Smith</LastName> 
    </Person> 
    <Person> 
    <FirstName>Adam</FirstName> 
    <LastName>Smith</LastName> 
    </Person> 
    <Person> 
    <FirstName>Jane</FirstName> 
    <LastName>Smith</LastName> 
    </Person> 
</People> 

현재, 내 독자 코드는 다음과 같습니다

public class PeopleReader 
{ 
    public static IEnumerable<XElement> StreamPerson(string path) 
    { 
     using (XmlReader rdr = XmlReader.Create(path)) 
     { 
      rdr.MoveToContent(); 

      while (rdr.Read()) 
      { 
       if (rdr.NodeType == XmlNodeType.Element && rdr.Name == "Person") 
       { 
        XElement item = XElement.ReadFrom(rdr) as XElement; 

        if (item != null) 
         yield return item; 
       } 
      }     
     } 
    } 
} 

현재의 호출 코드는 다음과 같습니다 내가 가진

// Current implementation 
foreach (var person in PeopleReader.StreamPerson(@"...\People.xml")) 
{ 
    MessageBox.Show(person.Element("LastName").Value); 
} 

.Element 전화 및 .Value.

내가 코드를 호출하기로하고 싶은 것은 :

// Required implementation where person is returned as a strongly typed obj. 
foreach (var person in PeopleReader.StreamPerson(@"...\People.xml")) 
{ 
    MessageBox.Show(person.LastName); 
} 

나는 내가 .XSD 파일은 다음 파일을 .cs 생성 생성 xsd.exe를 사용할 수 있다는 것을 이해하지만, 내가 분명히에 아니에요 실제 단계. 또한 호출 코드가 열거 형 객체를 받기 위해 생성 된 클래스를 반환하도록 독자 코드를 변경하는 방법을 잘 모르겠습니다. 즉, XElements에서 강력한 형식의 클래스로 이동하는 방법은 무엇입니까? Casting이 옵션으로 보이지 않습니다?

VS2015를 사용하고 있으며 가능하다면 타사 도구를 사용할 필요가 없습니다.

미리 감사드립니다. 이러한 것을 이해 한 -

public static IEnumerable<XElement> StreamPerson(string path) 
{ 
    using (XmlReader rdr = XmlReader.Create(path)) 
    { 
     rdr.MoveToContent(); 

     while (rdr.Read()) 
     { 
      XElement item = XElement.ReadFrom(rdr) as XElement; 
      if (item != null) 
      { 
       yield return new Person 
       { 
        FirstName = item.Element("FirstName")?.Value, 
        LastName = item.Element("LastName")?.Value 
       }; 
      } 
     } 
    } 
} 

업데이트 :

public class Person 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
} 

를 그리고 그것의 새 인스턴스를 반환 대신 Person을 유형을 만들고 반환 IEnumerable<Person>IEnumerable<XElement>를 반환

+0

먼저 강력한 유형이 필요합니다. 직접 작성하거나 실행해야합니까? –

+0

안녕하세요 @HenkHolterman, 손으로 할 수 없습니다. 생성 된 것이 가장 좋습니다. 여기에 간단한 예제 만 사용하여 – Cleve

답변

1

에 의해 제안 된 접근 방식 중 하나를 인스턴스화 할. 클래스는 다음과 같이 정의된다

var serializer = new XmlSerializer(typeof(Person)); 

using (var rdr = XmlReader.Create(path)) 
{ 
    rdr.MoveToContent(); 

    while (rdr.Read()) 
    { 
     if (rdr.NodeType == XmlNodeType.Element && rdr.Name == "Person") 
     { 
      yield return (Person) serializer.Deserialize(rdr); 
     } 
    } 
} 

는 :

public class Person 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
} 

는 작업 데모 this fiddle를 참조하십시오.

XML에 대한 클래스를 생성하려면 xsd.exe (XML 스키마가있는 경우 XML 스키마)을 사용하거나 Edit -> Paste Special -> Paste XML as Classes을 사용하여 XML 샘플을 복사하여 Visual Studio에 붙여 넣을 수 있습니다. this related question을 참조하십시오.

+0

안녕하세요 @Charles Mager, 네, 제 파일은 스트리밍이 필요합니다. 위의 예는 메시지를 전달하기 위해 줄였습니다. – Cleve

+0

업데이트 해 주셔서 감사합니다. 매우 감사. – Cleve

+0

내 VS 2015 Professional에서 편집 -> 선택하여 붙여 넣기 -> 붙여 넣기 XML을 클래스로 찾지 못했습니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까? – Cleve

1

xml은 더 큰 클래스의 "경량"버전을 나타내며, 그 클래스는 내가 제안한 현재 프로젝트를 참조합니다 :

가벼운 속성을 포함하는 더 큰 클래스에 기본 클래스를 만듭니다. 이렇게하면 코드 반복이 없기 때문에 코드 반복이 가능합니다.

public class PersonBase 
{ 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
} 

public class Person : PersonBase 
{ 
    public string OtherProperty { get; set; } 
} 

그런 다음 객체를 사용 내 위의 방법 또는 당신이 XmlSerializer을 사용하는 것이 좋습니다 것 찰스

+0

'item' 변수를 선언하거나 초기화하지 않고'if (item! = null)'을 사용하므로'XElement item = XElement.ReadFrom (rdr) as XElement;가 당신의 발췌 문장에서 누락되었습니다 –

+0

안녕하세요 @ 질라드 그린, 나는 어떤 사람들이 더 복잡해지기 때문에 나는 xsd가 제공 할 수 있다고 생각한 자동화 된 접근법에 기대고있는 사람과 같은 많은 수업을 갖게 될 것입니다. – Cleve

+0

@MartinHonnen - 고마워요. 나머지 코드를 복사 할 때 우연히 제거했습니다. –

관련 문제