XML序列化和迭代 [英] XML Serialization and iterating

查看:180
本文介绍了XML序列化和迭代的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个有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> Derivati​​onally相关表格和LT; /指针>
  <指针裁判=v00475647来源=2TARGET =1> Derivati​​onally相关表格和LT; /指针>
  <指针裁判=v00475819来源=1目标=2> Derivati​​onally相关表格和LT; /指针>
  <指针裁判=v00905283来源=1目标=1> Derivati​​onally相关表格和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#已经有各种的词典类它做不同的事情

要多读元素融入到一个数组,声明为列表&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; D​​ictionaryList&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; Derivati​​onally相关表格和LT; /指针&GT;
            &LT;指针裁判=v00475647来源=2TARGET =1&GT; Derivati​​onally相关表格和LT; /指针&GT;
            &LT;指针裁判=v00475819来源=1目标=2&GT; Derivati​​onally相关表格和LT; /指针&GT;
            &LT;指针裁判=v00905283来源=1目标=1&GT; Derivati​​onally相关表格和LT; /指针&GT;
            &LT;指针裁判=n00252894&GT;下位词&LT; /指针&GT;
            &LT;高清&GT;一些柱头或费及结算LT自己(或他人)的行为; / DEF&GT;
        &LT; /同义词集&GT;
    &LT; /同义词集&GT;
&LT; / DictionaryList&GT;


更新

要通过所有的同义词集类所有的类的所有文本值在一个循环 DictionaryList ,你可以这样做:

  VAR testXml = @&LT; D​​ictionaryList&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 to Synset for clarity, since c# already has various dictionary classes which do something different.

To read multiple word elements into an array, declare it as a List<Word> in the Synset class, then apply the [XmlElement] attribute. This tells the serializer to expect repeated occurrences of the word 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 the Synset classes in a DictionaryList, 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆