XML序列化和迭代 [英] XML Serialization and iterating
问题描述
我有一个有3个词这个XML文件。
<同义词集ID =n00252662TYPE =N>
< lex_filenum> 04< / lex_filenum>
&所述;字lex_id =1>吹扫&下; /字GT;
<字lex_id =1>净化< /字GT;
&所述;字lex_id =1>下法&下; /字GT;
<指针裁判=n01247647>上位词< /指针>
<指针裁判=v00905283来源=3目标=1> Derivationally相关表格和LT; /指针>
<指针裁判=v00475647来源=2TARGET =1> Derivationally相关表格和LT; /指针>
<指针裁判=v00475819来源=1目标=2> Derivationally相关表格和LT; /指针>
<指针裁判=v00905283来源=1目标=1> Derivationally相关表格和LT; /指针>
<指针裁判=n00252894>下位词< /指针>
<高清>一些柱头或费及结算LT自己(或他人)的行为; / DEF>
< /同义词集>
和DictionaryList.cs
使用System.Collections.Generic;
使用的System.Xml.Serialization;
使用的System.Xml;
使用UnityEngine;
使用System.IO;[XmlRoot(DictionaryList)]
公共类DictionaryList
{
[XmlArray(同义词集)]
[XmlArrayItem(同义词集)]
公开名单<&字典GT;快译通=新的List<&字典GT;(); //字符串的文件路径= Application.dataPath +/Resources/gamedata.xml 公共静态DictionaryList负荷(字符串路径)
{
VAR串行器=新的XmlSerializer(typeof运算(DictionaryList)); 使用(VAR流=新的FileStream(路径,FileMode.Open))
{
返回serializer.Deserialize(流)为DictionaryList;
}
} //直接从给定字符串加载XML。有用与www.text组合。
公共静态DictionaryList LoadFromText(字符串文本)
{
VAR串行器=新的XmlSerializer(typeof运算(DictionaryList));
返回serializer.Deserialize(新StringReader(文本))作为DictionaryList;
}
}
然后将Dictionary.cs
使用的System.Xml;
使用的System.Xml.Serialization;
使用System.Linq的;
System.Collections中使用;
使用System.Collections.Generic;公共类字典
{
公共字符串字; 公共字符串DEF; 公共字符串的例子; 公共词典()
{ } 公共词典(NME字符串,字符串DES)
{
字= NME; DEF =德;
}
}
在我的code,解串器不包括自单词LT字清除和下法; - 变量是不是数组
我试图让一个数组列表,但我不知道,如果解串器甚至会放换句话说,如果我做一个列表数组字吧。
加访问列表里的名单是给了我一个问题。我想知道,如果有我可以,我可以访问或存储连字作为数组在不改变XML文件的选项。
这是我的主要字典文件
使用UnityEngine;
System.Collections中使用;
使用System.Collections.Generic;
使用的System.Xml;
使用的System.Xml.Serialization;
使用System.IO;
使用System.Linq的;
使用UnityEngine.UI;公共类MainDictionary:MonoBehaviour {
DictionaryList DictionaryCollectionNoun;
DictionaryList DictionaryCollectionVerb;
DictionaryList DictionaryCollectionADV;公共InputField SearchField;
公开文本名称字段;
公开文本DetailsField;
公开文本DebugText;
公开文本ExampleField;
公共TextAsset textAssetNoun;
公共TextAsset textAssetVerb;
公共TextAsset textAssetADV;
//使用这个初始化
无效的start(){ // TextAsset textAsset =(TextAsset)Resources.Load(datanoun的typeof(TextAsset));
// XmlDocument的xmlDoc中=新的XmlDocument();
//xmldoc.LoadXml(textAsset.text);
DebugText.text = Application.dataPath; textAssetNoun =(TextAsset)Resources.Load(datanoun);
textAssetVerb =(TextAsset)Resources.Load(dataverb);
textAssetADV =(TextAsset)Resources.Load(dataadv);
// XmlDocument的xmlDoc中=新的XmlDocument();
//xmldoc.LoadXml(textAsset.text); //例的伪code Danzee模式;
// VAR XMLDATA = @\"<DictionaryList><synsets><synset><word>test</word><def>Fun</def></synset></synsets></DictionaryList>\";
DictionaryCollectionNoun = DictionaryList.LoadFromText(textAssetNoun.text);
DictionaryCollectionVerb = DictionaryList.LoadFromText(textAssetVerb.text);
DictionaryCollectionADV = DictionaryList.LoadFromText(textAssetADV.text);
//Debug.Log(Application.dataPath);
//DebugText.text = xmldoc.ToString();
}公共无效ChangeSearch()
{
//字典结果=新词典(无结果,无说明);
//布尔nounBool = DictionaryCollectionNoun.Dict.Any(P =&GT; p.word == SearchField.text.ToLower())?真假;
//布尔verbBool = DictionaryCollectionVerb.Dict.Any(P =&GT; p.word == SearchField.text.ToLower())?真假;
//布尔advbool = DictionaryCollectionADV.Dict.Any(P =&GT; p.word == SearchField.text.ToLower())?真假;
//如果(nounBool)
// {
//结果= DictionaryCollectionNoun.Dict.Find(X =&GT; x.word == SearchField.text.ToLower());
//}
//否则,如果(verbBool)
// {
//结果= DictionaryCollectionVerb.Dict.Find(X =&GT; x.word == SearchField.text.ToLower());
//}
//否则,如果(advbool)
// {
//结果= DictionaryCollectionADV.Dict.Find(X =&GT; x.word == SearchField.text.ToLower());
//}
//NameField.text = Result.word1;
//DetailsField.text = Result.def2;
//ExampleField.text = Result.example;}
}
请尝试以下操作:
公共类字
{
[XmlAttribute(lex_id)]
公共字符串LexId {搞定;组; } [XMLTEXT]
公共字符串值{获得;组; } 公共重写字符串的ToString()
{
返回值;
} 公共静态明确经营者的字符串(字字)
{
如果(字== NULL)
返回null;
返回word.Value;
}
}公共类SynsetPointer
{
[XmlAttribute(参)]
公共字符串参考文献{搞定;组; } [XmlAttribute(源)]
公共字符串源{搞定;组; } [XmlAttribute(目标)]
公共字符串目标{搞定;组; } [XMLTEXT]
公共字符串值{获得;组; }
}[XmlRoot(同义词集)]
[XmlType将(同义词集)]
公共类同义词集合
{
公共同义词集合()
{
this.Pointers =新的List&LT; SynsetPointer&GT;();
this.Words =新的List&LT; Word和GT;();
} [XmlElement的(lex_filenum)]
公众诠释LexFilenum {搞定;组; } [的XmlElement(字)]
公开名单&LT; Word和GT;个字{搞定;组; } [XmlIgnore]
公共IEnumerable的&LT;串GT; WordValues {{返回(字== NULL空:Words.Select(W =&GT;(串)W)?); }} [XmlElement的(指针)]
公开名单&LT; SynsetPointer&GT;指针{搞定;组; } [的XmlElement(DEF)]
公共字符串定义{搞定;组; }
}[XmlRoot(DictionaryList)]
公共类DictionaryList
{
公共DictionaryList()
{
this.Dict =新的List&LT;同义词集&GT;();
} [XmlArray(同义词集)]
[XmlArrayItem(同义词集)]
公开名单&LT;同义词集&GT;快译通{搞定;组; } //字符串的文件路径= Application.dataPath +/Resources/gamedata.xml 公共静态DictionaryList负荷(字符串路径)
{
VAR串行器=新的XmlSerializer(typeof运算(DictionaryList)); 使用(VAR流=新的FileStream(路径,FileMode.Open))
{
返回serializer.Deserialize(流)为DictionaryList;
}
} //直接从给定字符串加载XML。有用与www.text组合。
公共静态DictionaryList LoadFromText(字符串文本)
{
VAR串行器=新的XmlSerializer(typeof运算(DictionaryList));
返回serializer.Deserialize(新StringReader(文本))作为DictionaryList;
}
}
我改名为你的词典
类同义词集
为清楚起见,因为C#已经有各种的词典类它做不同的事情。 p>
要多读字
元素融入到一个数组,声明为列表&LT;在<$
; Word和GT C $ C>同义词集类,然后应用<一个href=\"https://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlelementattribute%28v=vs.110%29.aspx\"相对=nofollow> [的XmlElement]
属性。这告诉序列化,期望字
元素,而不是元素嵌套列表中重复出现。
这将成功地读写XML看起来像这样的:
&LT; DictionaryList&GT;
&LT;同义词集&GT;
&LT;同义词集&GT;
&所述; lex_filenum→4&下; / lex_filenum&GT;
&所述;字lex_id =1&GT;吹扫&下; /字GT;
&LT;字lex_id =1&GT;净化&LT; /字GT;
&所述;字lex_id =1&GT;下法&下; /字GT;
&LT;指针裁判=n01247647&GT;上位词&LT; /指针&GT;
&LT;指针裁判=v00905283来源=3目标=1&GT; Derivationally相关表格和LT; /指针&GT;
&LT;指针裁判=v00475647来源=2TARGET =1&GT; Derivationally相关表格和LT; /指针&GT;
&LT;指针裁判=v00475819来源=1目标=2&GT; Derivationally相关表格和LT; /指针&GT;
&LT;指针裁判=v00905283来源=1目标=1&GT; Derivationally相关表格和LT; /指针&GT;
&LT;指针裁判=n00252894&GT;下位词&LT; /指针&GT;
&LT;高清&GT;一些柱头或费及结算LT自己(或他人)的行为; / DEF&GT;
&LT; /同义词集&GT;
&LT; /同义词集&GT;
&LT; / DictionaryList&GT;
块引用>更新
要通过所有的
同义词集
类所有的字
类的所有文本值在一个循环DictionaryList
,你可以这样做:VAR testXml = @&LT; DictionaryList&GT;&LT;同义词集&GT;&LT;同义词集ID =n00001740,TYPE =N&GT;&LT; lex_filenum&GT; 03&LT; / lex_filenum&GT;&下;字lex_id =0&GT;实体下; /字GT;&下;指针参=n00001930 n00002137 n04424418&GT;下位词&下; /指针&GT;&下; DEF&GT;后者被认为或已知或推断有其独特的存在(活的或无生命的)下; / DEF&GT;&下; /同义词集&GT;&下; /同义词集&GT;&下; / DictionaryList&gt;中;
VAR字典= DictionaryList.LoadFromText(testXml); 的foreach(在dict.Dict VAR同义词集合)
{
VAR字= synSet.WordValues.ToList();
VAR WORD0 =(words.Count大于0字[0]:NULL);
VAR WORD2 =(words.Count→2字[2]:NULL);
//做的话的东西。
}更新2
要搜索包含特定单词
同义词集
,你可以这样做:VAR字=实体;
VAR结果= dict.Dict.Where(S = GT; s.WordValues.Any(W =&GT; W-- ==字)); //查找包含单词实体的所有同义词集
VAR结果= dict.Dict.FirstOrDefault(S = GT; s.WordValues.Any(W =&GT; W-- ==字)); //查找包含单词实体的第一个同义词集I have this XML file which have 3 Words.
<synset id="n00252662" type="n"> <lex_filenum>04</lex_filenum> <word lex_id="1">purge</word> <word lex_id="1">purging</word> <word lex_id="1">purgation</word> <pointer refs="n01247647">Hypernym</pointer> <pointer refs="v00905283" source="3" target="1">Derivationally related form</pointer> <pointer refs="v00475647" source="2" target="1">Derivationally related form</pointer> <pointer refs="v00475819" source="1" target="2">Derivationally related form</pointer> <pointer refs="v00905283" source="1" target="1">Derivationally related form</pointer> <pointer refs="n00252894">Hyponym</pointer> <def>the act of clearing yourself (or another) from some stigma or charge</def> </synset>
And DictionaryList.cs
using System.Collections.Generic; using System.Xml.Serialization; using System.Xml; using UnityEngine; using System.IO; [XmlRoot("DictionaryList")] public class DictionaryList { [XmlArray("synsets")] [XmlArrayItem("synset")] public List<Dictionary> Dict = new List<Dictionary>(); //string filepath = Application.dataPath + "/Resources/gamedata.xml"; public static DictionaryList Load(string path) { var serializer = new XmlSerializer(typeof(DictionaryList)); using (var stream = new FileStream(path, FileMode.Open)) { return serializer.Deserialize(stream) as DictionaryList; } } //Loads the xml directly from the given string. Useful in combination with www.text. public static DictionaryList LoadFromText(string text) { var serializer = new XmlSerializer(typeof(DictionaryList)); return serializer.Deserialize(new StringReader(text)) as DictionaryList; } }
Then The Dictionary.cs
using System.Xml; using System.Xml.Serialization; using System.Linq; using System.Collections; using System.Collections.Generic; public class Dictionary { public string word; public string def; public string example; public Dictionary() { } public Dictionary(string nme, string Des) { word = nme; def = Des; } }
In my Code, the deserializer does not Include the word purging and purgation since the word <- variable is not an Array.
I have tried to make it an array List but I am not sure if the the deserializer will even put the other words if I make an List array word to it.
Plus accessing the the List inside the list is giving me a problem. I want to know if there is an option I can take where I can access or even store the word as an array without altering the XML file.
And this is my main Dictionary file
using UnityEngine; using System.Collections; using System.Collections.Generic; using System.Xml; using System.Xml.Serialization; using System.IO; using System.Linq; using UnityEngine.UI; public class MainDictionary : MonoBehaviour { DictionaryList DictionaryCollectionNoun; DictionaryList DictionaryCollectionVerb; DictionaryList DictionaryCollectionADV; public InputField SearchField; public Text NameField; public Text DetailsField; public Text DebugText; public Text ExampleField; public TextAsset textAssetNoun; public TextAsset textAssetVerb; public TextAsset textAssetADV; // Use this for initialization void Start () { //TextAsset textAsset = (TextAsset)Resources.Load("datanoun", typeof(TextAsset)); //XmlDocument xmldoc = new XmlDocument (); //xmldoc.LoadXml ( textAsset.text ); DebugText.text = Application.dataPath; textAssetNoun = (TextAsset)Resources.Load("datanoun"); textAssetVerb = (TextAsset)Resources.Load("dataverb"); textAssetADV = (TextAsset)Resources.Load("dataadv"); //XmlDocument xmldoc = new XmlDocument(); //xmldoc.LoadXml(textAsset.text); //Example Psuedocode Danzee Mode; //var xmlData = @"<DictionaryList><synsets><synset><word>test</word><def>Fun</def></synset></synsets></DictionaryList>"; DictionaryCollectionNoun = DictionaryList.LoadFromText(textAssetNoun.text); DictionaryCollectionVerb = DictionaryList.LoadFromText(textAssetVerb.text); DictionaryCollectionADV = DictionaryList.LoadFromText(textAssetADV.text); //Debug.Log(Application.dataPath); //DebugText.text = xmldoc.ToString(); } public void ChangeSearch() { //Dictionary Result = new Dictionary("No Result", "No Description"); //bool nounBool = DictionaryCollectionNoun.Dict.Any(p => p.word == SearchField.text.ToLower()) ? true : false; //bool verbBool = DictionaryCollectionVerb.Dict.Any(p => p.word == SearchField.text.ToLower()) ? true : false; //bool advbool = DictionaryCollectionADV.Dict.Any(p => p.word == SearchField.text.ToLower()) ? true : false; //if (nounBool) //{ // Result = DictionaryCollectionNoun.Dict.Find(x => x.word == SearchField.text.ToLower()); //} //else if (verbBool) //{ // Result = DictionaryCollectionVerb.Dict.Find(x => x.word == SearchField.text.ToLower()); //} //else if (advbool) //{ // Result = DictionaryCollectionADV.Dict.Find(x => x.word == SearchField.text.ToLower()); //} //NameField.text = Result.word1; //DetailsField.text = Result.def2; //ExampleField.text = Result.example; }
}
解决方案Try the following:
public class Word { [XmlAttribute("lex_id")] public string LexId { get; set; } [XmlText] public string Value { get; set; } public override string ToString() { return Value; } public static explicit operator string(Word word) { if (word == null) return null; return word.Value; } } public class SynsetPointer { [XmlAttribute("refs")] public string Refs { get; set; } [XmlAttribute("source")] public string Source { get; set; } [XmlAttribute("target")] public string Target { get; set; } [XmlText] public string Value { get; set; } } [XmlRoot("synset")] [XmlType("synset")] public class Synset { public Synset() { this.Pointers = new List<SynsetPointer>(); this.Words = new List<Word>(); } [XmlElement("lex_filenum")] public int LexFilenum { get; set; } [XmlElement("word")] public List<Word> Words { get; set; } [XmlIgnore] public IEnumerable<string> WordValues { get { return (Words == null ? null : Words.Select(w => (string)w)); } } [XmlElement("pointer")] public List<SynsetPointer> Pointers { get; set; } [XmlElement("def")] public string Definition { get; set; } } [XmlRoot("DictionaryList")] public class DictionaryList { public DictionaryList() { this.Dict = new List<Synset>(); } [XmlArray("synsets")] [XmlArrayItem("synset")] public List<Synset> Dict { get; set; } //string filepath = Application.dataPath + "/Resources/gamedata.xml"; public static DictionaryList Load(string path) { var serializer = new XmlSerializer(typeof(DictionaryList)); using (var stream = new FileStream(path, FileMode.Open)) { return serializer.Deserialize(stream) as DictionaryList; } } //Loads the xml directly from the given string. Useful in combination with www.text. public static DictionaryList LoadFromText(string text) { var serializer = new XmlSerializer(typeof(DictionaryList)); return serializer.Deserialize(new StringReader(text)) as DictionaryList; } }
I renamed your
Dictionary
class toSynset
for clarity, since c# already has various dictionary classes which do something different.To read multiple
word
elements into an array, declare it as aList<Word>
in theSynset
class, then apply the[XmlElement]
attribute. This tells the serializer to expect repeated occurrences of theword
element rather than a nested list of elements.This will successfully read and write XML that looks like this:
<DictionaryList> <synsets> <synset> <lex_filenum>4</lex_filenum> <word lex_id="1">purge</word> <word lex_id="1">purging</word> <word lex_id="1">purgation</word> <pointer refs="n01247647">Hypernym</pointer> <pointer refs="v00905283" source="3" target="1">Derivationally related form</pointer> <pointer refs="v00475647" source="2" target="1">Derivationally related form</pointer> <pointer refs="v00475819" source="1" target="2">Derivationally related form</pointer> <pointer refs="v00905283" source="1" target="1">Derivationally related form</pointer> <pointer refs="n00252894">Hyponym</pointer> <def>the act of clearing yourself (or another) from some stigma or charge</def> </synset> </synsets> </DictionaryList>
Update
To loop through all the text values of all the
Word
classes in all theSynset
classes in aDictionaryList
, you can do:var testXml = @"<DictionaryList> <synsets> <synset id=""n00001740"" type=""n""> <lex_filenum>03</lex_filenum> <word lex_id=""0"">entity</word> <pointer refs=""n00001930 n00002137 n04424418"">Hyponym</pointer> <def>that which is perceived or known or inferred to have its own distinct existence (living or nonliving)</def> </synset> </synsets> </DictionaryList>"; var dict = DictionaryList.LoadFromText(testXml); foreach (var synSet in dict.Dict) { var words = synSet.WordValues.ToList(); var word0 = (words.Count > 0 ? words[0] : null); var word2 = (words.Count > 2 ? words[2] : null); // Do something with the words. }
Update 2
To search for a
Synset
containing a given word, you can do:var word = "entity"; var Results = dict.Dict.Where(s => s.WordValues.Any(w => w == word)); // Find all synsets containing the word "entity" var Result = dict.Dict.FirstOrDefault(s => s.WordValues.Any(w => w == word)); // Find the first synsets containing the word "entity"
这篇关于XML序列化和迭代的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!