将 XML 元素查询为字符串

本文关键字:字符串 查询 元素 XML | 更新日期: 2023-09-27 17:55:18

有一个快速的问题:我目前正在尝试学习如何处理XML文件,并想由您提出一个问题:

遇到了一些问题,我当然可以使用一些帮助。我在下面创建了一个简单的小XML文件(用户.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 = Mayght"。我希望它包含的只是"可能"。当然,如果我从选择中删除"fname =",那么它会抛出一个关于不命名字段的错误,所以我有点碰壁了。我尝试在谷歌上搜索解决方案,但由于我不确定我在谷歌上搜索什么,它并没有给我带来太多的运气。

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

-A)是否可以使用此方法简单地让 firstName 包含"可能",而不是"fname = 可能"。如果是这样,如何?如果没有,有没有其他方法可以做到这一点?

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

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

将 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 }语法允许您将多个值放入匿名类的对象中,您可以从中按名称轻松提取所需的值。

您的选择语句是一个投影。

这是告诉编译器创建一个新的匿名对象,该对象具有一个属性 - 带有属性值的 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;
}

使用:

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 文件中读取数据是正确的方法;-)