2013-03-11 12 views
1

我只是試圖從XML中讀取特定節點,並將其用作條件中的字符串變量。這讓我到XML文件,並給我所有的東西。從XML文件讀取單個節點並將其用作條件

string url = @"http://agent.mtconnect.org/current"; 
     XmlDocument xmlDoc = new XmlDocument(); 
     xmlDoc.Load(url); 
     richTextBox1.Text = xmlDoc.InnerXml; 

但我需要 「OFF」 的電源狀態 「ON」(XML部分下面,可以在線查看整個XML)

<Events><PowerState dataItemId="p2" timestamp="2013-03-11T12:27:30.275747" name="power" sequence="4042868976">ON</PowerState></Events> 

我已經試過我所知道的一切。我只是不熟悉XML文件。其他職位讓我無處可去。 幫助請!

+0

您可能想要查看XPath。這就像XML的SQL。 – JDB 2013-03-11 12:46:51

+0

請參閱以下文章: http://stackoverflow.com/questions/670563/linq-to-read-xml – 2013-03-11 12:48:13

回答

0

如果你想避免LINQ,或者如果它不爲你工作,你可以使用直XML遍歷此:

string url = @"http://agent.mtconnect.org/current"; 
    System.Xml.XmlDocument xmlDoc = new System.Xml.XmlDocument(); 
    xmlDoc.Load(url); 
    System.Xml.XmlNamespaceManager theNameManager = new System.Xml.XmlNamespaceManager(xmlDoc.NameTable); 
    theNameManager.AddNamespace("mtS", "urn:mtconnect.org:MTConnectStreams:1.2"); 
    theNameManager.AddNamespace("m", "urn:mtconnect.org:MTConnectStreams:1.2"); 
    theNameManager.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance"); 

    System.Xml.XmlElement DeviceStreams = (System.Xml.XmlElement)xmlDoc.SelectSingleNode("descendant::mtS:DeviceStream", theNameManager); 
    System.Xml.XmlNodeList theStreams = DeviceStreams.SelectNodes("descendant::mtS:ComponentStream", theNameManager); 

    foreach (System.Xml.XmlNode CompStream in theStreams) 
    { 
     if (CompStream.Attributes["component"].Value == "Electric") 
     { 
      System.Xml.XmlElement EventElement = (System.Xml.XmlElement)CompStream.SelectSingleNode("descendant::mtS:Events", theNameManager); 
      System.Xml.XmlElement PowerElement = (System.Xml.XmlElement)EventElement.SelectSingleNode("descendant::mtS:PowerState", theNameManager); 
      Console.Out.WriteLine(PowerElement.InnerText); 
      Console.In.Read(); 
     } 
    } 

當遍歷根節點中具有默認名稱空間的任何文檔,我發現有一個命名空間管理器是必要的。沒有它,這個文件就是不可導航的。

我在控制檯應用程序中創建了此代碼。它爲我工作。我也不是大師,我可能會在這裏犯一些錯誤。我不確定是否有某種方法可以引用缺省命名空間而不用命名它(mtS)。任何知道如何使這個更清潔或更高效的人請評論。

編輯:因爲只有一個元素在那裏,其innerText是所有你會得到

if (CompStream.Attributes["component"].Value == "Electric") 
{ 
    Console.Out.WriteLine(((System.Xml.XmlElement)CompStream.SelectSingleNode("descendant::mtS:Events", theNameManager)).InnerText;); 
    Console.In.Read(); 
} 

對於「悶響」少了一個級別,你可以改變這一點。

+0

這工作。但它似乎很笨重。正如你所看到的,這個XML不斷變化,我每隔30秒就用一個定時器來看它。我走錯路了嗎? Linq會爲我想要做的更好嗎? – user2139891 2013-03-11 17:43:38

+0

也許但我不知道如何使用LINQ2XML。如果@the_joric發佈的代碼有效,我會建議使用它。少用幾行。它也可能看起來笨重,但是這個過程中最長的一部分將會得到這個文件。其餘的只是非常花哨的文本操作。嘗試一下你的用例,看看你得到了什麼。你可能會對錶演感到驚訝。此解決方案的好處在於,如果您最終需要使用任何其他節點,您可以輕鬆捕獲它們。 – 2013-03-11 17:49:38

2

您可以嘗試LINQ2XML爲:

string value = (string) (XElement.Load("http://agent.mtconnect.org/current") 
      .Descendants().FirstOrDefault(d => d.Name.LocalName == "PowerState")) 
+0

嘗試此並得到System.Core.dll中發生類型'System.InvalidOperationException'未處理的異常 – user2139891 2013-03-11 17:39:49

+0

Linq似乎保持連接到其他只運行一次,並完成它的XML。 the_joric的代碼中缺少什麼? – user2139891 2013-03-11 22:19:55

+0

我的錯。修復了代碼。您的文檔具有根名稱空間。在這種情況下,您需要使用'LocalName'或指定名稱中的名稱空間。另外我把'First()'改成'FirstOrDefault()'。前者在元素未找到時引發異常,而後者僅返回null。 – 2013-03-12 15:02:34

相關問題