2013-04-10 120 views
0

首先警告,我是一個完整的反序列化n00b。也就是說,我從消息隊列中的另一個系統接收到一些XML。我無法控制XML。反序列化一般XML

XML封裝了消息,它包含一個頭和一個有效載荷。頭文件包含消息類型,所以我需要首先解析出頭文件,然後解析出消息內容,並且希望使用相同的XmlReader進行此操作。 (我不知道XmlReader流是否記得它的位置,或者如果Reader關閉了流並且我需要重新打開它,但這應該是可以實現的,是的?)

我遇到的第一個問題是如何告訴我想要的元素名稱的頭部類是裏面。創建一個消息類是有問題的,因爲在反序列化頭之前,我不知道它是什麼類型的消息。看看這個XML:

<SCHED_MSG> 
    <HEADER> 
     <SOURCE_IDENT_TEXT>MES.PRIM_SCHED</SOURCE_IDENT_TEXT> 
     <GEN_EST>2011-12-21T14:01:48.876-05:00</GEN_EST> 
     <ISL_MSG_IDENT_TEXT>REL_SCHED_PID_MHS</ISL_MSG_IDENT_TEXT> 
    </HEADER> 
</SCHED_MSG> 

如果我標記XmlRootElement將的ElementName =「頭」,我得到一個異常,因爲這不是XML的根。 (有沒有辦法告訴它根是「SCHED_MSG.HEADER」?)如果我使用SCHED_MSG作爲頭,我似乎無法到達GEN_EST元素。 (同樣,是否有某種方法可以告訴dot Net XmlElementAttribute(ElementName =「HEADER.GEN_EST」)?)

注意:我已經從這個消息中刪除了消息,但它會在標籤之後和標籤之前。我從隊列中接收消息爲char *,它用於初始化System :: String,然後使用該字符串創建StringReader,並將StringReader提供給XmlReader.Create()。 XmlReader依次傳遞給使用此類的類型的XmlSerializer構造函數:

[Serializable] 
//[XmlRootAttribute(ElementName = "SCHED_MHS_MSG")] 
[XmlRootAttribute(ElementName = "SCHED_MHS_MSG.DOFASCO_HEADER")] 
public ref class DofascoHeader 
{ 
public: 
    [XmlElementAttribute(ElementName = "GEN_EST")] 
    System::DateTime GenerationTime; 

    //[XmlElementAttribute(ElementName = "ISL_MSG_IDENT_TEXT")] 
    //String ^MessageName; 
}; 

任何見解?

回答

0

那麼,如果其他人正在嘗試這樣做,這裏至少有一個選項可行。

XmlReader^messageData = XmlReader::Create(mqTestStream); 
try 
{ 
    while (messageData->Read()) 
    { 
     if (
      (messageData->NodeType == XmlNodeType::Element) 
      && 
      (messageData->Name == "HEADER") 
      ) 
     { 

      System::Xml::Serialization::XmlSerializer ^HeadParser = gcnew System::Xml::Serialization::XmlSerializer(Header::typeid); 

      Header ^MyHead; 
      MyHead = dynamic_cast<Header^>(HeadParser->Deserialize(messageData)); 
      break; 
     } 
    } 
} 
catch(XmlException ^e) 
{ 
    Console::WriteLine(e->Message); 
}