2010-02-26 36 views
52

tôi có mã này:Sử dụng LINQ to XML với namespace Xml

/*string theXml = 
@"<Response xmlns=""http://myvalue.com""><Result xmlns:a=""http://schemas.datacontract.org/2004/07/My.Namespace"" xmlns:i=""http://www.w3.org/2001/XMLSchema-instance""><a:TheBool>true</a:TheBool><a:TheId>1</a:TheId></Result></Response>";*/ 

string theXml = @"<Response><Result><TheBool>true</TheBool><TheId>1</TheId></Result></Response>"; 

XDocument xmlElements = XDocument.Parse(theXml); 

var elements = from data in xmlElements.Descendants("Result") 
       select new { 
          TheBool = (bool)data.Element("TheBool"), 
          TheId = (int)data.Element("TheId"), 
          }; 

foreach (var element in elements) 
{ 
    Console.WriteLine(element.TheBool); 
    Console.WriteLine(element.TheId); 
} 

Khi tôi sử dụng giá trị đầu tiên cho theXml, kết quả là null, trong khi với cái thứ hai, tôi có giá trị tốt đẹp ...

Cách sử dụng LINQ to Xml với giá trị xmlns?

Trả lời

79

LINQ to XML phương pháp như DescendantsElement lấy một XName như một cuộc tranh cãi. Có một chuyển đổi từ string thành XName điều đang diễn ra tự động cho bạn. Bạn có thể sửa lỗi này bằng cách thêm XNamespace trước các chuỗi trong các cuộc gọi DescendantsElement của mình. Xem ra vì bạn có 2 không gian tên khác nhau trong công việc.

 

string theXml = 
       @"true1"; 

      //string theXml = @"true1"; 

    XDocument xmlElements = XDocument.Parse(theXml); 
    XNamespace ns = "http://myvalue.com"; 
    XNamespace nsa = "http://schemas.datacontract.org/2004/07/My.Namespace"; 
    var elements = from data in xmlElements.Descendants(ns + "Result") 
      select new 
       { 
        TheBool = (bool) data.Element(nsa + "TheBool"), 
        TheId = (int) data.Element(nsa + "TheId"), 
       }; 

    foreach (var element in elements) 
    { 
     Console.WriteLine(element.TheBool); 
     Console.WriteLine(element.TheId); 
    } 
 

Thông báo việc sử dụng các ns trong Descendants và NSA trong Elements

+1

tuyệt vời, làm việc :) !! Cảm ơn rất nhiều – Tim

+18

xmlElements.Descendants (xmlElements.Root.GetDefaultNamespace() + "Result") cũng có thể hoạt động ... –

23

Bạn có thể chuyển số XName bằng không gian tên tới Descendants()Element(). Khi bạn chuyển một chuỗi tới Descendants(), nó được chuyển đổi hoàn toàn sang một XName không có không gian tên.

Để tạo một XName trong một không gian tên, bạn tạo một XNamespace và nối nó vào phần tử tên địa phương (một chuỗi).

XNamespace ns = "http://myvalue.com"; 
XNamespace nsa = "http://schemas.datacontract.org/2004/07/My.Namespace"; 

var elements = from data in xmlElements.Descendants(ns + "Result") 
        select new 
           { 
            TheBool = (bool)data.Element(nsa + "TheBool"), 
            TheId = (int)data.Element(nsa + "TheId"), 
           }; 

Cũng có dạng viết tắt để tạo XName với không gian tên thông qua chuyển đổi ẩn từ chuỗi.

var elements = from data in xmlElements.Descendants("{http://myvalue.com}Result") 
        select new 
           { 
            TheBool = (bool)data.Element("{http://schemas.datacontract.org/2004/07/My.Namespace}TheBool"), 
            TheId = (int)data.Element("{http://schemas.datacontract.org/2004/07/My.Namespace}TheId"), 
           }; 

Ngoài ra, bạn có thể truy vấn đối với XElement. Name.LocalName.

var elements = from data in xmlElements.Descendants() 
        where data.Name.LocalName == "Result" 
+0

Tên địa phương không tồn tại trong nội dung của tôi – Tim

+2

Chuyển đổi từ toán tử + thành xname là ngớ ngẩn, khủng khiếp và hủy bỏ hoàn toàn. MS đang nghĩ gì vậy? Có lẽ nó sử dụng một biểu thức > dưới mui xe - làm cho tôi cảm thấy bị bệnh. – Gusdor

+0

+1 cho {viết tắt}. Tôi không biết về điều đó! –

0

tôi thấy đoạn mã sau để làm việc tốt cho việc đọc các thuộc tính với namespace trong VB.NET:

MyXElement.Attribute(MyXElement.GetNamespaceOfPrefix("YOUR_NAMESPACE_HERE") + "YOUR_ATTRIB_NAME") 

Hope this helps ai đó xuống đường.

0

Tôi có một số không gian tên được liệt kê ở đầu tài liệu XML, tôi không thực sự quan tâm đến yếu tố nào từ không gian tên nào. Tôi chỉ muốn lấy các yếu tố bằng tên của họ. Tôi đã viết phương pháp mở rộng này.

/// <summary> 
    /// A list of XElement descendent elements with the supplied local name (ignoring any namespace), or null if the element is not found. 
    /// </summary> 
    public static IEnumerable<XElement> FindDescendants(this XElement likeThis, string elementName) { 
     var result = likeThis.Descendants().Where(ele=>ele.Name.LocalName==elementName); 
     return result; 
    } 
Các vấn đề liên quan