2010-09-04 19 views
69

Xem xét XML sau:Làm thế nào để sử dụng XPath với XElement hoặc LINQ?

<response> 
    <status_code>200</status_code> 
    <status_txt>OK</status_txt> 
    <data> 
    <url>http://bit.ly/b47LVi</url> 
    <hash>b47LVi</hash> 
    <global_hash>9EJa3m</global_hash> 
    <long_url>http://www.tumblr.com/docs/en/api#api_write</long_url> 
    <new_hash>0</new_hash> 
    </data> 
</response> 

Tôi đang tìm kiếm một cách thực sự ngắn để có được chỉ là giá trị của phần tử <hash>. Tôi đã thử:

var hash = xml.Element("hash").Value; 

Nhưng điều đó không hiệu quả. Có thể cung cấp truy vấn XPath cho một số XElement không? Tôi có thể làm điều đó với khuôn khổ cũ System.Xml, làm một cái gì đó như:

xml.Node("/response/data/hash").Value 

Có một cái gì đó như thế này trong một không gian tên LINQ?


UPDATE:

Sau monkeying xung quanh với điều này một số chi tiết tôi tìm thấy một cách để làm những gì tôi đang cố gắng để làm:

var hash = xml.Descendants("hash").FirstOrDefault().Value; 

tôi vẫn muốn được quan tâm để xem bất cứ ai có một giải pháp tốt hơn?

+3

Không sử dụng FirstOfDefault() trong trường hợp này, bởi vì nếu "băm" không được tìm thấy, bạn sẽ nhận được một NullReferenceException. Sử dụng First() thay vào đó, bạn sẽ nhận được một ngoại lệ mô tả hơn. – kaalus

+2

Sử dụng First() nếu bạn mong đợi "băm" luôn tồn tại. Nếu không, FirstOrDefault() là tốt miễn là bạn kiểm tra null trước khi truy cập thuộc tính Value. –

Trả lời

120

Để sử dụng XPath với LINQ to XML, hãy thêm khai báo sử dụng cho System.Xml.XPath, điều này sẽ đưa các phương thức mở rộng System.Xml.XPath.Extensions vào phạm vi.

Trong ví dụ của bạn:

var value = (string)xml.XPathEvaluate("/response/data/hash"); 
+1

OK, có vẻ gần nhất với câu hỏi gốc –

+3

Thực ra, đó là (bây giờ?) Trong 'System.Xml.XPath'. –

+0

@DanFriedman nó đã không di chuyển. Lưu ý liên kết là tài liệu lớp học, hơi sớm hơn tôi cung cấp cho không gian tên (không có một liên kết). – Richard

13

Hãy xem, khi giao dịch với LINQ to XML tại sao bạn không sử dụng LINQ để lấy đối tượng thực tế.

Con cháu tìm từng phần tử từ toàn bộ XML và liệt kê tất cả các đối tượng khớp với tên được chỉ định. Vì vậy, trong trường hợp băm của bạn là tên mà nó tìm thấy.

Vì vậy, chứ không phải là làm

var hash = xml.Descendants("hash").FirstOrDefault().Value; 

tôi sẽ phá vỡ như:

var elements = xml.Descendants("hash"); 
var hash = elements.FirstOrDefault(); 

if(hash != null) 
hash.Value // as hash can be null when default. 

Bằng cách này bạn cũng có thể nhận được các thuộc tính, các nút yếu tố, vv

Kiểm tra bài viết này để nhận được ý tưởng rõ ràng về nó để nó giúp. http://www.codeproject.com/KB/linq/LINQtoXML.aspx Tôi hy vọng điều này sẽ giúp bạn.

+2

@adhishek +1 để giải thích giá trị tách phần tử thành biến riêng của nó để bạn có thể thực hiện các công cụ khác như nhận thuộc tính, v.v. –

+1

Một lý do để sử dụng XPath là bạn mất tất cả những thứ XPath có thể làm và LINQ không thể . Điều hiển nhiên đầu tiên bạn cần thực hiện là truy vấn được định nghĩa trong thời gian chạy (nói một biểu thức được đọc từ cấu hình hoặc bất kỳ thứ gì). –

33

Những người khác đã hoàn toàn hợp lý đề xuất cách sử dụng LINQ "truy vấn" gốc XML để thực hiện những gì bạn muốn.

Tuy nhiên, vì lợi ích của cách cung cấp rất nhiều lựa chọn thay thế, hãy xem xét XPathSelectElement, XPathSelectElementsXPathEvaluate để đánh giá biểu thức XPath chống lại một XNode (họ đang tất cả phương pháp khuyến nông trên XNode). Bạn cũng có thể sử dụng CreateNavigator để tạo một XPathNavigator cho số XNode.

Cá nhân tôi là một người hâm mộ lớn sử dụng LINQ to XML API trực tiếp, vì tôi là người hâm mộ LINQ lớn, nhưng nếu bạn cảm thấy thoải mái hơn với XPath, điều trên có thể giúp bạn.

5

Bạn có thể sử dụng phương pháp .Element() để chuỗi các yếu tố để tạo thành cấu trúc XPath-như thế nào.

Ví dụ của bạn:

XElement xml = XElement.Parse(@"...your xml..."); 
XElement hash = xml.Element("data").Element("hash"); 
+0

Tôi nghĩ đây là câu trả lời tốt nhất bởi vì nó được thực hiện công việc trong khi tiếp tục sử dụng LINQ to XML (được khuyến nghị) thay vì sử dụng XPath với truy vấn LINQ to XML (không được khuyến nghị). –

+1

Sử dụng XPath ngắn gọn hơn, đặc biệt là nếu bạn đang tìm kiếm bất kỳ đứa trẻ lớn nào hoặc hơn thế nữa. –

1

tôi đã cố gắng đưa ra một khuôn khổ LINQesq để tạo xpath. Nó cho phép bạn mô tả xpath sử dụng C# lambda biểu thức

var xpath = CreateXpath.Where(e => e.TargetElementName == "td" && e.Parent.Name == "tr"); 

var xpath = CreateXpath.Where(e => e.TargetElementName == "td").Select(e => e.Text); 

Không chắc nếu điều này là hữu ích trong bối cảnh này, nhưng bạn có thể tìm tài liệu ở đây:

http://www.syntaxsuccess.com/viewarticle/how-to-create-xpath-using-linq

Các vấn đề liên quan