【问题标题】:Noob LINQ - reading, filtering XML with XDocumentNoob LINQ - 使用 XDocument 读取、过滤 XML
【发布时间】:2010-04-14 03:49:41
【问题描述】:

我只是在学习 XDocument 和 LINQ 查询。这是一些简单的 XML(在我的浏览器中的这个论坛中,它的格式看起来并不完全正确,但你明白了......)

<?xml version="1.0" encoding="utf-8"?>
<quiz  
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.example.com/name XMLFile2.xsd"
  title="MyQuiz1">
  <q_a>
    <q_a_num>1</q_a_num>
    <q_>Here is question 1</q_>
    <_a>Here is the answer to 1</_a>
  </q_a>

  <q_a>
    <q_a_num>2</q_a_num>
    <q_>Here is question 2</q_>
    <_a>Here is the answer to 2</_a>
  </q_a>
</quiz>

我可以遍历我的 XML 文件中的所有元素,并像这样在 ListBox 中显示它们的名称、值和节点类型,没问题:

        XDocument doc = XDocument.Load(sPath);
        IEnumerable<XElement> elems = doc.Descendants();

        IEnumerable<XElement> elem_list = from elem in elems
                                          select elem;

        foreach (XElement element in elem_list)
        {
            String str0 = "Name = " + element.Name.ToString() + 
                          ",  Value = " + element.Value.ToString() +
                          ",  Nodetype = " + element.NodeType.ToString();
            System.Windows.Controls.Label strLabel = new System.Windows.Controls.Label();
            strLabel.Content = str0;
            listBox1.Items.Add(strLabel);
        }

...但是现在我想在我的查询中添加一个“where”子句,以便我只选择具有特定名称的元素(例如,“qa”),但我的元素列表为空。我试过了 。 . .

            IEnumerable<XElement> elem_list = from elem in elems
                                        where elem.Name.ToString() == "qa"
                                        select elem;

有人可以解释我做错了什么吗? (总的来说,有一些调试查询的好技巧吗?)提前谢谢!

【问题讨论】:

    标签: c# linq linq-to-xml


    【解决方案1】:

    问题在于 Name 属性不是字符串,而是XName。当你 ToString 它时,你得到的比你想象的要多。

    虽然可以按照您尝试的方式编写查询,但也要考虑以下可能性:

    //from nodes immediately below this one
    IEnumerable<XElement> elem_list = doc.Elements("qa");
    
    //from nodes of all levels below this node.
    IEnumerable<XElement> elem_list = doc.Descendants("qa");
    

    【讨论】:

    • 但是,要获取非限定名作为字符串,他可以使用elem.Name.LocalName.
    【解决方案2】:

    我可能会将您的查询更改为看起来更像这样的内容

    var query = from q_a in document.Descendants("q_a")
                select new
                {
                    Number = (int)q_a.Element("q_a_num"),
                    Question = (string)q_a.Element("q_"),
                    Answer = (string)q_a.Element("_a")
                };
    

    这样,您将从每个q_a 后代中提取内部元素到IEnumerable&lt;[Anonymous Type]&gt;,每个对象都包含数字、问题和答案。

    但是,如果您只想提取名称为 q_a 的 XElement,则可以使用 where 子句来完成。

    IEnumerable<XElement> elem_list = elems.Where(elem => elem.Name.LocalName == "q_a");
    

    当然,正如 David B 所示,这里不需要 where 子句。

    IEnumerable<XElement> elem_list = elems.Elements("q_a");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-22
      相关资源
      最近更新 更多