我从xml反序列化一个对象,但KeywordList和ResponseList中的字符串总是空的。
尝试了很多事情,似乎无法做到正确。如果我使用阅读器循环播放,则显示值。
from tkinter import *
def activateMotors():
if motorsOn.get() == 1:
scale.config(state=ACTIVE)
elif motorsOn.get() == 0:
scale.config(state=DISABLED)
root = Tk()
root.wm_title('Servo Control')
motorsOn= IntVar()
motorsCheck=Checkbutton(root,
text="Motors ON(checked)/OFF(unchecked)",
variable=motorsOn,
command=activateMotors)
motorsCheck.pack()
scale = Scale(root, from_=0, to=180,
orient=HORIZONTAL,label="Motor #",state=DISABLED)
scale.pack()
root.mainloop()
以下是示例xml
using System;
using System.Collections.Specialized;
using System.Xml;
using System.Xml.Serialization;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
XmlSerializer serializer = new XmlSerializer(typeof(ElizaResponses));
using (XmlReader reader = XmlReader.Create("eliza.xml"))
{
ElizaResponses responses = (ElizaResponses)serializer.Deserialize(reader);
reader.Close();
// This reads in all data
//StreamReader reader = new StreamReader("eliza.xml");
//reader.ReadToEnd();
//reader.MoveToContent();
//while (reader.Read())
//{
// if(reader.NodeType == XmlNodeType.Text)
// {
// Console.WriteLine("{0}, {1}", reader.NodeType, reader.Value);
// }
// else
// {
// Console.WriteLine("{0}, {1}", reader.NodeType, reader.Name);
// }
//}
}
Console.ReadLine();
}
}
[Serializable]
[XmlRoot("ElizaResponses")]
[XmlType("ElizaResponses")]
public sealed class ElizaResponses
{
ElizaConversation[] chatList;
public ElizaConversation[] ChatList
{
get { return this.chatList; }
set { this.chatList = value; }
}
}
[Serializable]
public sealed class ElizaConversation
{
// Tried List<string>, string[], StringCollection
StringCollection keywordList = new StringCollection();
StringCollection responseList = new StringCollection();
// Tried [XmlArray], [XmlElement]
[XmlElement("KeywordList")]
[XmlArrayItem("string", typeof(string))]
StringCollection KeywordList
{
get { return this.keywordList; }
set { this.keywordList = value; }
}
[XmlArray("ResponseList")]
[XmlArrayItem("string", typeof(string))]
StringCollection ResponseList
{
get { return this.responseList; }
set { this.responseList = value; }
}
}
}
应该添加我没有异常并且已经在app.config文件中显示错误消息
<?xml version="1.0" encoding="utf-8"?>
<ElizaResponses>
<ChatList>
<ElizaConversation>
<KeywordList>
<string>ok</string>
</KeywordList>
<ResponseList>
<string>cool.</string>
<string>great.</string>
<string>:)</string>
</ResponseList>
</ElizaConversation>
<ElizaConversation>
<KeywordList>
<string>shutup</string>
<string>shut up</string>
</KeywordList>
<ResponseList>
<string>make me.</string>
<string>no I won't.</string>
</ResponseList>
</ElizaConversation>
</ChatList>
</ElizaResponses>
答案 0 :(得分:1)
您应该首先自动生成它们并验证自动生成的类型是否有效,而不是继续尝试手动生成类型。只有这样,根据需要简化。如果将XML发布到https://xmltocsharp.azurewebsites.net/,则可以生成将反序列化XML的类:
[XmlRoot(ElementName = "KeywordList")]
public class KeywordList
{
[XmlElement(ElementName = "string")]
public List<string> String { get; set; }
}
[XmlRoot(ElementName = "ResponseList")]
public class ResponseList
{
[XmlElement(ElementName = "string")]
public List<string> String { get; set; }
}
[XmlRoot(ElementName = "ElizaConversation")]
public class ElizaConversation
{
[XmlElement(ElementName = "KeywordList")]
public KeywordList KeywordList { get; set; }
[XmlElement(ElementName = "ResponseList")]
public ResponseList ResponseList { get; set; }
}
[XmlRoot(ElementName = "ChatList")]
public class ChatList
{
[XmlElement(ElementName = "ElizaConversation")]
public List<ElizaConversation> ElizaConversation { get; set; }
}
[XmlRoot(ElementName = "ElizaResponses")]
public class ElizaResponses
{
[XmlElement(ElementName = "ChatList")]
public ChatList ChatList { get; set; }
}
您可以使用上面的代码验证此版本的ElizaResponses
将反序列化您的XML。但是,这些可以简化。
首先,将KeywordList
和ResponseList
合并到StringList
:
public class StringList
{
[XmlElement(ElementName = "string")]
public List<string> String { get; set; }
}
[XmlRoot(ElementName = "ElizaConversation")]
public class ElizaConversation
{
[XmlElement(ElementName = "KeywordList")]
public StringList KeywordList { get; set; }
[XmlElement(ElementName = "ResponseList")]
public StringList ResponseList { get; set; }
}
接下来,取消StringList
完全将其替换为List<string<>
。由于消除了额外级别的容器类,因此需要用[XmlElement]
和[XmlArray]
替换两个[XmlArrayItem]
属性,从而产生以下最终版本:
[XmlRoot(ElementName = "ElizaConversation")]
public class ElizaConversation
{
[XmlArray(ElementName = "KeywordList")]
[XmlArrayItem(ElementName = "string")]
public List<string> KeywordList { get; set; }
[XmlArray(ElementName = "ResponseList")]
[XmlArrayItem(ElementName = "string")]
public List<string> ResponseList { get; set; }
}
[XmlRoot(ElementName = "ChatList")]
public class ChatList
{
[XmlElement(ElementName = "ElizaConversation")]
public List<ElizaConversation> ElizaConversation { get; set; }
}
[XmlRoot(ElementName = "ElizaResponses")]
public class ElizaResponses
{
[XmlElement(ElementName = "ChatList")]
public ChatList ChatList { get; set; }
}
您最初的尝试包括以下问题:
StringCollection
。[XmlArrayItem("Item", typeof(string))]
声明中,名称"Item"
错误。应该是"string"
。[XmlElement]
无法与[XmlArrayItem]
合并。KeywordList
和ResponseList
不公开。 XmlSerializer
仅序列化公众成员。示例fiddle。
答案 1 :(得分:0)
找到答案。无法设置属性,因为它们不公开。