2013-01-10 38 views
1

您好,我想用N多的動態,其中條件,我的解決方案..的LINQ to XML與動態n個有條件的地方

和我的情況我已經獲取所有的XML元素,所有必須包含數組(arrSearchContents)的所有元素,它是通過分割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"/> 

回答

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() 
+0

非常感謝。它真的幫助我即興編寫我的代碼... – pks

+0

@pks歡迎,順便說一句,如果所有'MDetails'元素具有'Desc'屬性,你可以省略'desc!= null'檢查。還要記住,默認情況下不帶參數的'String.Split()'按字串分割。如果答案爲你工作,你可以接受它:) –

+1

正確答案根據我的要求。 – pks

2

你應該檢查一下節點屬性包含價值,而不是老虎鉗詩句

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>(); 
} 
+0

順便說一句,你其實可以把條件轉換中的XPath:「// MDetails [包含(@Desc,{0}) ]「(其中{0}是您的搜索項) – Efrain

+0

是的,當然,但我不喜歡在LINQ to XML中創建長的XPath表達式。 XPath並不是很多開發者所熟知的,所以我只用它來指定DOM中的所有元素。否則由LINQ以靜態類型的方式完成。再次 - 在這裏可以有很多選擇。謝謝你的迴應 –

+0

是真的。實際上你的LINQ代碼讀起來確實很容易。 – Efrain