用于具有混合元素的 XML 的 XmlSerializer

问题描述 投票:0回答:2
c# xmlserializer syncml
2个回答
1
投票

你的基本问题是,在两个地方,你继承自

List<T>
。 不推荐这样做(请参阅here进行讨论),此外序列化器也不能很好地支持,例如列表的属性永远不会被序列化。 相反,使用包含列表的类,并用
[XmlElement]
标记这些列表,以指示它们应该在没有外部包装元素的情况下进行序列化。

因此你的模型应该看起来像这样:

[XmlRoot("SyncML", Namespace = "SYNCML:SYNCML1.2")]
public class SyncML
{
    [XmlElement]
    public SyncHdr SyncHdr { get; set; }

    [XmlArray("SyncBody")]
    [XmlArrayItem("Status", Type = typeof(StatusCommand))]
    [XmlArrayItem("Get", Type = typeof(GetCommand))]
    [XmlArrayItem("Final", Type = typeof(FinalCommand))]
    public List<SyncCommandBase> SyncBody { get; set; } = new ();
}

public class SyncHdr
{
    [XmlElement("VerDTD")]
    public string VerDtd { get; set; }

    [XmlElement("VerProto")]
    public string VerProto { get; set; }

    // etc.
}

public abstract class SyncCommandBase
{
}

public abstract class SyncCommand : SyncCommandBase
{
    [XmlElement("CmdID")]
    public int CmdId { get; set; }
}

public class StatusCommand : SyncCommand
{
    [XmlElement("MsgRef")]
    public int MsgRef { get; set; }

    [XmlElement("CmdRef")]
    public int CmdRef { get; set; }
}

public class GetCommand : SyncCommand
{
    [XmlElement(ElementName="Item")]
    public List<Item> Item { get; set; }
}

public class Item
{
    [XmlElement("Target")]
    public Location Target { get; set; }
}

public class Location
{
    [XmlElement("LocURI")]
    public string LocUri { get; set; }
}

public class FinalCommand : SyncCommandBase
{
}

演示小提琴#1 这里

请注意,我将

SyncCommandBase
作为
SyncCommand
的抽象超类插入,并让
FinalCommand
继承自它,因为
<Final/>
元素没有
<CmdID>
子元素。

如果您不想将

<Final/>
元素绑定到
SyncCommand
列表中,您可以按如下方式修改模型,使其成为中间
SyncBody
类中的显式属性:

[XmlRoot("SyncML", Namespace = "SYNCML:SYNCML1.2")]
public class SyncML
{
    [XmlElement]
    public SyncHdr SyncHdr { get; set; } // Unchanged

    [XmlElement("SyncBody")]
    public SyncBody SyncBody { get; set; } = new ();
}

public class SyncBody
{
    [XmlElement("Status", Type = typeof(StatusCommand), Order = 1)]
    [XmlElement("Get", Type = typeof(GetCommand), Order = 1)]
    public List<SyncCommand> SyncCommands { get; set; } = new ();
    
    [XmlElement("Final", Order = 100)] // Force <Final> to come last when re-serializing
    public SyncFinal Final { get; set; }
}

public abstract class SyncCommand
{
    [XmlElement("CmdID")]
    public int CmdId { get; set; }
}

public class StatusCommand : SyncCommand
{
    [XmlElement("MsgRef")]
    public int MsgRef { get; set; }

    [XmlElement("CmdRef")]
    public int CmdRef { get; set; }
}

public class GetCommand : SyncCommand
{
    [XmlElement(ElementName="Item")]
    public List<Item> Item { get; set; }
}

public class Item
{
    [XmlElement("Target")]
    public Location Target { get; set; }
}

public class Location
{
    [XmlElement("LocURI")]
    public string LocUri { get; set; }
}

public class SyncFinal
{
}

演示小提琴 #2 这里


0
投票

@Zenilogix 我正在使用支持 SyncML 的手机,该手机支持使用 OBEX 串行(USB)与 Outlook 进行联系人同步。但我想从中获取联系人而不将其同步到 Outlook,否则我需要在同步到 Outlook 之前获取该联系人。我该怎么办请帮忙。 该手机有自己的工具可以将联系人与 Outlook 同步,所以我使用wireshak 捕获了它的数据包,然后我得到了

02 00 2d cb 00
   00 00 00 42 00 20 61 70 70 6c 69 63 61 74 69 6f
   6e 2f 76 6e 64 2e 73 79 6e 63 6d 6c 2b 77 62 78
   6d 6c 00 c3 00 00 00 cd 

请参阅 pcapmg1。 当我尝试使用我的代码发送相同的数据包时 我没有收到

90 00 03
电话的预期响应。请参阅 pcapmg2 我正在附加 pacap 文件,用于为手机本身提供的工具捕获的数据包。 我成功地使用串行连接到设备

LPCWSTR szPort2 = L"\\\\?\\usb#vid_1f58&pid_1f20&mi_03#dummy_03#{86e0d1e0-8089-11d0-9ce4-08003e301f73}";
HANDLE hSerial = CreateFile(szPort2, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);

//FILE_ATTRIBUTE_NORMAL,FILE_FLAG_OVERLAPPED 我也成功发送了obex的AT命令 // 发送AT+ISAT_OBEX=1指令

const char* command = "AT+ISAT_OBEX=1";
DWORD bytesWritten;
if (!WriteFile(hSerial, command, strlen(command), &bytesWritten, NULL)) {
    std::cerr << "Error writing to serial port\n";
    return;}
after this i sent packets by reffering this pdf [OBEX Connect Example][1] page 23 ( ) OBEX Connect Example

我也在 OBEX Connect 中取得了成功。但我不知道如何继续前进 用于 obex 的 pcapmg1 与 wbxml 一起放置pcapmg2 这是设备的预期响应,但我没有得到 这是我发送的第一个数据包

0x80, 0x00, 0x15, 0x10, 0x00, 0x04, 0x00, 0x46, 0x00, 0x0e, 0x53, 
0x59, 0x4e, 0x43, 0x4d, 0x4c, 0x2d, 0x53, 0x59, 0x4e, 0x43,0x00,0x00,0x00

我得到了成功的回复

a0 00 1a 10 00 10 00 cb 00 00 00 00 4a 00 0e 53 59 4e 43 4d 4c 2d 53 59 4e 43

但是我正在发送第二个数据包

0x02,0x00,0x2d,0xcb,0x00,0x00,0x00,0x00,0x42,0x00,0x20,0x61,
0x70,0x70,0x6c,0x69,0x63,0x61,0x74,0x69,0x6f,0x6e,0x2f,
0x76,0x6e,0x64,0x2e,0x73,0x79,0x6e,0x63,0x6d,0x6c,0x2b,
0x77,0x62,0x78,0x6d,0x6c,0x00,0xc3,0x00,0x00,0x00,0xcd

,我没有从设备得到任何响应

© www.soinside.com 2019 - 2024. All rights reserved.