2011-10-16 24 views
8

Tôi mới làm việc với XML và tôi gặp phải sự cố lạ khi cố gắng lấy thẻ cụ thể từ tệp cấu hình spring.net. Sau khi cố gắng thu hẹp vấn đề với một tập tin thử nghiệm xml, tôi phát hiện ra rằng việc áp dụng đoạn mã sau:Không thể sử dụng Con cháu() hoặc Phần tử() với xmlns

List<XElement> nodes = xmlFile.Descendants("B").ToList(); 

cung cấp một danh sách không có sản phẩm nào với các tập tin sau đây:

<?xml version="1.0" encoding="utf-8" ?> 
<A fakeAttribute="aaa"> 
    <B id="DbProvider"/> 
</A> 

nhưng cung cấp một chuỗi rỗng có tệp sau:

<?xml version="1.0" encoding="utf-8" ?> 
<A xmlns="aaa"> 
    <B id="DbProvider"/> 
</A> 

Sự khác biệt duy nhất giữa các tệp là thuộc tính.

Tôi không thể tưởng tượng được lời giải thích cho điều này. Cảm ơn bạn đã giúp đỡ.

Trả lời

8

Bạn cần phải tìm kiếm thẻ trong namespace rằng:

XNamespace ns = "aaa"; 

xmlFile.Descendants(ns + "B").ToList() 
+0

Cảm ơn! Điều đó đã làm các trick - nhưng cũng mở đường cho một vấn đề khác. Ví dụ, tôi có thể lấy con cháu có tên là "B", nhưng không thể có được con cháu có tên "db: provider" (không phải bằng cách sử dụng "db" hay "db: provider"), thật đáng buồn là tôi cần làm gì. – Tomata

+0

db được liệt kê dưới dạng không gian tên khác. Lỗi của tôi. – Tomata

+3

@Tomata Nếu bạn muốn bỏ qua các không gian tên, bạn có thể viết một cái gì đó như: 'var lst = doc.Descendants(). Where (p => p.Name.LocalName ==" B "). ToList();' – xanatos

6

Bạn nên xác định không gian tên khi truy vấn cho các yếu tố.

Bạn có thể sử dụng GetDefaultNamespace method để tránh mã hóa cứng. Nó cũng hữu ích nếu bạn không biết nó là gì trước thời hạn.

Ví dụ:

var ns = xmlFile.GetDefaultNamespace(); 
var nodes = xmlFile.Descendants(ns + "B").ToList(); 
+0

Trong một case, .GetDefaultNamespace không hoạt động vì tác giả lược đồ XML không sử dụng xmlns mà là xmlns: foo. Bạn có thể sử dụng: var ns = xDoc.Root.GetNamespaceOfPrefix ("foo"); – Stonetip

9

Chỉ cần cho đầy đủ vì:

var lst = doc.Descendants("{aaa}B").ToList(); 

(những gì người kia nói là đúng, nhưng tôi muốn tặng một lựa chọn :-))

Đối với siêu đầy đủ vì lợi ích, nếu bạn muốn tìm kiếm bỏ qua không gian tên:

var lst = doc.Descendants().Where(p => p.Name.LocalName == "B").ToList(); 
Các vấn đề liên quan