2013-11-12 1 views
3

У меня есть документ XML, который выглядит какLinq запрос, чтобы соответствовать строковые значения в 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; 
+0

Пожалуйста отправьте запрос LINQ вы уже пробовали – Amicable

+0

@ Применимо Я только что опубликовал несколько строк кодов, которые были перепрограммированы. –

+0

Не уверен, что это полезно, но с помощью этого алгоритма, если пользователь входит в «GRAPEFRUIT GRAPES», совпадения не будет найдено. То же самое для «НИЧЕГО ЯБЛОКА». Я бы ожидал, что APPLE ORANGE появится ... – oerkelens

ответ

2

Я хотел бы попробовать что-то вроде этого:

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: Не уверен, что если согласование должно быть префиксом строки поиска. Может быть, это еще что-то вроде этого:

 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(); 
1

Для ближайшего совпадения вам понадобится несколько conditins.

Например, var h = xdoc.Root.Elements("ingredient").FirstOrDefault(u => str.Contains(u.value)) - это условие, которое вернет более близкое значение в примере.

+0

Это был мой второй выбор кода –

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"); 
Смежные вопросы