如何在C#中使用XmlSerializer将字节数组序列化为XML?

假设我们有一个结构,它的数据由使用Marshal.PtrToStructure的非托管字节数组提供。

C#结构布局:

[StructLayout(LayoutKind.Sequential, Size = 128, CharSet = CharSet.Ansi, Pack = 1)] public struct MNG_Y_Params { public byte Number; public byte Version; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] public byte[] OliNumber; public byte InterfaceType; } 

字节数组表示非托管代码中的(ascii)字符串。

此结构是另一个结构的成员(具有一些其他成员):

 public struct MyData { public int ID; public StructType structType; [XmlElement(ElementName="MNG_Y_Params")] public MNG_Y_Params y_params; [XmlElement(ElementName = "SimpleStruct2")] public SimpleStruct2 ss2; }; 

所以我们也有这个支持代码

 public class XMLIgnore { static public XmlSerializer customserialiser(MyData d) { XmlAttributes attrs = new XmlAttributes(); attrs.XmlIgnore = true; XmlAttributeOverrides xmlOveride = new XmlAttributeOverrides(); switch (d.structType) { case StructType.ST_1: xmlOveride.Add(typeof(MyData), "ss2", attrs); break; case StructType.ST_2: xmlOveride.Add(typeof(MyData), "y_params", attrs); break; default: break; } return new XmlSerializer(typeof(MyData), xmlOveride); } } 

和保存方法

  static void SaveToXml(object obj, string fileName, XmlSerializer writer) { //XmlSerializer writer = new XmlSerializer(obj.GetType()); using (StreamWriter file = new StreamWriter(fileName)) { writer.Serialize(file, obj); } } 

对于示例,我们只生成一些数据。

  MNG_Y_Params yParams = new MNG_Y_Params(); yParams.Version = 1; yParams.InterfaceType = 15; yParams.Number = 35; ASCIIEncoding enc = new ASCIIEncoding(); yParams.OliNumber = enc.GetBytes("#1"); MyData md1 = new MyData(); md1.ID = 1; md1.structType = StructType.ST_1; md1.y_params = yParams; XmlSerializer writer = XMLIgnore.customserialiser(md1); SaveToXml(md1, @"C:\temp\dataOne.xml", writer); 

预期的XML:

   1 ST_1  35 1 #1 15   

结果XML:

   1 ST_1  35 1 IzE= 15   

请关注字节数组成员(OliNumber)结果。

我们可以在这里使用一个属性吗? 我错过了什么?

感谢您的时间和帮助。

宜兰

供参考

默认情况下, XmlSerializer将使用base 64编码对字节数组进行编码。 如果您使用此站点并粘贴在IzE= ,并对其进行解码,则结果为#1 。 您可以通过设置XmlElementAttribute.DataType来更改编码。 我不确定[XmlElement(DataType = "string")]是否有效,但您可以尝试一下。 使用[XmlElement(DataType = "hexBinary")]将生成原始字节。

我使用以下方法使用它:

  public class MySerializableClass { [XmlIgnore] public string NaughtyXmlCharactersAsString { get; set; } [XmlElement(ElementName = "NaughtyXmlCharacters", DataType = "hexBinary")] public byte[] NaughtyXmlCharactersAsBytes { get { return Encoding.UTF8.GetBytes(NaughtyCharactersAsString ?? string.Empty); } set { NaughtyXmlCharactersAsString = Encoding.UTF8.GetString(value); } } 

然后我只会访问该属性的“AsString”版本。

这就是我做的方式:

 public class MySerializableClass { private string dummy; [XmlElement("NaughtyXmlCharacters")] public string NaughtyXmlCharactersAsString { get { return BitConverter.ToString(NaughtyXmlCharacters); } set { // without this, the property is not serialized. dummy = value; } } [XmlIgnore] public byte[] NaughtyXmlCharacters { get; set; } } 

然后将字节格式化为hex值,并用减号分隔:00-AF-B1