0

首先是一个警告,我在反序列化方面是一个完整的 n00b。也就是说,我在消息队列中从另一个系统接收了一些 XML。我无法控制 XML。

XML 封装了消息,它包含一个标头和一个有效负载。标头包含消息类型,所以我需要先解析出标头,然后再解析出消息内容,我希望使用相同的 XmlReader 来执行此操作。(我不知道 XmlReader 流是否记住了它的位置,或者 Reader 是否关闭了流并且我需要重新打开它,但这应该是可以实现的,是吗?)

我遇到的第一个问题是如何告诉 Header Class 我想要的元素名称在里面。创建消息类是有问题的,因为在反序列化标头之前我不会知道它是什么类型的消息。看看这个 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 = "HEADER",则会出现异常,因为这不是 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;
};

有什么见解吗?

4

1 回答 1

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);
}
于 2013-04-10T19:01:52.740 回答