gpt4 book ai didi

c# - 将类的可空双属性序列化为 Xml 文本

转载 作者:数据小太阳 更新时间:2023-10-29 02:29:49 26 4
gpt4 key购买 nike

我必须使用以下代码进行序列化:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace MyExample
{
class Program
{
static void Main(string[] args)
{
MyXmlDocument document = new MyXmlDocument();

document.MyExample.NodeA.value = "Value To Node A";
document.MyExample.NodeB.value = "Value To Node B";
document.MyExample.NodeC.value = 1234.567;
document.WriteToXml(@"C:\Users\E9JR\Desktop\mydocument.xml");
Console.Write("> Done!");
Console.ReadKey();
}
}

[XmlRoot(ElementName="xmlExample",IsNullable=false)]
public class XmlExample
{
private NodeA_Elem _nodea;
[XmlElement()]
public NodeA_Elem NodeA
{
get
{
return _nodea;
}
set
{
_nodea = value;
}
}
public bool ShouldSerializeNodeA()
{
return !String.IsNullOrEmpty(_nodea.value);
}

private NodeB_Elem _nodeb;
[XmlElement(ElementName = "NodeB", IsNullable = false)]
public NodeB_Elem NodeB
{
get
{
return _nodeb;
}
set
{
_nodeb = value;
}
}
public bool ShouldSerializeNodeB()
{
return !String.IsNullOrEmpty(_nodeb.value);
}

private NodeC_Elem _nodec;
[XmlElement(ElementName = "NodeC",IsNullable=false)]
public NodeC_Elem NodeC
{
get
{
return _nodec;
}
set
{
_nodec = value;
}
}
public bool ShouldSerializeNodeC()
{
return _nodec.value.HasValue;
}

public XmlExample()
{
_nodea = new NodeA_Elem();
_nodeb = new NodeB_Elem();
_nodec = new NodeC_Elem();
}
}

public class NodeA_Elem
{
[XmlText()]
public string value { get; set; }
}

public class NodeB_Elem
{
[XmlText()]
public string value { get; set; }
}

public class NodeC_Elem
{
[XmlText()]
public double? value { get; set; }
}

public class MyXmlDocument
{
private XmlExample _myexample;
public XmlExample MyExample
{
get
{
return _myexample;
}
set
{
_myexample = value;
}
}

public void WriteToXml(string path)
{
XmlSerializer serializer = new XmlSerializer(typeof(XmlExample));

XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.Encoding = Encoding.Unicode;

StringWriter txtwriter = new StringWriter();
XmlWriter xmlwtr = XmlWriter.Create(txtwriter, settings);
serializer.Serialize(xmlwtr, MyExample);

StreamWriter writer = new StreamWriter(path);
writer.Write(txtwriter.ToString());

writer.Close();
}

public void ReadXml(string path)
{
XmlSerializer serializer = new XmlSerializer(typeof(XmlExample));

StreamReader reader = new StreamReader(path);

MyExample = (XmlExample)serializer.Deserialize(reader);

}

public MyXmlDocument()
{
_myexample = new XmlExample();
}
}
}

我正在尝试使用 value 属性作为节点的文本来序列化 NodeC,这是一个 double 属性,但它不起作用,即使使用 ShouldSerialize 模式来避免序列化空节点也是如此。 NodeA 和 NodeB 工作正常。我需要 NodeC 方面的帮助。

最佳答案

您不能将可为 null 的 double 值序列化为 XmlText。如果您查看您收到的 System.InvalidOperationException 的完整文本,您将看到如下内容:

   InnerException: System.InvalidOperationException
Message="Cannot serialize member 'value' of type System.Nullable`1[System.Double]. XmlAttribute/XmlText cannot be used to encode complex types."
Source="System.Xml"
StackTrace:
at System.Xml.Serialization.XmlReflectionImporter.ImportAccessorMapping(MemberMapping accessor, FieldModel model, XmlAttributes a, String ns, Type choiceIdentifierType, Boolean rpc, Boolean openModel, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.ImportFieldMapping(StructModel parent, FieldModel model, XmlAttributes a, String ns, RecursionLimiter limiter)
at System.Xml.Serialization.XmlReflectionImporter.InitializeStructMembers(StructMapping mapping, StructModel model, Boolean openModel, String typeName, RecursionLimiter limiter)

该消息不言自明。来自 documentation for XmlTextAttribute 的确认:

You can apply the XmlTextAttribute to public fields and public read/write properties that return primitive and enumeration types.

You can apply the XmlTextAttribute to a field or property that returns an array of strings. You can also apply the attribute to an array of type Object but you must set the Type property to string. In that case, any strings inserted into the array are serialized as XML text.

The XmlTextAttribute can also be applied to a field that returns an XmlNode or an array of XmlNode objects.

要了解为什么 ShouldSerializeXXX() 在这里没有帮助,您应该了解 XmlSerializer works as follows :

  1. 第一次序列化类型时,XmlSerializer 构造函数在内部编写运行时 C# 代码以使用反射序列化和反序列化该类型的实例和所有引用类型,然后编译代码并将生成的 DLL 加载到内存中。

  2. 随后,类实例的序列化和反序列化由先前创建的动态 DLL 执行。

但是第1步没有访问类的实例。它完全基于类型信息创建其动态库。并且,从类型信息中,无法推断相关的 ShouldSerializeXXX() 方法在 double? 时会返回 false 为空。因此,动态代码生成中止,因为无法生成将可为空的 double 值写入 XmlText 的代码。

作为变通方法,您可以制作一个表示 double 的字符串属性:

public class NodeC_Elem
{
[XmlIgnore]
public double? value { get; set; }

[XmlText]
public string StringValue
{
get
{
if (value == null)
return null;
return XmlConvert.ToString(value.Value);
}
set
{
if (value == null)
{
this.value = null;
return;
}
this.value = XmlConvert.ToDouble(value);
}
}
}

关于c# - 将类的可空双属性序列化为 Xml 文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28110589/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com