2010-09-20 77 views
9

假設我有以下XML文檔。使用C#獲取XML文檔的屬性值

<reply success="true">More nodes go here</reply> 

如何獲取屬性成功的值,在這種情況下,它將是字符串「true」。

+0

必須使用「XmlDocument」或任何其他特定的XML處理API嗎? – 2010-09-20 10:57:20

+0

@Daniel:之前你甚至去那裏:http://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags/1732454#1732454 ;-) – 2010-09-22 19:44:26

+0

@Isak:我不打算去RegEx路線!提出使用DOM API(即'XmlDocument')的「XML文檔」的問題,但我問的是否是必需的,或者是否可以接受基於流/基於SAX的API,如「XmlReader」。 – 2010-09-23 06:32:45

回答

22

我會嘗試這樣的事:

XmlDocument doc = new XmlDocument(); 
doc.LoadXml("<reply success=\"true\">More nodes go here</reply>"); 

XmlElement root = doc.DocumentElement; 

string s = root.Attributes["success"].Value; 
+0

您也可以嘗試按名稱獲取屬性:root.Attributes [「succes」]。值 – 2010-09-20 11:09:25

+1

按位置訪問屬性通常是非常糟糕的做法,因爲根據定義,XML元素上屬性的排序並不重要。在這個微不足道的案例中,它是有效的,因爲只有一個屬性,但這只是幸運的。 – 2010-09-22 17:24:50

+0

你是對的,我已經在我的第一個評論中提出了替代方案。我現在編輯了我原來的帖子來顯示它。 – 2010-09-23 05:49:23

-1

下面是一個使用XmlReader的替代解決方案可能是一個小比使用XmlDoument更有效,雖然這是這樣一個小的XML文檔proably可以忽略不計

string input = "<reply success=\"true\">More nodes go here</reply>"; 

using (XmlReader xmlReader = XmlReader.Create(new StringReader(input))) 
{ 
    xmlReader.MoveToContent(); 
    string success = xmlReader.GetAttribute("success"); 
    Console.WriteLine(success); 
} 
+1

哇,連續三個答案都會以三種不同的方式做同樣的錯誤事情。 – 2010-09-22 17:26:13

+0

我認爲原來問題給人的一般印象是我們應該找到第一個屬性的值。我現在已更正了我的代碼,以執行您建議的更普遍有用的操作。 – explorer 2010-09-22 19:50:14

+0

@Robert:夠公平,回答改變 – 2010-09-23 06:41:44

2
using System; 
    using System.Linq; 
    using System.Xml.Linq; 

    class MyClass 
    { 
     static void Main(string[] args) 
     { 
      XElement xmlcode = 
      XElement.Parse("<reply success=\"true\">More nodes go </reply>"); 

      var successAttributes = 
       from attribute in xmlcode.Attributes() 
       where attribute.Name.LocalName=="success" 
       select attribute ; 

      if(successAttributes.Count()>0) 
      foreach (var sa in successAttributes) 
      { 
       Console.WriteLine(sa.Value);   
      } 
      Console.ReadLine(); 
     } 
    } 
+0

看到我對Rewinder的回答的評論;這個答案有完全相同的問題。它將在這個微不足道的案件中起作用,但總的來說這是一個非常糟糕的做法。 – 2010-09-22 17:25:45

+0

是的,你是對的。我編輯代碼以使其查找並打印XML片段中所有'成功'屬性值的值,而不管它們的順序或位置如何。現在給我回零:) – explorer 2010-09-22 19:43:01

8

如果將XML加載到XmlDocument中,有多種方法可以獲取該屬性的值。您可以使用XPath找到屬性:

XmlAttribute a = doc.SelectSingleNode("/reply/@success"); 
Console.Write(a.Value); 

如果你已經有了XmlElement出現的屬性(在這種情況下是文檔元素),那麼你可以只使用GetAttribute

Console.Write(doc.DocumentElement.GetAttribute("success")); 

如果您使用XPathDocumentXmlReaderXDocument,也有類似的方法。

但是,在所有情況下,您都希望通過其名稱獲取屬性,而不是其位置。在你的測試案例中,只有一個屬性;在任何實際應用程序中,可能都有多個屬性,並且XML中的屬性排序並不重要。這兩個元素在語義上是等效的:

<a foo='true' bar='false'/> 

<a bar='false' foo='true'/> 

您甚至不知道XML解析器會按照它們在文檔中出現的順序顯示屬性;根據實現情況,解析器可能會按字母順序或隨機順序將它們提供給您。 (我見過)

+0

但是我們在這裏專門討論C#/ .NET,並且在MS文檔中沒有提到XmlReader或XmlDocument在任何非文檔/輸入順序中索引屬性,所以如果需求是爲了「獲得出現在輸入XML中的第一個屬性」,這可以通過查找索引爲零的屬性來實現。當然,問題並不是要求「第一個」屬性,因此在這種情況下使用屬性名稱而不是索引是正確的。 – 2010-09-23 06:44:35

+1

MS文檔中沒有保證'XmlDocument'(實際上是''XmlNamedNodeMap'')以任何確定性順序對屬性進行索引。有一些示例顯示節點按照它們添加到地圖的順序進行索引。但是這些例子在這個頁面 - http://msdn.microsoft.com/en-us/library/7sf9z378.aspx - 什麼,祈禱,是標題中的第一個字? – 2010-09-23 09:10:31

1
var at = 
XElement.Parse("<reply success=\"true\">More nodes go </reply>").Attribute("success"); 
if (at != null) Console.Write(at.Value); 
0

以下代碼適用於我。

String strXML = "<reply success=\"true\">More nodes go here</reply>"; 

    using (XmlReader reader = XmlReader.Create(new StringReader(strXML))) 
    { 
      reader.ReadToFollowing("reply"); 
      reader.MoveToContent(); 
      string strValue = reader.GetAttribute("success"); 
      Console.WriteLine(strValue); 
    }