Linq to XML простой атрибут get из оператора узла - PullRequest
2 голосов
/ 21 октября 2010

Вот фрагмент кода:

XDocument themes = XDocument.Load(HttpContext.Current.Server.MapPath("~/Models/Themes.xml"));
string result = "";
var childType = from t in themes.Descendants()
    where t.Attribute("name").Value.Equals(theme)
    select new { value = t.Attribute("type").Value };

foreach (var t in childType) {
    result += t.value;
}
return result;

и вот XML:

<?xml version="1.0" encoding="utf-8" ?>
<themes>
  <theme name="Agile">
    <root type="Project">
      <node type="Iteration" >
        <node type="Story">
          <node type="Task"/>
        </node>
      </node>
    </root>
  </theme>
  <theme name="Release" >
    <root type="Project">
      <node type="Release">
        <node type="Task" />
        <node type="Defect" />
      </node>
    </root>
  </theme>
</themes>

Что я делаю не так? Я получаю исключение «объект не установлен как экземпляр объекта».

Я пытаюсь вернуть тип выбранного узла на основе типа родительского узла, т. Е. Если тема «Agile», а родительский узел «Project», возвращаемое значение должно быть « Итерация». Это окончательный результат, но я никогда не заходил так далеко, потому что застрял с тем, что вы видите выше.

Ответы [ 4 ]

5 голосов
/ 21 октября 2010

Я думаю, вы хотите что-то ближе к этому:

XDocument themes = XDocument.Load(HttpContext.Current.Server.MapPath("~/Models/Themes.xml"));
string result = "";
var childType = from t in themes.Descendants("theme")
                where t.Attribute("name").Value.Equals(theme)
                select new { value = t.Descendants().Attribute("type").Value };

foreach (var t in childType) {
    result += t.value;
}
return result;

РЕДАКТИРОВАТЬ: Возможно, это даже ближе:

XDocument themes = XDocument.Load(HttpContext.Current.Server.MapPath("~/Models/Themes.xml"));
string result = "";
var childType = from t in themes.Descendants("theme")
                where t.Attribute("name").Value.Equals(theme)
                where t.Element("node").Attribute("type").Value == parent
                select new { value = t.Descendants().Attribute("type").Value };

foreach (var t in childType) {
    result += t.value;
}
return result;

РЕДАКТИРОВАТЬ 2: Это работает для меня:

XDocument themes = XDocument.Load(HttpContext.Current.Server.MapPath("~/Models/Themes.xml"));
string result = "";
var theme = "Agile";
var parent = "Project";
var childType = from t in themes.Descendants("theme")
            where t.Attribute("name").Value.Equals(theme)
            where t.Element("root").Attribute("type").Value == parent
            from children in t.Element("root").Descendants()
            select new { value = children.Attribute("type").Value };
foreach (var t in childType) {
    result += t.value;
}
return result;

РЕДАКТИРОВАТЬ 3: Вот полная рабочая программа, просто бросить ее в класс в консольном приложении.

static void Main(string[] args)
        {
            var xml = "<themes><theme name='Agile'><root type='Project'><node type='Iteration' ><node type='Story'><node type='Task'/></node></node></root></theme><theme name='Release' ><root type='Project'><node type='Release'><node type='Task' /><node type='Defect' /></node></root></theme></themes>";
            XDocument themes = XDocument.Parse(xml);
            string result = "";
            var theme = "Agile";
            var parent = "Project";
            var childType = from t in themes.Descendants("theme")
                            where t.Attribute("name").Value.Equals(theme)
                            where t.Element("root").Attribute("type").Value == parent
                            from children in t.Element("root").Descendants()
                            select new { value = children.Attribute("type").Value };

            foreach (var t in childType)
            {
                Console.WriteLine(t.value);
            }

            Console.Read();

        }
1 голос
/ 21 октября 2010

Хорошо, вот что я сделал в конце, это не очень красиво, но работает.Он основан на ответе Pramodh с несколькими твиками.

string result = "";
                var childType = themes.Descendants("theme")
                                               .Where(x => x.Attribute("name").Value == theme)
                                               .Where(x => x.Descendants("node").First().Attribute("type").Value == parentType)
                                               .Select(x => x.Descendants("node").First().Descendants().First().Attribute("type").Value);

                foreach (var t in childType) {
                    result += t;
                }
                return result;

Теперь, если я перейду к теме "Agile" и родительской "Iteration", он вернет историю.

Как я сказал, не оченьдовольно, но это работает.

Спасибо всем, кто разместил ответы.

0 голосов
/ 21 октября 2010

В вашем запросе есть две ошибки.

Первый:

from t in themes.Descendants()

Это даст вам все themes элементов.
Если вам нужны элементы theme, вы должны указать их, отфильтровав:

from t in themes.Descendants("theme")

Следовательно, вторая ошибка будет

select new { value = t.Attribute("type").Value }

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

Редактировать: Согласно добавленной информации, это должно сработать:

        var childType =
            from t in doc.Descendants("theme")
            where t.Attribute("name").Value.Equals(theme)
            select t.Element("root")
                    .Element("node")
                    .Attribute("type").Value;

Однако это предназначено для извлечения нескольких типов из узлов с одинаковым theme именем.
Если тип всегда будет одинаковым, вам следует подумать о вызове .SingleOrDefault().

0 голосов
/ 21 октября 2010

Я не прояснил ваш вопрос.Вот мое решение (как я понял)

var childType = themes.Descendants("theme")
                             .Where(X => X.Attribute("name").Value == "Agile")
                             .Where(X => X.Descendants("root").Attributes("type").First().Value == "Project")
                             .Select(X => X.Descendants("node").Attributes("type").First().Value);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...