Linq to XML with n number of dynamic where condition

时间:2013-01-10 11:23:22

标签: c# asp.net xml linq linq-to-xml

嗨我想在我的解决方案中使用 n个动态条件。

在我的场景中我将获取所有必须包含数组(arrSearchContents)的所有xml元素,这些元素是通过拆分strSearchContent的所有单词构建的。

<Mobiles>
  <Mobile Id="1">
    <MDetails ModelNo="1" Desc="x phone color red"/>
    <MDetails ModelNo="2" Desc="x phone color green"/>
    <MDetails ModelNo="3" Desc="x phone color blue"/>
    <MDetails ModelNo="4" Desc="x phone color black"/>
    <MDetails ModelNo="5" Desc="x phone color yellow"/>
    <MDetails ModelNo="6" Desc="x phone color pink"/>
    <MDetails ModelNo="7" Desc="x phone color gray"/>
    <MDetails ModelNo="8" Desc="x phone color silver"/>
    <MDetails ModelNo="9" Desc="x phone color orange"/>
  </Mobile>
  <Mobile Id="2">
    <MDetails ModelNo="11" Desc="y phone color red"/>
    <MDetails ModelNo="12" Desc="y phone color green"/>
    <MDetails ModelNo="13" Desc="y phone color blue"/>
    <MDetails ModelNo="14" Desc="y phone color black"/>
    <MDetails ModelNo="15" Desc="y phone color yellow"/>
    <MDetails ModelNo="16" Desc="y phone color pink"/>
    <MDetails ModelNo="17" Desc="y phone color gray"/>
    <MDetails ModelNo="18" Desc="y phone color silver"/>
    <MDetails ModelNo="19" Desc="y phone color orange"/>
  </Mobile>
  <Mobile Id="3">
  ......
  <Mobile>
  ......
</Mobiles>

我想要一个像波纹管代码一样的解决方案。 任何机构都可以 纠正 代码

public void doSearch(string strSearchContent)
{
string[] arrSearchContents;
arrSearchContents = strSearchContent.Split(' ');

string fileName = HttpContext.Current.Server.MapPath(@"~\XMLFiles/Mobile.xml");
XDocument doc = null;
    if (System.IO.File.Exists(fileName))
    {
        doc = XDocument.Load(fileName);

        IEnumerable<XElement> list1 =
            from elements in doc.Descendants("MDetails")
            where
                for(int i=0;i<arrSearchContents.Length;i++)
                {
                    elements.Attribute("Desc").Value.Contains(arrSearchContents[i]) &&
                }
            select elements;
    }
}

所选列表应包含搜索字符串的所有关键字。

as per example : if strSearchContent = "phone color blue"

then as a result it should return :

<MDetails ModelNo="3" Desc="x phone color blue"/>
<MDetails ModelNo="13" Desc="y phone color blue"/>

2 个答案:

答案 0 :(得分:4)

from d in doc.Descendants("MDetails")
let desc = (string)d.Attribute("Desc")
where desc != null && 
      arrSearchContents.All(keyword => desc.Contains(keyword))
select d;

但它也会匹配“bluephonecolor”。如果要匹配单词,可以使用正则表达式,或者按单词拆分说明:

!arrSearchContents.Except(desc.Split()).Any()

答案 1 :(得分:2)

您应该检查节点属性是否包含值,而不是vise-verse

var str = @"<Mobiles>
                    <Mobile Id=""1"">
                        <MDetails ModelNo=""1"" Desc=""x phone color red""/>
                        <MDetails ModelNo=""2"" Desc=""x phone color green""/>
                        <MDetails ModelNo=""3"" Desc=""x phone color blue""/>
                        <MDetails ModelNo=""4"" Desc=""x phone color black""/>
                        <MDetails ModelNo=""5"" Desc=""x phone color yellow""/>
                        <MDetails ModelNo=""6"" Desc=""x phone color pink""/>
                        <MDetails ModelNo=""7"" Desc=""x phone color gray""/>
                        <MDetails ModelNo=""8"" Desc=""x phone color silver""/>
                        <MDetails ModelNo=""9"" Desc=""x phone color orange""/>
                    </Mobile>
                    <Mobile Id=""2"">
                        <MDetails ModelNo=""11"" Desc=""y phone color red""/>
                        <MDetails ModelNo=""12"" Desc=""y phone color green""/>
                        <MDetails ModelNo=""13"" Desc=""y phone color blue""/>
                        <MDetails ModelNo=""14"" Desc=""y phone color black""/>
                        <MDetails ModelNo=""15"" Desc=""y phone color yellow""/>
                        <MDetails ModelNo=""16"" Desc=""y phone color pink""/>
                        <MDetails ModelNo=""17"" Desc=""y phone color gray""/>
                        <MDetails ModelNo=""18"" Desc=""y phone color silver""/>
                        <MDetails ModelNo=""19"" Desc=""y phone color orange""/>
                    </Mobile></Mobiles>";

    var doc = XDocument.Parse(str);
    var strSearchContent = "phone color blue";
    IEnumerable<XElement> list1 = doc.XPathSelectElements("//MDetails")
                                     .Where(node => node.Attribute("Desc").Value.Contains(strSearchContent));

    //LinqPad specific print call
    list1.Dump();

打印

<MDetails ModelNo="3" Desc="x phone color blue" /> 
<MDetails ModelNo="13" Desc="y phone color blue" /> 

因此生成的代码将如下所示(请注意,我已经更改了方法的返回类型):

public IEnumerable<XElement> doSearch(string strSearchContent)
{
    string fileName = HttpContext.Current.Server.MapPath(@"~\XMLFiles/Mobile.xml");

    if (File.Exists(fileName))
    {
        XDocument doc = XDocument.Load(fileName);
        return doc.XPathSelectElements("//MDetails")
                  .Where(node => node.Attribute("Desc").Value.Contains(strSearchContent));
    }

    return Enumerable.Empty<XElement>();
}