2011-09-19 38 views
10

Có cách nào đơn giản, để nhận tất cả các nút từ tài liệu xml không? Tôi cần tất cả các nút, childnode và như vậy, để kiểm tra xem chúng có thuộc tính nào đó không.C#: Bắt tất cả các nút của tài liệu XML

Hoặc tôi có phải thu thập dữ liệu thông qua tài liệu, yêu cầu mã con không?

+0

Nếu bạn cần phải kiểm tra các thuộc tính nhất định, bạn không cần phải đi qua _every node_ (nút văn bản, nút văn bản, nút bình luận). Chỉ cần đi qua từng nút phần tử hoặc mỗi nút thuộc tính (nghĩa là với LINQ hoặc XSLT). Các nút phần tử là loại nút duy nhất có các thuộc tính. – Abel

+0

Tài liệu này lớn đến mức nào? Tức là nó sẽ được tối ưu hóa giá trị? –

+0

Xem các liên kết [http://forums.asp.net/t/1285409.aspx/1](http://forums.asp.net/t/1285409.aspx/1) [http: //www.developerfusion .com/article/4078/reading-storage-and-transforming-xml-data-in-net/5 /] (http://www.developerfusion.com/article/4078/reading-storing-and-transforming-xml -data-in-net/5 /) [http://weblogs.asp.net/karan/archive/2010/04/29/parse-an-xml-file.aspx](http://weblogs.asp. net/karan/archive/2010/04/29/parse-an-xml-file.aspx) – Prasanth

Trả lời

20

Trong LINQ to XML nó rất dễ dàng:

XDocument doc = XDocument.Load("test.xml"); // Or whatever 
var allElements = doc.Descendants(); 

Vì vậy, để tìm thấy tất cả các yếu tố với một thuộc tính đặc biệt, ví dụ:

var matchingElements = doc.Descendants() 
          .Where(x => x.Attribute("foo") != null); 

Giả sử bạn muốn tất cả các thành phần . Nếu bạn muốn tất cả các nút (bao gồm các nút văn bản v.v., nhưng không phải là bao gồm các thuộc tính dưới dạng các nút riêng biệt), bạn sẽ sử dụng DescendantNodes() để thay thế.

CHỈNH SỬA: Không gian tên trong LINQ to XML là tốt đẹp. Bạn muốn sử dụng:

var matchingElements = doc.Descendants() 
          .Where(x => x.Attribute(XNamespace.Xmlns + "aml") != null); 

hoặc cho một không gian tên khác nhau:

XNamespace ns = "http://some.namespace.uri"; 

var matchingElements = doc.Descendants() 
                         .Where(x => x.Attribute(ns + "foo") != null); 
+0

@ Jeff: Ý của bạn là về việc sử dụng một người lập chỉ mục thay vì một lời gọi phương thức để lấy một thuộc tính? Nếu vậy, cố định. Nếu không, tôi đang bối rối ... –

+0

Vâng, đó là những gì tôi muốn nói. :) –

+0

Tuyệt vời. Abit không liên quan, nhưng làm thế nào tôi sẽ kiểm tra các thuộc tính, trong đó có một không gian tên trong tên của họ? Giống như: xmlns: aml? Nó nói rằng tôi không thể có: trong tên thuộc tính của tôi. – Nicolai

1

Xem LINQ to XML. Điều đó làm những gì bạn cần.

http://www.hookedonlinq.com/LINQtoXML5MinuteOverview.ashx

Bạn có thể sử dụng phần mở rộng SelectMany ví dụ.

Nhưng nếu bạn muốn kiểm tra các giá trị, bạn chỉ có thể sử dụng LINQ để tạo các câu lệnh where.

6

thấy ở đây: Iterating through all nodes in XML file

ngay:

string xml = @" 
    <parent> 
     <child> 
     <nested /> 
     </child> 
     <child> 
     <other> 
     </other> 
     </child> 
    </parent> 
    "; 

    XmlReader rdr = XmlReader.Create(new System.IO.StringReader(xml)); 
    while (rdr.Read()) 
    { 
    if (rdr.NodeType == XmlNodeType.Element) 
    { 
     Console.WriteLine(rdr.LocalName); 
    } 
    } 
+1

Phương pháp này nói chung rất, rất nhanh so với XDocument và các phương thức giống như DOM khác. – Abel

2

XDocument.Descendants sẽ trở lại cho bạn tất cả các nút trong một đếm được bằng phẳng.

0
protected void Page_Load(object sender, EventArgs e) 
    { 

      XmlDocument document = new XmlDocument(); 

      string xmlStr; 
      using (var wc = new WebClient()) 
      { 
       xmlStr = wc.DownloadString("test.xml"); 
      } 

      var xmlDoc = new XmlDocument(); 

      xmlDoc.LoadXml(xmlStr); 

      XmlNode xnod = xmlDoc.DocumentElement; 

      AddWithChildren(xnod, 1); 
} 
+0

Đoạn mã mà không có giải thích hiếm khi hữu ích. Hãy xem xét thêm một số bối cảnh cho câu trả lời của bạn. – Chris

0
public void AddWithChildren(XmlNode xnod, Int32 intLevel) //,XmlDocument xmlDoc 
    { 
     List<IEnumerable> item = new List<IEnumerable>(); 
     XmlNode xnodWorking; 
     String strIndent = new string('-', 2 * intLevel); 
     String strIndent1 = new string('@', 2 * intLevel); 
     if (xnod.NodeType == XmlNodeType.Element) 
     { 
      item.Add(new ListXML(strIndent + xnod.Name, strIndent + xnod.Name, "")); 
      XmlNamedNodeMap mapAttributes = xnod.Attributes; 
      foreach (XmlNode xnodAttribute in mapAttributes) 
      { 
       item.Add(new ListXML(strIndent1 + xnodAttribute.Name, strIndent1 + xnodAttribute.Name, "")); 
      } 
      if (xnod.HasChildNodes) 
      { 
       xnodWorking = xnod.FirstChild; 
       while (xnodWorking != null) 
       { 
        AddWithChildren(xnodWorking, intLevel + 1); 
        xnodWorking = xnodWorking.NextSibling; 
       } 
      } 
     } 
    } 
3

Theo tôi giải pháp đơn giản nhất là sử dụng XPath. Cũng làm việc này nếu bạn có NET 2:

var testDoc = new XmlDocument(); 
       testDoc.LoadXml(str); 
       var tmp = testDoc.SelectNodes("//*"); // match every element 
Các vấn đề liên quan