XElement.Descendants не работает с пространством имен

У меня есть простой XML,

<S xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"><H></H></S>

Я хочу найти все узлы "Н".

XElement x = XElement.Parse("<S xmlns=\"http://schemas.microsoft.com/winfx/2006/xaml/presentation\"><H></H></S>");
IEnumerable<XElement> h = x.Descendants("H");
if (h != null)
{
}

Но этот код не работает. Когда я удаляю пространство имен из тега S, код работает правильно.

Ответы

Ответ 1

У вашего элемента есть пространство имен, потому что xmlns эффективно устанавливает пространство имен по умолчанию для этого элемента и его потомков. Вместо этого попробуйте:

XNamespace ns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation";
IEnumerable<XElement> h = x.Descendants(ns + "H");

Обратите внимание, что Descendants никогда не вернет null, поэтому условие в конце вашего кода бессмысленно.

Если вы хотите найти все элементы H независимо от пространства имен, вы можете использовать:

var h = x.Descendants().Where(e => e.Name.LocalName == "H");

Ответ 2

Просто хотел добавить к Jon ответ, что вы можете получить пространство имен следующим образом:

XNamespace ns = x.Name.Namespace

Тогда просто используйте его, как он предложил:

IEnumerable<XElement> h = x.Descendants(ns + "H");