1

有一个简单的问题:我目前正在尝试学习如何使用 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 =”,那么它会引发关于未命名字段的错误,所以我有点碰壁了。我尝试在谷歌上搜索解决方案,但由于我不确定我在谷歌搜索什么,它并没有给我带来太多运气。

所以我有3个问题。如果将我指向包含信息的教程的方向会更容易,我也会对此感到兴奋!不只是在寻找一个简单的解决方法,而是想弄清楚为什么会这样,因为我正在尝试学习 XML 而不仅仅是完成一项任务。

-A) 是否可以使用这种方法让 firstName 包含“Might”,而不是“fname = Might”。如果是这样,怎么做?如果没有,是否有另一种方法可以做到这一点?

-B) 为什么我需要“fname =”?这是与 LINQ 有关,还是完全是其他东西的一部分?除了 LINQ/XML 的东西,我还没有在其他任何地方找到这方面的例子,所以我无法更详细地解释它为什么会这样。

-C)这是一种可接受的方法来处理我在示例中尝试执行的操作,也就是根据某个字段(在本例中为用户名)查询 XML 文件以获取特定信息吗?如果没有,你能告诉我任何可能更好的方法吗?

4

3 回答 3

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=Might",因为您正在调用ToString从查询返回的整个匿名对象。从查询返回的匿名对象实际上具有名为 的属性fname

对于您的C)问题:使用此 LinqToXml 从 xml 文件读取数据是正确的方法;-)

于 2013-01-21T20:20:29.843 回答
1

这里的问题是您使用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 }语法允许您将多个值放入匿名类的对象中,您可以通过名称轻松地从中提取所需的值。

于 2013-01-21T20:21:17.943 回答
1

您的 select 语句是一个投影。

这告诉编译器创建一个新的匿名对象,该对象具有一个属性 - 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;
}
于 2013-01-21T20:23:02.357 回答