2011-09-19 55 views
10

是否有一種簡單的方法來從xml文檔獲取所有節點?我需要每個節點,孩子節點等來檢查它們是否具有某些屬性。C#:獲取XML文檔的所有節點

或者我將不得不爬過文檔,要求孩子節點?

+0

如果你需要檢查某些屬性,你不需要經過_every node_(文本節點,文檔節點,註釋節點)。只需遍歷每個元素節點或每個屬性節點(即使用LINQ或XSLT)。元素節點是唯一具有屬性的節點類型。 – Abel

+0

這個文件有多大?即是否值得優化? –

+0

查看鏈接[http://forums.asp.net/t/1285409.aspx/1](http://forums.asp.net/t/1285409.aspx/1)[http://www.developerfusion的.com /文章/ 4078 /讀取儲存和 - 轉化-XML的數據在網/ 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

回答

20

LINQ to XML中這是非常簡單的:

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

因此,要找到具有特定屬性的所有元素,例如:

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

假設你想要所有元素。如果您想要所有節點(包括文本節點等,但是而不是包括作爲單獨節點的屬性),您可以使用DescendantNodes()來代替。

編輯:LINQ to XML命名空間很好。你會使用:

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

或不同的命名空間:

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

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

@Jeff:你的意思是使用索引器而不是方法調用來獲取屬性?如果是這樣,修復。如果沒有,我很困惑... –

+0

是的,這就是我的意思。 :) –

+0

優秀。升技無關,但我將如何檢查名稱中有名稱空間的屬性?喜歡:xmlns:aml?它說我不能有:以我的屬性名稱。 – Nicolai

6

在這裏看到:Iterating through all nodes in XML file

不久:

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

與XDocument和其他類似DOM的方法相比,此方法通常非常快速。 – Abel

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

沒有解釋的代碼轉儲很少有幫助。請考慮在答案中添加一些上下文。 – 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

在最簡單的解決方案是使用XPath我的意見。如果你有.NET 2,這也可以工作:

var testDoc = new XmlDocument(); 
       testDoc.LoadXml(str); 
       var tmp = testDoc.SelectNodes("//*"); // match every element