2013-07-29 4 views
1

В следующей программе helloElem не является нулевым, как ожидалось.Получение элемента XML

string xml = @"<root> 
<hello></hello> 
</root>"; 

XDocument xmlDoc = XDocument.Parse(xml); 
var helloElem = xmlDoc.Root.Element("hello"); //not null 

Если дать XML пространство имен:

string xml = @"<root xmlns=""namespace""> 
<hello></hello> 
</root>"; 

XDocument xmlDoc = XDocument.Parse(xml); 
var helloElem = xmlDoc.Root.Element("hello"); //null 

почему helloElem утратившим? Как получить элемент привет в этом случае?

ответ

2

делают как ниже

XDocument xmlDoc = XDocument.Parse(xml); 
XNamespace ns = xmlDoc.Root.GetDefaultNamespace(); 
var helloElem = xmlDoc.Root.Element(ns+ "hello"); 
2

Попробуйте

XNamespace ns = "namespace"; 
var helloElem = xmlDoc.Root.Element(ns + "hello"); 
+0

Это работает, но возможно ли, чтобы код поддерживал все случаи, с/без пространств имен, а не с жесткой кодировкой пространства имен? –

+0

@ roger.james Это как просить компилятор C# игнорировать пространства имен и просто попытаться найти соответствующий объект в вашем проекте. Как и ваши проекты, пространства имен в XML помогают отличить «конфету: бар» от «foo: bar», которые, безусловно, две разные вещи. –

1

Вот это пространство имен по умолчанию XPath.

private static XElement XPathSelectElementDefaultNamespace(XDocument document, 
                  string element) 
{ 
    XElement result; 
    string xpath; 

    var ns = document.Root.GetDefaultNamespace().ToString(); 

    if(string.IsNullOrWhiteSpace(ns)) 
    { 
     xpath = string.Format("//{0}", element); 
     result = document.XPathSelectElement(xpath); 
    } 
    else 
    { 
     var nsManager = new XmlNamespaceManager(new NameTable()); 
     nsManager.AddNamespace(ns, ns); 

     xpath = string.Format("//{0}:{1}", ns, element); 
     result = document.XPathSelectElement(xpath, nsManager); 
    } 

    return result; 
} 

Использование:

string xml1 = @"<root> 
<hello></hello> 
</root>"; 

string xml2 = @"<root xmlns=""namespace""> 
<hello></hello> 
</root>"; 

var d = XDocument.Parse(xml1); 
Console.WriteLine(XPathSelectElementDefaultNamespace(d, "hello")); 
// Prints: <hello></hello> 

d = XDocument.Parse(xml2); 
Console.WriteLine(XPathSelectElementDefaultNamespace(d, "hello")); 
// Prints: <hello xmlns="namespace"></hello> 
3

Конечно, вы можете избавиться от namespaces, смотрите ниже:

string xml = @"<root> 
        <hello></hello> 
       </root>"; 

XDocument xmlDoc = XDocument.Parse(xml); 
var helloElem = xmlDoc.Descendants().Where(c => c.Name.LocalName.ToString() == "hello"); 

Приведенный выше код может обрабатывать узлы с или без namespaces. См. Descendants() для получения дополнительной информации. Надеюсь это поможет.

Смежные вопросы