2011-11-28 41 views
10

phép nói rằng tôi có xml sau (một ví dụ nhanh)Sử dụng XPath để phân tích một tài liệu XML

<rows> 
    <row> 
     <name>one</name> 
    </row> 
    <row> 
     <name>two</name> 
    </row> 
</rows> 

Tôi cố gắng để phân tích điều này bằng cách sử dụng XmlDocument và XPath (cuối cùng để tôi có thể làm cho một danh sách các hàng).

Ví dụ ...

XmlDocument doc = new XmlDocument(); 
doc.LoadXml(xml); 

foreach(XmlNode row in doc.SelectNodes("//row")) 
{ 
    string rowName = row.SelectSingleNode("//name").InnerText; 
} 

Tại sao, trong vòng lặp foreach của tôi, là rowName luôn "một"? Tôi hy vọng nó sẽ là "một" trong lần lặp đầu tiên và "hai" vào lần thứ hai.

Dường như tên // nhận được cá thể đầu tiên trong tài liệu, chứ không phải là cá thể đầu tiên trong hàng như tôi mong đợi. Sau khi tất cả, tôi đang gọi phương thức trên nút "hàng". Nếu đây là "nó hoạt động như thế nào" thì ai cũng có thể giải thích làm thế nào tôi có thể thay đổi nó để làm việc theo nhu cầu của tôi?

Cảm ơn bạn

+0

thế nào về cách chọn nó bởi // hàng/tên? Điều này có hiệu quả không? – Steve

Trả lời

14

Là mã bạn được đăng trên thực tế có đúng không? Tôi nhận được một lỗi biên dịch trên row.SelectNode() vì nó không phải là một thành viên của XmlNode.

Dù sao, ví dụ của tôi ở trên tác phẩm, nhưng giả định chỉ có một <name> nút duy nhất trong nút <row> vì vậy bạn có thể cần phải sử dụng SelectNodes() thay vì SelectSingleNode() nếu đó không phải là trường hợp.

Khi những người khác đã hiển thị, hãy sử dụng .InnerText để chỉ nhận giá trị.

+0

Cảm ơn, và tốc độ của bạn sẽ giúp bạn có được 25! Tôi đã đi xa như cố gắng với một dấu gạch chéo đơn, nhưng khi đó đã ném một lỗi tôi đã từ bỏ và đã viết một chức năng để tìm kiếm các nút con. Quay trở lại XPath tốt ngay bây giờ mặc dù :) – musefan

+0

Quên '.InnerText' trong bài viết gốc của tôi, cố định ngay bây giờ ... và nhập sai' SelectSingleNode' – musefan

3

Sử dụng đường dẫn tương đối, ví dụ: string rowName = row.SelectSingleNode("name").InnerText;.

2

Vấn đề là trong truy vấn XPath thứ hai của bạn:

//row 

này có phạm vi toàn cầu, vì vậy dù bạn ở đâu gọi nó là từ, nó sẽ chọn tất cảrow yếu tố.

Nó sẽ làm việc nếu bạn thay thế biểu hiện của bạn với:

.//row 
2

Tôi sẽ sử dụng SelectSingleNode, và sau đó là tài sản innerText.

var rowName = row.SelectSingleNode("name").InnerText; 
4

Sử dụng LINQ to XML. Bao gồm using System.Xml.Linq; trong tập tin mã của bạn và sau đó làm đoạn mã sau để có được danh sách của bạn

XDocument xDoc = XDocument.Load(filepath); 
IEnumerable<XElement> xNames; 

xNames = xDoc.Descendants("name"); 

Điều đó sẽ cung cấp cho bạn một danh sách các yếu tố tên. Sau đó, nếu bạn muốn biến điều đó thành một số List<string> chỉ cần thực hiện việc này:

List<string> list = new List<string>(); 
foreach (XElement element in xNames) 
{ 
    list.Add(element.value); 
} 
4

Xpath thứ hai của bạn bắt đầu bằng //. Đây là tên viết tắt của /descendant-or-self::node(), mà bạn có thể thấy bắt đầu bằng /, có nghĩa là nó tìm kiếm từ gốc của tài liệu, bất kể ngữ cảnh mà bạn sử dụng nó.

Bạn có thể muốn một trong số:

var rowName = row.SelectSingleNode("name"); 

để tìm name nút có trẻ em ngay lập tức của row, hoặc

var rowName = row.SelectSingleNode(".//name"); 

để tìm name nút * bất cứ nơi nào dưới the hàng . Note the .` trong xpath thứ hai này làm cho xpath bắt đầu từ nút ngữ cảnh.

0

Sử dụng sau

 doc.LoadXml(xml); 

      foreach(XmlNode row in doc.SelectNodes("/rows/row")) 
      { 
       string rowName = row.SelectSingleNode("//name").InnerText.ToString(); 
      } 
+0

Điều đó sẽ gây ra cùng một vấn đề như tôi phải bắt đầu, xin lỗi – musefan

+0

Hãy để tôi rephrase lol, tôi đã thoát khỏi/hàng và chỉ cần làm nó như là hàng // và nó đã làm việc cho tôi. –

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