2013-01-21 58 views
1

查詢XML元素有一個快速的問題:我目前正在努力學習如何使用XML文件的工作,並希望運行由你一個問題:

我遇到了一個有點問題,我肯定能使用一些幫助。我創建了下面一個簡單的小XML文件(users.xml中):

<?xml version="1.0" encoding="utf-8" standalone="yes"?> 
    <users> 
     <user> 
     <firstname>Might</firstname> 
     <lastname>Guy</lastname> 
     <username>SomeUser</username> 
     </user> 
     <user> 
     <firstname>Bob</firstname> 
     <lastname>Marley</lastname> 
     <username>BobMarley</username> 
     </user>  
    </users> 

我想要做的是找到一種方法來查詢該文件,以獲得有關用戶的特定信息。名字,姓氏無關緊要。現在,閒逛之後,我發現了什麼認爲是更好的方式之一許多人是:

string firstName; 

var data = from item in doc.Descendants("users") 
        where item.Element("user").Element("username").Value == "SomeUser" 
        select new 
        { 
         fname = item.Element("user").Element("firstname").Value 
        }; 

//Checking to see if anything was found. I know this isn't necessary to pull 
//the information. I'm just doing this so I can know to throw an error to the 
//screen if none is found 
    if (data.Count() > 0) 
//Now pull the data. Should only be 1 hit 
     foreach (var p in data) 
     { 
      firstName = p.ToString(); 
     } 
    else 
     MessageBox.Show("No such user found"); 

現在,這個示例代碼來給我的用戶的名字。但是,firstName的實際內容是「fname = Might」。我想要它包含的是「可能」。當然,如果我從選擇中刪除「fname =」,那麼它會拋出一個關於未命名該字段的錯誤,所以我點了一堵牆。我試着用Google搜索一個解決方案,但是因爲我不確定我在用谷歌搜索它沒有給我帶來好運。

所以我有3個問題。如果僅僅指出包含信息的教程的方向會更容易些,我也會對此感到激動!不只是尋找一個簡單的修復,而是想弄清楚爲什麼這是因爲我試圖學習XML而不是完成一項任務。

-A)是否有可能使用此方法來簡單地讓firstName包含「Might」,而不是「fname = Might」。如果是這樣,怎麼樣?如果沒有,是否有另一種方法可以做到這一點?

-B)爲什麼我需要「fname =」?這與LINQ有什麼關係,還是它完全是其他部分的一部分?除了LINQ/XML之外,我還沒能在其他任何地方找到這方面的例子,所以我一直無法得到更詳細的解釋,爲什麼它是這樣的。

-C)這是一個可接受的方法來解釋我在示例中要做的事情,也就是根據某個字段(用戶名,在本例中)查詢某個特定信息的XML文件?如果沒有,你能指出我採取哪種方法可能更好?

+1

方注意:你應該調用'FirstOrDefault()'。 – SLaks

+0

啊哈!非常感謝你! –

+1

您可能需要閱讀[匿名類型](http://msdn.microsoft.com/en-us/library/bb397696.aspx) – RobH

回答

1

這裏的問題XML文件中的數據正確的做法是,你正在使用p.ToString()代替p.fname。這個怎麼樣:

string firstName, lastName; 

var data = from item in doc.Descendants("user") 
      where item.Element("username").Value == "SomeUser" 
      select new 
      { 
       fname = item.Element("firstname").Value, 
       lname = item.Element("lastname").Value 
      }; 

var p = data.FirstOrDefault(); 
if(p != null) 
{ 
    firstName = p.fname; 
    lastName = p.lname; 
} 
else 
{ 
    MessageBox.Show("No such user found"); 
} 

要回答你的問題B,你不需要使用fname =語法。如果你只想要一個值,而不是,:

select new 
    { 
     fname = item.Element("firstname").Value, 
    }; 

你可以只使用:

select item.Element("firstname").Value; 

select new { key = value, key2 = value2 }語法允許你把幾個值到一個匿名類的一個對象,從中可以輕鬆提取您需要的值,按名稱。

+0

非常好!非常感謝您的幫助。這正是我需要的信息,尤其是B的答案。 –

1

用途:

var data = from item in doc.Descendants("users") 
       where item.Element("username").Value == "SomeUser" 
       select new 
       { 
        fname = item.Element("firstname").Value 
       }; 

var user = data.FirstOrDefault(); 
var firstName = user.fname; 

你得到「FNAME =可能」,因爲你整個匿名對象上調用ToString從查詢返回。從查詢返回的匿名對象實際上具有名爲fname的屬性。

要將C)問題:這是讀取這個LinqToXml ;-)

+0

非常感謝!也很高興聽到有關C = D的內容每次我搜索XML工作時,我都會一直運行「用戶LINQ」,因此它成爲我唯一使用它的目標。 –

1

您的選擇語句是投影。

這是告訴編譯器創建一個新的匿名對象,該對象具有一個屬性 - 具有屬性值的fname。

select new 
{ 
    fname = item.Element("user").Element("firstname").Value 
}; 

這是幾乎一樣做這樣的事情 - 除了編譯器自動的它適合你。

public class SomeObject 
{ 
    public string fname { get; set; } 
    public override ToString() 
    { 
    return "fname = " + fname; 
    } 
} 

var data = from item in doc.Descendants("users") 
        where item.Element("user").Element("username").Value == "SomeUser" 
        select new SomeObject { fname = item.Element("user").Element("firstname").Value } 

你的foreach是然後再遍歷每個元素並調用對象的toString ..

foreach (var p in data) 
{ 
    firstName = p.ToString(); 
} 

如果你改變你的foreach這將解決該問題:

foreach (var p in data) 
{ 
    firstName = p.fname; 
} 
+0

太棒了!謝謝你對「fname =」的解釋。這清除了奇妙!我確信我多次忽略了它,但是我絕對沒有找到與在線哈哈接近的解釋。再次感謝你! –