Linq to XML with where in clause with one or many keywords

Linq to XML with where in clause with one or many keywords

我有以下 XML 文件...

    <?xml version="1.0" encoding="utf-8"?>
<photosettings>
    <rootdirectory>c:\phototool\photos\</rootdirectory>
    <photos>
        <photo photographer="Susan Hunter" description="beach scene" folder="beach" name="21562313421.jpg">
            <keywords>
                <keyword>beach</keyword>
                <keyword>sand</keyword>
                <keyword>shells</keyword>
            </keywords>
        </photo>
        <photo photographer="John Smith" description="Beach sunset" folder="beach" name="14123124213.jpg">
            <keywords>
                <keyword>beach</keyword>
                <keyword>sand</keyword>
                <keyword>shells</keyword>
                <keyword>sunset</keyword>
            </keywords>
        </photo>
        <photo photographer="Julie Neuber" description="Overcomming Obstacle" folder="motivation" name="123423413.jpg">
            <keywords>
                <keyword>beach</keyword>
                <keyword>shells</keyword>
            </keywords>
        </photo>
    </photos>
</photosettings>

我想根据关键字搜索来查询 XML,我让它对单个关键字有效...

 using System;
using System.Linq;
using System.Xml.Linq;

class Program
{
    public static void Main(String[] args)
    {
        String strPath = @"C:\phototool\photos.xml";
        XDocument doc = XDocument.Load(strPath);

        var pquery = from p in doc.Descendants("photo")
                     where p.Elements("keywords")
                            .Elements("keyword").Select(k => k.Value).ToArray().Contains("sand")
                     select new
                         {
                             photographer = (string)p.Attribute("photographer"),
                             description = (string)p.Attribute("description"),
                             folder = (string)p.Attribute("folder"),
                             filename = (string)p.Attribute("name"),
                             lstrKeywords = p.Elements("keywords").Elements("keyword").Select(i => i.Value).ToList(),
                         };

        foreach (var p in pquery)
        {
            Console.WriteLine("photographer = {0}, descrption = {1} folder = {2} filename = {3} keywords = {4}", p.photographer, p.description, p.folder, p.filename, String.Join(", ", p.lstrKeywords));
        }
        Console.WriteLine("Press <enter> to continue");
        Console.ReadLine();
    }
}

我想弄清楚如何搜索多个关键字。其实我不知道用户会搜索多少关键字

我想查询 return 个包含关键字 1 和关键字 2 的节点。

类似这样的东西(非工作示例)...

   .Elements("keyword").Select(k => k.Value).ToArray().Contains("sand", "beach")

谢谢,

试试这个

XDocument doc = XDocument.Load(Server.MapPath("XMLFile.xml"));
List<string> word = new List<string>() { "sand", "beach" };
var list = doc.Root.Elements("photos").Elements("photo").Elements("keywords").Elements("keyword").Where(x => (word.Contains(x.Value))).Select(x => new { PhotoGrapher = x.Parent.Parent.Attribute("photographer"), description = x.Parent.Parent.Attribute("description"), keyword = x.Parent.Elements("keyword").Select(i=>i.Value).ToList() }).ToList();

foreach(var item in list)
{
var PhotoGrapher = item.PhotoGrapher;
//Get other properties you want
}

我刚刚 select编辑 photographer description and keywords 你也可以 select 其他属性。

我明白了。

关键是将字符串(关键字)列表放入 for each 循环中,并为每个关键字应用 .Where 过滤器。

这是代码...

using System;
using System.Linq;
using System.Xml.Linq;
using System.Collections.Generic;
class Program
{
    public static void Main(String[] args)
    {
        String strPath = @"C:\phototool\photos.xml";
        XDocument doc = XDocument.Load(strPath);
        List<string> lstrKeywords = new List<string>();
        lstrKeywords.Add("beach");
        lstrKeywords.Add("sunset");

        var pquery = from p in doc.Descendants("photo")
                     select p;

        foreach (string str in lstrKeywords)
        {
            pquery = pquery.Where(i => i.Elements("keywords").Elements("keyword").Select(k => k.Value).ToArray().Contains(str));
        }    
        var pqueryII = from p in pquery
                       select new
                           {
                               photographer = (string) p.Attribute("photographer"),
                               description = (string) p.Attribute("description"),
                               folder = (string) p.Attribute("folder"),
                               filename = (string) p.Attribute("name"),
                               lstrKeywords = p.Elements("keywords").Elements("keyword").Select(i => i.Value).ToList(),
                           };
        foreach (var p in pqueryII)
        {
            Console.WriteLine("photographer = {0}, descrption = {1} folder = {2} filename = {3} keywords = {4}", p.photographer, p.description, p.folder, p.filename, String.Join(", ", p.lstrKeywords));
        }
        Console.WriteLine("Press <enter> to continue");
        Console.ReadLine();
    }
}

收集您要测试的术语并过滤掉不包含所有术语的项目。

var searchTerms = new[] { "sand", "beach" };
var query =
    from p in doc.Descendants("photo")
    select new
    {
        Photographer = (string)p.Attribute("photographer"),
        Description = (string)p.Attribute("description"),
        Folder = (string)p.Attribute("folder"),
        Filename = (string)p.Attribute("name"),
        Keywords = p.Descendants("keyword").Select(k => (string)k).ToList(),
    } into x
    where searchTerms.All(t => x.Keywords.Contains(t))
    select x;