反序列化对象忽略某些节点
Posted
技术标签:
【中文标题】反序列化对象忽略某些节点【英文标题】:Deserializing object ignoring certain nodes 【发布时间】:2020-09-16 00:55:31 【问题描述】:我有一个使用 XmlSerializer 序列化的对象。当尝试将此 XML 文件反序列化回对象时,由于某种原因它正在跳过一个节点。
<?xml version="1.0" encoding="utf-8"?>
<Dialogue xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Conversations>
<Conversation Id="993fed92-6917-4003-975f-78df4ca77257" Name="sdfsf">
<TextNode Id="8ce1fba9-9daf-4145-b374-d8d7df6ca983" IsGraphEntryPoint="false" NodePositionX="1056" NodePositionY="341">
<Speaker>None</Speaker>
<Lines />
</TextNode>
<ChoiceNode Id="7c697932-dbde-47a2-b931-bc881811ef63" IsGraphEntryPoint="false" NodePositionX="783" NodePositionY="605">
<Choices>
<ChoiceOptionNode ChoiceId="cbe28c44-a535-4191-80b2-1bb3d1881cb7" PortName="Choice#1" ConnectsTo="82fefda3-f6d9-4462-a39e-a20c56f97bcb">
<Lines>
<ChoiceOptionLineNode>
<LanguageId>42d97432-c027-416d-2aa8-1ec47ca1410e</LanguageId>
<LanguageCode>NL</LanguageCode>
<Text />
</ChoiceOptionLineNode>
</Lines>
</ChoiceOptionNode>
</Choices>
</ChoiceNode>
</Conversation>
</Conversations>
</Dialogue>
所有 Textnodes 都正确反序列化,但 Choicenodes 似乎完全被忽略了。
对象本身:
public class ChoiceNode : BaseConversationNode
[XmlArray("Choices")]
[XmlArrayItem(ElementName = "ChoiceOptionNode")]
public List<ChoiceOptionNode> Choices;
public class ChoiceOptionNode
[XmlAttribute]
public Guid ChoiceId;
[XmlAttribute]
public string PortName;
[XmlArray("Lines")]
[XmlArrayItem(ElementName = "ChoiceOptionLineNode")]
public List<ChoiceOptionLineNode> Lines;
[XmlAttribute]
public Guid ConnectsTo;
public class ChoiceOptionLineNode
public Guid LanguageId;
public string LanguageCode;
public string Text;
public abstract class BaseConversationNode
[XmlElement(ElementName = "Connections")]
public List<Output> Connections = new List<Output>();
[XmlIgnore]
public GraphNode Node;
[XmlAttribute]
public Guid Id;
[XmlAttribute]
public bool IsGraphEntryPoint;
[XmlIgnore]
public Rect NodeRect;
[XmlAttribute]
public float NodePositionX;
[XmlAttribute]
public float NodePositionY;
/// <summary>
/// The hex color of the node window
/// </summary>
/// <returns></returns>
[XmlIgnore]
public string NodeColorHex => !String.IsNullOrEmpty(options?.NodeColor) ? options.NodeColor : "c1c1c1";
[XmlIgnore]
public float NodeWidth => options?.NodeWidth ?? 200;
[XmlIgnore]
public float NodeHeight => options?.NodeHeight ?? 150;
[XmlIgnore]
private NodeOptionsAttribute _options;
[XmlIgnore]
private NodeOptionsAttribute options
get
if (_options == null)
NodeOptionsAttribute attr = (NodeOptionsAttribute)Attribute.GetCustomAttribute(this.GetType(), typeof(NodeOptionsAttribute));
_options = attr;
return _options;
[XmlIgnore]
public List<Language> Languages;
[XmlRoot(ElementName = "Connection")]
public class Output
[XmlAttribute]
public Guid ConnectsTo;
[XmlAttribute]
public string PortName;
[XmlAttribute]
public Direction PortDirection;
[XmlAttribute]
public Port.Capacity Capacity;
public class Dialogue
/// <summary>
/// The list of Conversations
/// </summary>
[XmlArrayItem(ElementName = "Conversation")]
public List<Conversation> Conversations;
/// <summary>
/// The list of Languages
/// </summary>
public List<Language> Languages;
[XmlIgnore]
private List<Type> nodeTypes;
[XmlIgnore]
public List<Type> NodeTypes
get
if (nodeTypes == null)
nodeTypes = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(assembly =>
assembly.GetTypes())
.Where(type =>
type.IsSubclassOf(typeof(BaseConversationNode))
//&& type.CustomAttributes.Any(x => x.AttributeType != typeof(AutoGeneratedNodeAttribute))
&& !type.Equals(typeof(StartNode))
)
.ToList();
return nodeTypes;
public class Language
[XmlAttribute]
public Guid Id;
public string Name;
public string Code;
public class Conversation
[XmlAttribute]
public Guid Id;
[XmlAttribute]
public string Name;
[XmlElement(typeof(StartNode), ElementName = "StartNode")]
[XmlElement(typeof(TextNode), ElementName = "TextNode")]
public List<BaseConversationNode> Nodes;
我觉得这很奇怪,因为我使用的 XML 正是 XML 序列化程序首先返回的内容。你会认为它能够正确反序列化它自己的序列化 XML...
我在这里错过了什么?
亲切的问候,
-弗迪
编辑:忘记添加基类。 编辑 2:我是个笨蛋,忘记在第一次编辑时添加其他相关类。
【问题讨论】:
【参考方案1】:我注意到了我的错误。如下:
[XmlElement(typeof(StartNode), ElementName = "StartNode")]
[XmlElement(typeof(TextNode), ElementName = "TextNode")]
public List<BaseConversationNode> Nodes;
我应该在 Nodes 变量中添加另一个 XmlElement
属性:
[XmlElement(typeof(StartNode), ElementName = "StartNode")]
[XmlElement(typeof(TextNode), ElementName = "TextNode")]
[XmlElement(typeof(ChoiceNode), ElementName = "ChoiceNode")]
public List<BaseConversationNode> Nodes;
这确实可以正确地反序列化 XML。
【讨论】:
以上是关于反序列化对象忽略某些节点的主要内容,如果未能解决你的问题,请参考以下文章