2010-01-06 7 views
1

클래스 CarResource, 클래스 RaceCarResource : public CarResource, 및 클래스 SuperDuperUltraRaceCarResource : public RaceCarResource 클래스가 있다고 가정합니다.C# : 파생 클래스에 대한 XML 구성 수동 읽기

하나의 LoadFromXML 메서드를 사용하여 데이터를로드하려고합니다.

CarResource : LoadFromXML 데이터를로드하려면 어떻게해야합니까? CarResource : LoadFromXML을 호출하고 자체 데이터를로드하는 등의 RaceCarResource? 내가하여 XmlTextReader를 사용하는 경우

난 단지 한 번에 전체 파일을 구문 분석하는 방법을 알고, 는 그렇게 처음 CarResource를 사용하지 방법 : LoadFromXML이

등의 일이, 다음 RaceCarResource을 할 수있는 나는 그것이에 희망 최소한 내가 무엇을 의미하는지 분명히해라. :)

답변

1
public class CarResource 
{ 
    public virtual void LoadFromXML(String xmlData) 
    { 
     ... 
    } 
} 

public class RaceCarResource : CarResource 
{ 
    public override void LoadFromXML(String xmlData) 
    { 
     base.LoadFromXML(xmlData); 
     ... 
    } 
} 

... 등등. new 키워드는 상속 된 메서드를 숨기지 만 하위 클래스에서 호출 할 수있게합니다.

실제로 XML을 구문 분석 할 때 몇 가지 옵션이 있습니다. 내 첫 번째 제안은 전체 XML 파일을 메모리로 읽어 들이고 LINQ to XML을 사용하여 클래스를 파싱하고 클래스를 채 웁니다. XmlSerializer (LINQ to XML은 구현하기가 더 쉽지만 코드 기반의 크기가 커짐에 따라 Xml Serialization은 유지 관리가 더 쉬워집니다.)를 시도해 볼 수도 있습니다.

+0

하지만 어떻게 행동해야하나요? XML 파일을 읽어서 CarResource가 자신의 데이터만을 파싱하도록하고, RaceCarResource가 자신의 데이터를 자체적으로 파싱하도록하세요? – Pygmy

+0

왜 기본 클래스의 메서드를 가상으로 만들지 않는 것이 좋을까요? 하위 클래스는 필요에 따라 가상 호출을 무시하고 여전히 기본 클래스 구현을 호출 할 수 있습니다. – NotMe

+0

@Chris - 다릅니다. 네가 맞으므로 내 대답을 업데이트했다.이 경우 클래스를 그런 식으로 구성하는 것이 더 합리적이다.하지만이 링크를 확인해 보라 : http://msdn.microsoft.com/en-us/library/6fawty39. aspx –

0

로드 할 XML 파일의 구조에 따라 XML 직렬화를 사용할 수도 있습니다. 특정 정보를로드하거나 단순히 속성을 사용하기 위해로드 메소드를 오버라이드 (또는 후속 클래스에서 오버라이드) 할 수 있습니다. 참조 : http://msdn.microsoft.com/en-us/library/ms950721.aspx

0

몇 가지 옵션이 있습니다.

Linq to XML을 사용하여 하위 엔티티를 쿼리하고 해당 노드를 다른 클래스에 전달할 수 있습니다. 이것은 아마도 가장 효율적인 방법 일 것입니다.

당신은 다시에만 해당 자식 노드를 통과, xmlnavigator를 사용할 수 있습니다 ... 참조 : Implementing my own XPathNavigator in C#

당신은 단순히 XML 직렬화 (XMLSERIALIZE XmlDeserialize)를 사용할 수

, XML을 사용하기 위해서는 C# - How to xml deserialize object itself?

0

참조 비 직렬화의 경우 인스턴스 메소드는 현재 객체를 효과적으로 '불변'으로 만듭니다. 그러나 다음과 같이 제안합니다.

public class CarResource 
{ 
    public CarResource LoadNewFromXML(string xml) 
    { 
     XmlSerializer ser = new XmlSerializer(this.GetType()); 
     object o = null; 
     using (MemoryStream ms = new MemoryStream(Encoding.ASCII.GetBytes(xml))) 
     { 
      o = ser.Deserialize(ms); 
     } 
     return o as CarResource; 
    } 
} 

public class RaceCarResource : CarResource 
{ 
} 

public class SuperRaceCarResource : RaceCarResource 
{ 
} 

호출 코드 당신의 XML은 .NET의 XML 직렬화와 호환되지 않을 경우

RaceCarResource car = new RaceCarResource(); 
car = car.LoadNewFromXML("<RaceCarResource/>") as RaceCarResource; 

SuperRaceCarResource sc = new SuperRaceCarResource(); 
sc = sc.LoadNewFromXML("<SuperRaceCarResource/>") as SuperRaceCarResource; 
0

, 다음 가장 쉬운 방법은 XML을 나타내는 자원의 유형 감지하는 공장을 만드는 것입니다 다음 적절한 것을 처리 : 같은 N 보인다. 당신이 당신의 객체로 구문 분석을 넣고 싶은 경우에, 객체 생성 한 후 내부를 구문 분석하는 가상의 방법을 사용하십시오

class CarResource 
{ 
    public string Color { get; private set; } 

    internal virtual void ReadFrom(XmlReader xml) 
    { 
     this.Color = xml.GetAttribute("colour"); 
    } 
} 

class RaceCarResource : CarResource 
{ 
    public string Sponsor { get; private set; } 

    internal override void ReadFrom(XmlReader xml) 
    { 
     base.ReadFrom(xml); 
     this.Sponsor = xml.GetAttribute("name-on-adverts"); 
    } 
} 

class SuperDuperUltraRaceCarResource : RaceCarResource 
{ 
    public string Super { get; private set; } 

    internal override void ReadFrom(XmlReader xml) 
    { 
     base.ReadFrom(xml); 
     this.Super = xml.GetAttribute("soup"); 
    } 
} 

class CarResourceFactory 
{ 
    public CarResource Read(XmlReader xml) 
    { 
     CarResource car; 

     switch (xml.LocalName) 
     { 
      case "ordinary-car": car = new CarResource(); break; 
      case "racecar": car = new RaceCarResource(); break; 
      case "super_duper": car = new SuperDuperUltraRaceCarResource(); break; 
      default: throw new XmlException(); 
     } 

     XmlReader sub = xml.ReadSubtree(); 

     car.ReadFrom(sub); 

     sub.Close(); 

     return car; 
    } 
} 

이 확인 작업을 하위 유형에 대한 XML 엄격 후 추가 된 자식 요소가있는 경우 또는 수퍼 유형에 대한 내용 앞에그렇지 않으면 수퍼 타입의 직렬화를 재사용하여 더 작은 메소드로 분해해야합니다 (예 :베이스에 바퀴, 문, 엔진 크기의 수를로드하는 메소드가 있으며, 레이스 카는 LoadDoorData, LoadAeroFoilData, LoadWheelData을 호출합니다) 경주 용 XML은 문과 바퀴 데이터 사이에 aerofoil 데이터를 가지고 있습니다. 논리적 순서가 부과되지 않은 형식 (XMI, RDF)의 경우 로컬 이름을 검사하여 어떤 특수한 메서드를 호출해야 할지를 결정해야합니다. 이 경우에는 별도의 직렬화 도우미를 사용하는 것이 좋습니다.

생성 될 집합이 몇 가지 유형으로 고정되어 있지 않으면 다른 메커니즘을 사용할 수 있습니다.

관련 문제