3

我有一个看起来像的 XML 文档

<recipes>
<ingredient value"1">APPLE</ingredient>
<ingredient value"2">BANANA</ingredient>
<ingredient value"3">APPLE ORANGE</ingredient>
<ingredient value"4">APPLE BANANA</ingredient>
<ingredient value"5">APPLE STRAWBERRY</ingredient>
<ingredient value"6">GRAPES</ingredient>
</recipes>

现在用户输入一些字符串,例如Apple Grapes Banana。我按字母顺序对其进行排序,并尝试通过使用字符串操作递归地消除最后一个单词来将其与其中一个值匹配。但我确信在 Linq 中有一种更有效的方法可以做到这一点。我希望查询返回 XML 中最接近的匹配项<ingredient value"4">APPLE BANANA</ingredient>

string str = "APPLE BANANA GRAPES"; // user input arranged by ascending alphabet and capitalized
XDocument xdoc = XDocument.Load(above xml);// gets above xml
var h = xdoc.Root.Elements("ingredient").FirstOrDefault(u => u.Value == str);//recurse these steps
if (h == null)
{
str = str.Remove(str.LastIndexOf(" "));//recurse these steps
}
//check if str matches any value;
//if not remove last word from str and check again;
4

3 回答 3

2

I would try something like this :

    string str = "APPLE BANANA GRAPES";

    String[] criterias = str.Split(' ');

    XDocument x = XDocument.Parse(yourXmlString);
    var result =
        x.Root.Elements()
         // count # of matches for each element
         .Select(e => new {e, num = criterias.Count(c => e.Value.Contains(c))}) 
         // order by # of matches, then alphabetically
         .OrderByDescending(r => r.num).ThenBy(r => r.e.Value)
         // get a combination e: XElement, num: # of matches
         .FirstOrDefault();

Edit : Not sure if the matching should be a prefix of the search string. Maybe it is more something like this :

        var result =
            x.Root.Elements()
             // get prefixes
             .Where(e => str.StartsWith(e.Value))
             // count matchings
             .Select(e=>new {e, num=e.Value.Split(' ').Length})
             // get max matchings
             .OrderByDescending(r => r.num).ThenBy(r => r.e.Value)
             .FirstOrDefault();
于 2013-11-12T15:06:20.307 回答
1

我有一个简单的递归要介绍

    public string FindValueFromText(XDocument xdoc, string str)
    {
        while (str != "")
        {
            var h = xdoc.Root.Elements("ingredient").FirstOrDefault(u => u.Value == str);
            if (h == null)
            {
                str = str.Remove(str.LastIndexOf(" "));
                FindValueFromText(xdoc, str); //recursive
            }
            else 
            {
                return h.Attribute("value").Value;
            }
        }
        return "Not found value";
    }

在您要调用上述方法的位置添加这些行

XDocument xDoc = XDocument.Load(xmlFilePath);
string value = FindValueFromText(xDoc, "APPLE BANANA GRAPES");
于 2013-11-12T15:09:26.410 回答
1

您需要多个条件才能在此处进行最接近的匹配。

例如 var h = xdoc.Root.Elements("ingredient").FirstOrDefault(u => str.Contains(u.value)) ,在示例中将返回一个更接近的值的条件。

于 2013-11-12T15:03:03.363 回答