2010-03-11 43 views
1

所以我試圖解析XML文件:爲什麼在使用xmlns解析xml文件時XElement會崩潰?

<?xml version="1.0" encoding="utf-8" ?> 
<Root>  
    <att1 name="bob" age="unspecified" xmlns="http://foo.co.uk/nan">  
    </att1>  
</Root> 

使用下面的代碼:

XElement xDoc= XElement.Load(filename); 
var query = from c in xDoc.Descendants("att1").Attributes() select c; 
foreach (XAttribute a in query) 
{ 
    Console.WriteLine("{0}, {1}",a.Name,a.Value); 
} 

沒有被寫入到控制檯,除非我刪除的xmlns =「HTTP:// foo中。 co.uk/nan「,之後,我得到了一個期望的屬性名稱和值列表,而且正如我所需要的!

編輯:格式。

+0

順便說一句,有書面形式沒有點'從C中的任何選擇C'。 – SLaks 2010-03-11 14:32:13

+0

所以沒有!謝謝:)我從LINQ to XML的非常有用的介紹中選擇了這裏:http://www.microsoft.com/uk/msdn/nuggets/nugget/204/Querying-XML-in-C-with- LINQ-to-XML.aspx – zotty 2010-03-11 14:40:08

回答

3

你必須使用相同的命名空間在代碼:

XElement xDoc= XElement.Load(filename); 
XNamespace ns = "http://foo.co.uk/nan"; 
var query = from c in xDoc.Descendants(ns + "att1").Attributes() select c; 
foreach (XAttribute a in query) 
{ 
    Console.WriteLine("{0}, {1}",a.Name,a.Value); 
} 

屬性不拿起默認(xmlns=....)命名空間,所以你不需要限定它們。名稱空間標記(xmln:tags=....)純粹是文檔或API使用的本地名稱,名稱始終是名稱空間+本地名稱,因此您必須始終指定名稱空間。

+0

完美地完成了這個技巧,謝謝。由於命名空間可能會在xml文件之間發生變化,我猜你必須將該文件作爲字符串加載,然後查找命名空間並在代碼中聲明它? – zotty 2010-03-11 14:38:00

+0

@zotty如果您按照我的答案中顯示的方式查詢LocalName,則不需要字符串解析。 – 2010-03-11 14:52:31

+0

@zotty:如果命名空間不同,你的代碼將更加冗長,並且它確實缺少命名空間的點(節點的名稱是命名空間+本地名稱),但這有時是必需的。 – Richard 2010-03-12 11:17:10

1

您需要在Descendants調用指定命名空間,就像這樣:

XNamespace ns = "http://foo.co.uk/nan"; 
foreach (XAttribute a in xDoc.Descendants(ns + "att1")) 
{ 
    Console.WriteLine("{0}, {1}",a.Name,a.Value); 
} 
2

您對Descendants調用查詢沒有命名空間名爲「ATT1」的元素。

如果您調用Descendants("{http://foo.co.uk/nan}att1"),則應選擇名稱空間元素,但不選擇非名稱空間元素。

你可以選擇任何一個名爲「ATT1」元素或沒有命名空間是這樣的:

var query = from c in xDoc.Descendants() where c.Name.LocalName == "att1" select c.Attributes; 
相關問題