Noob LINQ - чтение, фильтрация XML с XDocument - PullRequest
2 голосов
/ 14 апреля 2010

Я только изучаю запросы 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-файле и отображать их Name, Value и NodeType в 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);
        }

... но теперь я хочу добавить предложение "где" в мой запрос, чтобы я выбирал только элементы с определенным именем (например, "qa"), но мой список элементов появляется пустым. Я старался . , ,

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

Может кто-нибудь объяснить, что я делаю не так? (и вообще есть ли хорошие советы по отладке запросов?) Заранее спасибо!

Ответы [ 2 ]

1 голос
/ 14 апреля 2010

Проблема в том, что свойство Name не является строкой, это XName .Когда вы запускаете его, вы получаете намного больше, чем вы думаете.

Хотя можно написать запрос так, как вы пытаетесь, также рассмотрите следующие возможности:

//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");
0 голосов
/ 14 апреля 2010

Возможно, я бы изменил ваш запрос на что-то похожее на это

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<[Anonymous Type]>, каждый объект содержит число, вопрос и ответ.

Однако, если вы просто хотите извлечь XElement, где имя q_a, вы можете сделать это, используя предложение where.

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

Конечно, как показал Дэвид Б., здесь не требуется пункт where.

IEnumerable<XElement> elem_list = elems.Elements("q_a");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...