Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从包含一些嵌入数据的XML文档中填充C#类?_C#_Asp.net_Xml - Fatal编程技术网

如何从包含一些嵌入数据的XML文档中填充C#类?

如何从包含一些嵌入数据的XML文档中填充C#类?,c#,asp.net,xml,C#,Asp.net,Xml,我有一个API返回了以下内容: 我想将XML中的数据提取到一个列表中,其中定义类如下所示: public class Def { public string text { get; set; } public List<string> synonym { get; set; } } public class Definition { public string type { get; set; } // single character: n or v o

我有一个API返回了以下内容:

我想将XML中的数据提取到一个列表中,其中定义类如下所示:

public class Def
{
    public string text { get; set; }
    public List<string> synonym { get; set; }
}

public class Definition
{
    public string type { get; set; } // single character: n or v or a 
    public List<Def> Def { get; set; }
}
公共类定义
{
公共字符串文本{get;set;}
公共列表同义词{get;set;}
}
公共类定义
{
公共字符串类型{get;set;}//单个字符:n或v或a
公共列表Def{get;set;}
}
有没有人能给我一些建议,告诉我如何做,并告诉我有哪些选项可以从XML中选择类元素并将它们放入类中

因为我认为这个问题可能对其他很多人有所帮助,所以我将宣布一个大悬赏,希望有人能抽出时间拿出一个好的例子

更新:


对不起。我在同义词上犯了一个错误。我现在已经改变了。希望它更有意义。同义词只是一个列表,我也用粗体写下了我需要的东西,因为到目前为止,这两个答案似乎根本无法回答这个问题。谢谢。

为什么要手工制作?让我们自动完成所有事情,因为我们是程序员

在项目上单击鼠标右键,选择“添加服务参考”

放入地址字段。
设置所需的命名空间。
您还可以通过单击“高级”按钮指定其他设置。
点击Ok按钮

将生成一组用于服务的类。
然后只使用这些类

请注意,在应用程序的App.config或Web.config中会显示使用该服务所需的设置。接下来我们使用它们

使用这些类的示例(不要忘记指定要使用的命名空间):

就这些

DictServiceSoapClient
构造函数中,我们从用于绑定的配置中指定名称

wordDefinition
中,我们有一个请求结果。 让我们从中获取信息:

Console.WriteLine(wordDefinition.Word);
Console.WriteLine();

foreach (var definition in wordDefinition.Definitions)
{
    Console.WriteLine("Word: " + definition.Word);
    Console.WriteLine("Word Definition: " + definition.WordDefinition);

    Console.WriteLine("Id: " + definition.Dictionary.Id);
    Console.WriteLine("Name: " + definition.Dictionary.Name);
}

Alexander Petrov的答案非常适合您,只是您正在处理一个不可靠的xml模式。 如果WordNet是一个真正的工具,他们应该修改模式以删除嵌套的WordDefinition元素 并为基本定义部分添加新元素

此快速解决方案适用于您提供的特定测试用例,但它依赖于许多假设 关于文本的性质。它还使用字符串操作和正则表达式,这些都是需要考虑的 效率低下,因此可能对您的需求来说速度太慢且容易出错。您可能会收到更好的解决方案 对于此任务,如果您将问题定制为字符串操作问题域。但正确的解决方案 是为了获得更好的xml模式

using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using System.Xml;

namespace DefinitionTest
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Definition> definitions = new List<Definition>();

            // The starting point after your web service call.
            string responseFromServer = EmulateWebService();

            // Load the string into this object in order to parse the xml.
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(responseFromServer);

            XmlNode root = doc.DocumentElement.ParentNode;

            XmlNodeList elemList = doc.GetElementsByTagName("WordDefinition");
            for (int i = 0; i < elemList.Count; i++)
            {
                XmlNode def = elemList[i];

                // We only want WordDefinition elements that have just one child which is the content we need.
                // Any WordDefinition that has zero children or more than one child is either empty or a parent element.
                if (def.ChildNodes.Count == 1)
                {
                    Console.WriteLine(string.Format("Content of WordDefinition {0}", i));
                    Console.WriteLine();
                    Console.WriteLine(def.InnerXml);
                    Console.WriteLine();

                    definitions.Add(ParseWordDefinition(def.InnerXml));

                    foreach (Definition dd in definitions)
                    {
                        Console.WriteLine(string.Format("Parsed Word Definition for \"{0}\"", dd.wordDefined));
                        Console.WriteLine();
                        foreach (Def d in dd.Defs)
                        {
                            string type = string.Empty;
                            switch (d.type)
                            {
                                case "a":
                                    type = "Adjective";
                                    break;
                                case "n":
                                    type = "Noun";
                                    break;
                                case "v":
                                    type = "Verb";
                                    break;
                                default:
                                    type = "";
                                    break;
                            }
                            Console.WriteLine(string.Format("Type \"{0}\"", type));
                            Console.WriteLine();
                            Console.WriteLine(string.Format("\tDefinition \"{0}\"", d.text));
                            Console.WriteLine();
                            if (d.Synonym != null && d.Synonym.Count > 0)
                            {
                                Console.WriteLine("\tSynonyms");
                                foreach (string syn in d.Synonym)
                                    Console.WriteLine("\t\t" + syn);
                            }
                        }
                    }
                }
            }
        }

        static string EmulateWebService()
        {
            string result = string.Empty;

            // The "definition.xml"file is a copy of the test data you provided.
            using (StreamReader reader = new StreamReader(@"c:\projects\definitiontest\definitiontest\definition.xml"))
            {
                result = reader.ReadToEnd();
            }
            return result;
        }

        static Definition ParseWordDefinition(string xmlDef)
        {
            // Replace any carriage return/line feed characters with spaces.
            string oneLine = xmlDef.Replace(System.Environment.NewLine, " ");

            // Squeeze internal white space.
            string squeezedLine = Regex.Replace(oneLine, @"\s{2,}", " ");

            // Assumption 1: The first word in the string is always the word being defined.
            string[] wordAndDefs = squeezedLine.Split(new char[] { ' ' }, StringSplitOptions.None);
            string wordDefined = wordAndDefs[0];
            string allDefinitions = string.Join(" ", wordAndDefs, 1, wordAndDefs.Length - 1);

            Definition parsedDefinition = new Definition();
            parsedDefinition.wordDefined = wordDefined;
            parsedDefinition.Defs = new List<Def>();

            string type = string.Empty;

            // Assumption 2: All definitions are delimited by a type letter, a number and a ':' character.
            string[] subDefinitions = Regex.Split(allDefinitions, @"(n|v|a){0,1}\s\d{1,}:");
            foreach (string definitionPart in subDefinitions)
            {
                if (string.IsNullOrEmpty(definitionPart))
                    continue;

                if (definitionPart == "n" || definitionPart == "v" || definitionPart == "a")
                {
                    type = definitionPart;
                }
                else
                {
                    Def def = new Def();
                    def.type = type;

                    // Assumption 3. Synonyms always use the [syn: {..},... ] pattern.
                    string realDef = (Regex.Split(definitionPart, @"\[\s*syn:"))[0];
                    def.text = realDef;

                    MatchCollection syns = Regex.Matches(definitionPart, @"\{([a-zA-Z\s]{1,})\}");
                    if (syns.Count > 0)
                        def.Synonym = new List<string>();

                    foreach (Match match in syns)
                    {
                        string s = match.Groups[0].Value;
                        // A little problem with regex retaining braces, so
                        // remove them here.
                        def.Synonym.Add(s.Replace('{', ' ').Replace('}', ' ').Trim());
                        int y = 0;
                    }
                    parsedDefinition.Defs.Add(def);
                }
            }
            return parsedDefinition;
        }
    }

    public class Def
    {
        // Moved your type from Definition to Def, since it made more sense to me.
        public string type { get; set; } // single character: n or v or a 
        public string text { get; set; }
        // Changed your synonym definition here.
        public List<string> Synonym { get; set; }
    }

    public class Definition
    {
        public string wordDefined { get; set; }
        // Changed Def to Defs.
        public List<Def> Defs { get; set; }
    }
}
使用系统;
使用System.Collections.Generic;
使用System.IO;
使用System.Text.RegularExpressions;
使用System.Xml;
名称空间定义测试
{
班级计划
{
静态void Main(字符串[]参数)
{
列表定义=新列表();
//web服务调用后的起点。
字符串responseFromServer=EmulateWebService();
//将字符串加载到此对象中以解析xml。
XmlDocument doc=新的XmlDocument();
doc.LoadXml(responseFromServer);
XmlNode root=doc.DocumentElement.ParentNode;
XmlNodeList elemList=doc.GetElementsByTagName(“WordDefinition”);
for(int i=0;i0)
{
Console.WriteLine(“\tSynonyms”);
foreach(d.Synonym中的字符串syn)
Console.WriteLine(“\t\t”+syn);
}
}
}
}
}
}
静态字符串仿真服务()
{
字符串结果=string.Empty;
//“definition.xml”文件是一个副本
var client = new DictServiceSoapClient("DictServiceSoap");
var wordDefinition = client.DefineInDict("wn", "abandon");
Console.WriteLine(wordDefinition.Word);
Console.WriteLine();

foreach (var definition in wordDefinition.Definitions)
{
    Console.WriteLine("Word: " + definition.Word);
    Console.WriteLine("Word Definition: " + definition.WordDefinition);

    Console.WriteLine("Id: " + definition.Dictionary.Id);
    Console.WriteLine("Name: " + definition.Dictionary.Name);
}
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using System.Xml;

namespace DefinitionTest
{
    class Program
    {
        static void Main(string[] args)
        {
            List<Definition> definitions = new List<Definition>();

            // The starting point after your web service call.
            string responseFromServer = EmulateWebService();

            // Load the string into this object in order to parse the xml.
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(responseFromServer);

            XmlNode root = doc.DocumentElement.ParentNode;

            XmlNodeList elemList = doc.GetElementsByTagName("WordDefinition");
            for (int i = 0; i < elemList.Count; i++)
            {
                XmlNode def = elemList[i];

                // We only want WordDefinition elements that have just one child which is the content we need.
                // Any WordDefinition that has zero children or more than one child is either empty or a parent element.
                if (def.ChildNodes.Count == 1)
                {
                    Console.WriteLine(string.Format("Content of WordDefinition {0}", i));
                    Console.WriteLine();
                    Console.WriteLine(def.InnerXml);
                    Console.WriteLine();

                    definitions.Add(ParseWordDefinition(def.InnerXml));

                    foreach (Definition dd in definitions)
                    {
                        Console.WriteLine(string.Format("Parsed Word Definition for \"{0}\"", dd.wordDefined));
                        Console.WriteLine();
                        foreach (Def d in dd.Defs)
                        {
                            string type = string.Empty;
                            switch (d.type)
                            {
                                case "a":
                                    type = "Adjective";
                                    break;
                                case "n":
                                    type = "Noun";
                                    break;
                                case "v":
                                    type = "Verb";
                                    break;
                                default:
                                    type = "";
                                    break;
                            }
                            Console.WriteLine(string.Format("Type \"{0}\"", type));
                            Console.WriteLine();
                            Console.WriteLine(string.Format("\tDefinition \"{0}\"", d.text));
                            Console.WriteLine();
                            if (d.Synonym != null && d.Synonym.Count > 0)
                            {
                                Console.WriteLine("\tSynonyms");
                                foreach (string syn in d.Synonym)
                                    Console.WriteLine("\t\t" + syn);
                            }
                        }
                    }
                }
            }
        }

        static string EmulateWebService()
        {
            string result = string.Empty;

            // The "definition.xml"file is a copy of the test data you provided.
            using (StreamReader reader = new StreamReader(@"c:\projects\definitiontest\definitiontest\definition.xml"))
            {
                result = reader.ReadToEnd();
            }
            return result;
        }

        static Definition ParseWordDefinition(string xmlDef)
        {
            // Replace any carriage return/line feed characters with spaces.
            string oneLine = xmlDef.Replace(System.Environment.NewLine, " ");

            // Squeeze internal white space.
            string squeezedLine = Regex.Replace(oneLine, @"\s{2,}", " ");

            // Assumption 1: The first word in the string is always the word being defined.
            string[] wordAndDefs = squeezedLine.Split(new char[] { ' ' }, StringSplitOptions.None);
            string wordDefined = wordAndDefs[0];
            string allDefinitions = string.Join(" ", wordAndDefs, 1, wordAndDefs.Length - 1);

            Definition parsedDefinition = new Definition();
            parsedDefinition.wordDefined = wordDefined;
            parsedDefinition.Defs = new List<Def>();

            string type = string.Empty;

            // Assumption 2: All definitions are delimited by a type letter, a number and a ':' character.
            string[] subDefinitions = Regex.Split(allDefinitions, @"(n|v|a){0,1}\s\d{1,}:");
            foreach (string definitionPart in subDefinitions)
            {
                if (string.IsNullOrEmpty(definitionPart))
                    continue;

                if (definitionPart == "n" || definitionPart == "v" || definitionPart == "a")
                {
                    type = definitionPart;
                }
                else
                {
                    Def def = new Def();
                    def.type = type;

                    // Assumption 3. Synonyms always use the [syn: {..},... ] pattern.
                    string realDef = (Regex.Split(definitionPart, @"\[\s*syn:"))[0];
                    def.text = realDef;

                    MatchCollection syns = Regex.Matches(definitionPart, @"\{([a-zA-Z\s]{1,})\}");
                    if (syns.Count > 0)
                        def.Synonym = new List<string>();

                    foreach (Match match in syns)
                    {
                        string s = match.Groups[0].Value;
                        // A little problem with regex retaining braces, so
                        // remove them here.
                        def.Synonym.Add(s.Replace('{', ' ').Replace('}', ' ').Trim());
                        int y = 0;
                    }
                    parsedDefinition.Defs.Add(def);
                }
            }
            return parsedDefinition;
        }
    }

    public class Def
    {
        // Moved your type from Definition to Def, since it made more sense to me.
        public string type { get; set; } // single character: n or v or a 
        public string text { get; set; }
        // Changed your synonym definition here.
        public List<string> Synonym { get; set; }
    }

    public class Definition
    {
        public string wordDefined { get; set; }
        // Changed Def to Defs.
        public List<Def> Defs { get; set; }
    }
}
class ParseyMcParseface
{
    /// <summary>
    /// Word definition lines
    /// </summary>
    private string[] _text;

    /// <summary>
    /// Constructor (Takes the innerText of the WordDefinition tag as input
    /// </summary>
    /// <param name="text">innerText of the WordDefinition</param>
    public ParseyMcParseface(string text)
    {
        _text = text.Split(new [] {'\n'}, StringSplitOptions.RemoveEmptyEntries)
            .Skip(1) // Skip the first line where the word is mentioned
            .ToArray();
    }

    /// <summary>
    /// Convert from single letter type to full human readable type
    /// </summary>
    /// <param name="c"></param>
    /// <returns></returns>
    private string CharToType(char c)
    {
        switch (c)
        {
            case 'a':
                return "Adjective";
            case 'n':
                return "Noun";
            case 'v':
                return "Verb";
            default:
                return "Unknown";
        }
    }

    /// <summary>
    /// Reorganize the data for easier parsing
    /// </summary>
    /// <param name="text">Lines of text</param>
    /// <returns></returns>
    private static List<List<string>> MakeLists(IEnumerable<string> text)
    {
        List<List<string>> types = new List<List<string>>();
        int i = -1;
        int j = 0;
        foreach (var line in text)
        {
            // New type (Noun, Verb, Adj.)
            if (Regex.IsMatch(line.Trim(), "^[avn]{1}\\ \\d+"))
            {
                types.Add(new List<string> { line.Trim() });
                i++;
                j = 0;
            }
            // New definition in the previous type
            else if (Regex.IsMatch(line.Trim(), "^\\d+"))
            {
                j++;
                types[i].Add(line.Trim());
            }
            // New line of the same definition
            else
            {
                types[i][j] = types[i][j] + " " + line.Trim();
            }
        }

        return types;
    }

    public List<Definition> Parse()
    {
        var definitionsLines = MakeLists(_text);

        List<Definition> definitions = new List<Definition>();

        foreach (var type in definitionsLines)
        {

            var defs = new List<Def>();
            foreach (var def in type)
            {
                var match = Regex.Match(def.Trim(), "(?:\\:\\ )(\\w|\\ |;|\"|,|\\.|-)*[\\[]{0,1}");
                MatchCollection syns = Regex.Matches(def.Trim(), "\\{(\\w|\\ )+\\}");

                List<string> synonymes = new List<string>();
                foreach (Match syn in syns)
                {
                    synonymes.Add(syn.Value.Trim('{', '}'));
                }

                defs.Add(new Def()
                {
                    text = match.Value.Trim(':', '[', ' '),
                    synonym = synonymes
                });
            }


            definitions.Add(new Definition
            {
                type = CharToType(type[0][0]),
                Def = defs
            });
        }
        return definitions;
    }
}
WebRequest request = 
WebRequest.Create("http://services.aonaware.com/DictService/DictService.asmx/DefineInDict");
request.Method = "POST";
string postData = "dictId=wn&word=abandon";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = byteArray.Length;
Stream dataStream = request.GetRequestStream();
dataStream.Write(byteArray, 0, byteArray.Length);
dataStream.Close();
WebResponse response = request.GetResponse();
Console.WriteLine(((HttpWebResponse)response).StatusDescription);
dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string responseFromServer = reader.ReadToEnd();


var doc = new XmlDocument();
doc.LoadXml(responseFromServer );
var el = doc.GetElementsByTagName("WordDefinition");

ParseyMcParseface parseyMcParseface = new ParseyMcParseface(el[1].InnerText);
var parsingResult = parseyMcParseface.Parse();
// parsingResult will contain a list of Definitions
// per the format specified in the question.
public enum WordTypes
{
    Noun,
    Verb,
    Adjective,
    Adverb,
    Unknown
}

public class Definition
{
    public Definition()
    {
        Synonyms = new List<string>();
        Anotnyms = new List<string>();
    }
    public WordTypes WordType { get; set; }
    public string DefinitionText { get; set; }
    public List<string> Synonyms { get; set; }
    public List<string> Anotnyms { get; set; }

}

static class DefinitionParser
{
    public static List<Definition> Parse(string wordDefinition)
    {
        var wordDefinitionLines = wordDefinition.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries)
            .Skip(1)
            .Select(x => x.Trim())
            .ToList();

        var flatenedList = MakeLists(wordDefinitionLines).SelectMany(x => x).ToList();

        var result = new List<Definition>();
        foreach (var wd in flatenedList)
        {
            var foundMatch = Regex.Match(wd, @"^(?<matchType>adv|adj|v|n){0,1}\s*(\d*): (?<definition>[\w\s;""',\.\(\)\!\-]+)(?<extraInfoSyns>\[syn: ((?<wordSyn>\{[\w\s\-]+\})|(?:[,\ ]))*\]){0,1}\s*(?<extraInfoAnts>\[ant: ((?<wordAnt>\{[\w\s-]+\})|(?:[,\ ]))*\]){0,1}");

            var def = new Definition();

            if (foundMatch.Groups["matchType"].Success)
            {
                var matchType = foundMatch.Groups["matchType"];
                def.WordType = DefinitionTypeToEnum(matchType.Value);
            }

            if (foundMatch.Groups["definition"].Success)
            {
                var definition = foundMatch.Groups["definition"];
                def.DefinitionText = definition.Value;
            }

            if (foundMatch.Groups["extraInfoSyns"].Success && foundMatch.Groups["wordSyn"].Success)
            {
                foreach (Capture capture in foundMatch.Groups["wordSyn"].Captures)
                {
                    def.Synonyms.Add(capture.Value.Trim('{','}'));
                }
            }

            if (foundMatch.Groups["extraInfoAnts"].Success && foundMatch.Groups["wordAnt"].Success)
            {
                foreach (Capture capture in foundMatch.Groups["wordAnt"].Captures)
                {
                    def.Anotnyms.Add(capture.Value.Trim('{', '}'));
                }
            }

            result.Add(def);
        }
        return result;
    }

    private static List<List<string>> MakeLists(IEnumerable<string> text)
    {
        List<List<string>> types = new List<List<string>>();
        int i = -1;
        int j = 0;
        foreach (var line in text)
        {
            // New type (Noun, Verb, Adj.)
            if (Regex.IsMatch(line, "^(adj|v|n|adv){1}\\s\\d*"))
            {
                types.Add(new List<string> { line });
                i++;
                j = 0;
            }
            // New definition in the previous type
            else if (Regex.IsMatch(line, "^\\d+"))
            {
                j++;
                types[i].Add(line);
            }
            // New line of the same definition
            else
            {
                types[i][j] = types[i][j] + " " + line;
            }
        }

        return types;
    }

    private static WordTypes DefinitionTypeToEnum(string input)
    {
        switch (input)
        {
            case "adj":
                return WordTypes.Adjective;
            case "adv":
                return WordTypes.Adverb;
            case "n":
                return WordTypes.Noun;
            case "v":
                return WordTypes.Verb;
            default:
                return WordTypes.Unknown;
        }
    }
}