如何通过c#中的XML序列化输出hex数?

我有一些类和结构,我使用XML序列化来保存和调用数据,但我想要的一个function是以hex表示forms输出整数。 是否有任何属性可以挂在这些结构上以实现这一目标?

有一些代码味道,但以下起作用:

public class ViewAsHex { [XmlIgnore] public int Value { get; set; } [XmlElement(ElementName="Value")] public string HexValue { get { // convert int to hex representation return Value.ToString("x"); } set { // convert hex representation back to int Value = int.Parse(value, System.Globalization.NumberStyles.HexNumber); } } } 

在控制台程序中测试该类:

 public class Program { static void Main(string[] args) { var o = new ViewAsHex(); o.Value = 258986522; var xs = new XmlSerializer(typeof(ViewAsHex)); var output = Console.OpenStandardOutput(); xs.Serialize(output, o); Console.WriteLine(); Console.WriteLine("Press enter to exit."); Console.ReadLine(); } } 

结果:

   f6fd21a  

您可以实现完全自定义序列化,但这可能有点多。 如何公开一个属性MyIntegerAsHex ,它将整数作为字符串返回,格式为hex数: MyInteger.ToString("X"); 该属性需要一个setter,即使它是一个计算字段,因此序列化对象中的字符串可以在反序列化时被送入新实例。

然后,您可以实现反序列化回调,或者只是将代码放入setter中,在反序列化对象时将hex数解析为十进制整数: MyInteger = int.Parse(IntegerAsHex, NumberStyles.AllowHexNumber);

因此,总之,您的属性看起来像这样:

 public string MyIntegerAsHex { get { return MyInteger.ToString("X"); } set { MyInteger = int.Parse(value, NumberStyles.AllowHexNumber); } } 

然后,如果您不想在XML文件中将数字视为十进制整数,只需使用[XmlIgnore]标记它。

我从KeithScode4life中得到了一个稍微改进的变通方法。

 using System; using System.Linq; public class Data { [XmlIgnore()] public uint Value { get; set; } [XmlAttribute("Value", DataType = "hexBinary")] public byte[] ValueBinary { get { return BitConverter.GetBytes(Value).Reverse().ToArray(); } set { Value = BitConverter.ToUInt32(value.Reverse().ToArray(), 0); } } } 

这样做的好处是xsd.exe工具将type属性设置为xs:hexBinary而不是xs:string

        

我知道,最后的答案是两年多前,但我一直在寻找解决方案并找到了这个主题。 但是对提议的解决方案不满意,所以我试图找到自己的解决方案:

 public struct HInt32 : IXmlSerializable { private int _Value; public HInt32(int v) { _Value = v; } XmlSchema IXmlSerializable.GetSchema() { return null; } void IXmlSerializable.ReadXml(XmlReader reader) { _Value = Int32.Parse(reader.ReadContentAsString().TrimStart('0', 'x'), NumberStyles.HexNumber); } void IXmlSerializable.WriteXml(XmlWriter writer) { writer.WriteValue("0x" + _Value.ToString("X2").PadLeft(8, '0')); } public static implicit operator int(HInt32 v) { return v._Value; } public static implicit operator HInt32(int v) { return new HInt32(v); } } 

现在,您可以在序列化类中使用此类型而不是Int32:

 public TestClass { public HInt32 HexaValue { get; set; } } public void SerializeClass() { TestClass t = new TestClass(); t.HexaValue = 6574768; // Transparent int assigment XmlSerializer xser = new XmlSerializer(typeof(TestClass)); StringBuilder sb = new StringBuilder(); using(StringWriter sw = new StringWriter(sb)) { xser.Serialize(sw, t); } Console.WriteLine(sb.ToString()); } 

结果是:

   0x006452B0  

您可以调整解决方案以获得所需的确切格式,并使HInt32结构更加“Int32 complient”。 警告:此解决方案不能用于将属性序列化为属性。