2013-07-29 58 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成爲空?在這種情況下,我如何獲得hello元素?

回答

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中的命名空間有助於將'candy:bar'與'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()瞭解更多信息。希望這可以幫助。