选择通过与其分组的另一个属性值找到的XML属性值。

时间:2015-02-12 02:45:28

标签: c# asp.net xml linq

我对使用XML做任何事情都很陌生,所以我不太了解术语,对于可能措辞严厉的问题感到遗憾。

我有一个XML文件结构如下:

<userinfo>
    <id username="bobby" password="password123" email="booby@gmail.com" question="Favourite colour" answer="blue"></id>
    <id username="tommy" password="adc123" email="herpderp@gmail.com" question="first pets name" answer="arnold"></id>
</userinfo>

(对此有任何建议的改进将不胜感激)

我需要根据用户名将问题值检索为字符串。

我已经有一些代码与xml交互了,我在这里返回一个bool用于登录,只是检查信息在一起:

public bool ValidLogin(string username, string password)
{
    XDocument doc = XDocument.Load(@"K:\Sem2\Software Development in Application Frameworks\test stuff\text\loginDetails.xml");

    return doc.Descendants("id")
                .Where(id => id.Attribute("username").Value == username 
                        && id.Attribute("password").Value == password)
                .Any();
}

但那是使用linq,我不知道如何从xml获取实际值。

如果它像以下那样简单,那就太好了。

 return doc.Descendants("id").Attribute("question").Value.Where(id => id.Attribute("username").Value == enteredUsername);

2 个答案:

答案 0 :(得分:2)

您需要使用Select()First()Last()Single()来获取值。

理想情况下,您应该有一个与您的XML文件匹配的类:

public class UserInfo
{
    public string username {get;set;}
    public string password {get;set;}
    public string question {get;set;}
    public string email {get;set;}
    public string answer {get;set;}
}

然后将您的方法更改为:

public UserInfo GetUserInfo(string username, string password)
{
    XDocument doc = XDocument.Load(@"K:\Sem2\Software Development in Application Frameworks\test stuff\text\loginDetails.xml");

    return doc.Descendants("id")
                .Where(id => (string)id.Attribute("username") == username 
                        && (string)id.Attribute("password") == password)
                .Select(s => new UserInfo
                {
                    username = (string)s.Attribute("username"),
                    password = (string)s.Attribute("password"),
                    email = (string)s.Attribute("email"),
                    question = (string)s.Attribute("question"),
                    answer = (string)s.Attribute("answer")
                })
                .FirstOrDefault();
}

现在使用您的调用方法:

var userInfo = GetUserInfo(username, password);

// check if user information matches what's in the XML file. return an error if it doesnt.
if (userInfo == null)
   Console.WriteLine("incorrect username/password");

// you haven't clarified in your question what you're doing with it. But the value of 'question' is accessible like this:
Console.WriteLine(userInfo.question);

答案 1 :(得分:1)

您可以使用SingleSelect等方法来获取您要查找的元素和属性。以下我在LinqPad中放在一起的例子:

var xml = "<userinfo>"
    + "<id username=\"bobby\" password=\"password123\" email=\"booby@gmail.com\" question=\"Favourite colour\" answer=\"blue\"></id>"
    + "<id username=\"tommy\" password=\"adc123\" email=\"herpderp@gmail.com\" question=\"first pets name\" answer=\"arnold\"></id>"
    + "</userinfo>";
var xDoc = XDocument.Parse(xml);
var enteredUsername = "tommy";

//Get idElement by username using Single()
var idElement = xDoc.Descendants("id")
                .Single(id => id.Attribute("username").Value == enteredUsername);

//Get question and answer values from idElement
var question = idElement.Attributes().Single(i => i.Name == "question").Value;
var answer = idElement.Attributes().Single(i => i.Name == "answer").Value;
Console.WriteLine(question);
Console.WriteLine(answer);

或者,您可以使用以下代码将值选择到匿名类中:

var xml = "...";
var xDoc = XDocument.Parse(xml);
var enteredUsername = "tommy";
var qa = xDoc.Descendants("id")
                .Where(id => id.Attribute("username").Value == enteredUsername)
                .Select(id => new { 
                    Question = id.Attribute("question").Value,
                    Answer = id.Attribute("answer").Value})
                .Single();
Console.WriteLine(qa.Question);
Console.WriteLine(qa.Answer);

希望有所帮助。