Как сериализовать массив байтов в XML с помощью XmlSerializer в C#?
скажем, у нас есть структура, что данные предоставляются неуправляемым массивом байтов с помощью Маршала.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);
}
}
и метод save
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:tempdataOne.xml", writer);
ожидается, что XML-код:
<?xml version="1.0" encoding="utf-8"?>
<MyData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ID>1</ID>
<structType>ST_1</structType>
<MNG_Y_Params>
<Number>35</Number>
<Version>1</Version>
<OliNumber>#1</OliNumber>
<InterfaceType>15</InterfaceType>
</MNG_Y_Params>
</MyData>
результат XML:
<?xml version="1.0" encoding="utf-8"?>
<MyData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ID>1</ID>
<structType>ST_1</structType>
<MNG_Y_Params>
<Number>35</Number>
<Version>1</Version>
<OliNumber>IzE=</OliNumber>
<InterfaceType>15</InterfaceType>
</MNG_Y_Params>
</MyData>
обратите внимание на байтовый массив (OliNumber) результат.
есть атрибут, который мы могли бы использовать здесь? Что я упускаю?
Спасибо за ваше время и помощь.
Илан
на ссылка
3 ответов
на XmlSerializer
по умолчанию будет кодировать массивы байтов использованием кодировки base 64. Если вы используете этой сайт и вставить в IzE=
, и расшифруйте его, результат будет #1
. Вы можете изменить кодировку, установив XmlElementAttribute.Тип данных. Я не уверен, если [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;
}
}
байты затем форматируются как шестнадцатеричные значения и разделяются знаком минус: 00-AF-B1