2017-09-15 83 views
0

我是非常新的XML使用C#我有一個XML我需要通過父母的具體子女 我需要獲取id和調用變量變量我做到了這一點,但每次都沒有通過循環C#中的後代沒有給出正確的值

我是否需要通過所有的父母的xml,直到我得到了我想要的樹?

的XML

<message xmlns="jabber:client" to="[email protected]" id="/finesse/api/User/1072/[email protected]__104Y2" from="pubsub.finesse1.dcloud.cisco.com"> 
<event xmlns="http://jabber.org/protocol/pubsub#event"> 
<items node="/finesse/api/User/1072/Dialogs"> 
    <item id="460c2d27-c914-4c24-a95f-edf9f8df45c21535"> 
    <notification xmlns="http://jabber.org/protocol/pubsub"> 
     <Update> 
     <data> 
      <dialogs> 
      <Dialog> 
       <associatedDialogUri></associatedDialogUri> 
       <fromAddress>1071</fromAddress> 
       <id>18639330</id> 
       <mediaProperties> 
       <DNIS>1072</DNIS> 
       <callType>AGENT_INSIDE</callType> 
       <dialedNumber>1072</dialedNumber> 
       <outboundClassification></outboundClassification> 
       <callvariables> 
        <CallVariable> 
        <name>callVariable1</name> 
        <value></value> 
        </CallVariable> 
        <CallVariable> 
        <name>callVariable2</name> 
        <value></value> 
        </CallVariable> 
        <CallVariable> 
        <name>callVariable3</name> 
        <value></value> 
        </CallVariable> 
        <CallVariable> 
        <name>callVariable4</name> 
        <value></value> 
        </CallVariable> 
        <CallVariable> 
        <name>callVariable5</name> 
        <value></value> 
        </CallVariable> 
        <CallVariable> 
        <name>callVariable6</name> 
        <value></value> 
        </CallVariable> 
        <CallVariable> 
        <name>callVariable7</name> 
        <value></value> 
        </CallVariable> 
        <CallVariable> 
        <name>callVariable8</name> 
        <value></value> 
        </CallVariable> 
        <CallVariable> 
        <name>callVariable9</name> 
        <value></value> 
        </CallVariable> 
        <CallVariable> 
        <name>callVariable10</name> 
        <value></value> 
        </CallVariable> 
       </callvariables> 
       </mediaProperties> 
       <mediaType>Voice</mediaType> 
       <participants> 
       <Participant> 
        <actions> 
        <action>ANSWER</action> 
        </actions> 
        <mediaAddress>1072</mediaAddress> 
        <mediaAddressType>AGENT_DEVICE</mediaAddressType> 
        <startTime>2017-09-15T19:23:36.872Z</startTime> 
        <state>ALERTING</state> 
        <stateCause></stateCause> 
        <stateChangeTime>2017-09-15T19:23:36.872Z</stateChangeTime> 
       </Participant> 
       <Participant> 
        <actions> 
        <action>UPDATE_CALL_DATA</action> 
        <action>DROP</action> 
        </actions> 
        <mediaAddress>1071</mediaAddress> 
        <mediaAddressType>AGENT_DEVICE</mediaAddressType> 
        <startTime>2017-09-15T19:23:36.609Z</startTime> 
        <state>INITIATED</state> 
        <stateCause></stateCause> 
        <stateChangeTime>2017-09-15T19:23:36.819Z</stateChangeTime> 
       </Participant> 
       </participants> 
       <state>ALERTING</state> 
       <toAddress>1072</toAddress> 
       <uri>/finesse/api/Dialog/18639330</uri> 
      </Dialog> 
      </dialogs> 
     </data> 
     <event>POST</event> 
     <requestId></requestId> 
     <source>/finesse/api/User/1072/Dialogs</source> 
     </Update> 
    </notification> 
    </item> 
</items> 
</event> 
</message> 

那就是 代碼

XElement xmlroots = XElement.Parse(parsingNewXML); 
//Dialog = xmlroots.Element("Dialog").Value; 
var CallVariable = parsingNewXML.Contains("CallVariable"); 
var startCall = parsingNewXML.Contains("ALERTING"); 

if (CallVariable == true && startCall == true) 
{ 

    foreach (XElement callID in xmlroots.Descendants("Dialog")) 
    { 
     DialogID = callID.Element("id").Value; 
     //System.Windows.MessageBox.Show(DialogID); 
     System.Windows.Application.Current.Dispatcher.BeginInvoke(
     DispatcherPriority.Background, 
     new Action(() => ((MainWindow)System.Windows.Application.Current.MainWindow).answerCall.Visibility = Visibility.Visible)); 
    } 
    foreach (XElement callVariables in xmlroots.Descendants("CallVariables")) 
    { 
     foreach (XElement callVariable in xmlroots.Descendants("CallVariable")) 
     { 
      list = callVariable.Element("value").Value; 
     } 
    } 
    // state = second.Element("state").Value; 
} 
+0

你的代碼和xml不一致。我不知道你需要什麼。 「如果」條款沒有任何意義。不知道parsingmsg指的是什麼。使用後代而不是祖先要容易得多。 – jdweng

+0

@jdweng 請幫助我我想從這個XML中得到id我該怎麼辦我不知道什麼是代碼來獲取ID我試過這段代碼但沒有幫我 – bavs

回答

5

第一個問題是,你只是打電話Descendants("Dialog")Descendants("CallVariables")等那些尋求在全局命名空間的元素 - 但你正在尋找的元素實際上http://jabber.org/protocol/pubsub命名空間由於這樣的:

<notification xmlns="http://jabber.org/protocol/pubsub"> 

當你看到xmlns="...",設置爲所有後代的默認命名空間。該缺省值可以被指定名稱空間的元素名稱顯式覆蓋 - 或者可以由xmlns=...由另一個後代進行更改。 (您的文檔包含默認的多層次。)

幸運的是,LINQ到XML可以很容易地指定命名空間,因爲從stringXNamespace隱式轉換,以及XName +(XNamespace, string)操作:

XDocument doc = XDocument.Parse(...); 
XNamespace pubsub = "http://jabber.org/protocol/pubsub"; 
// Find all the descendants with a local name of "Dialog" in the 
// namespace specified by the pubsub variable 
foreach (XElement dialog in doc.Descendants(pubsub + "Dialog")) 
{ 
    ... 
} 

作爲第二個問題,看這第二個循環:

foreach (XElement callVariables in xmlroots.Descendants("CallVariables")) 
{ 
    foreach (XElement callVariable in xmlroots.Descendants("CallVariable")) 
    { 
     list = callVariable.Element("value").Value; 
    } 
} 

有三個問題是:

  • 您的文檔中沒有任何元素叫做CallVariables - 取而代之的是callvariables。 XML區分大小寫。
  • 我敢肯定你不想組合調用變量調用變量元素。相反,我期望是這樣的:

    foreach (var callVariables in doc.Descendants(pubsub + "callvariables")) 
    { 
        // Note use of Elements, not Descendants. You still need 
        // the namespace part though... 
        foreach (var callVariable in callVariables.Elements(pubsub + "CallVariable")) 
        { 
         // Do what you want 
        } 
    } 
    
  • 目前你剛剛更換的循環,這意味着只在循環的最後一次迭代是真正有用的身體list變量。

有可能是很多其他的事情錯誤的代碼 - 這似乎很奇怪解析XML,然後檢查字符串表示是否包含一個特定的字符串(而不是檢查特定元素的存在,例如),但這些應該讓你開始。

+0

感謝您的回答,我正在尋找什麼,我不知道名稱空間感謝很多的解釋也 請你能告訴我爲什麼有人給我 - 在問題中提高自己下一次 – bavs

0

我不知道你真正想要的,但這提取的ID和callvariables到對話框對象的列表。如果你想使用ling-to-xml,你需要首先解析一個XDocument,然後遍歷所需的後代。最後,只需從另一個循環獲得調用變量的值。

不要忘了,關心最後的例外。

 public class Dialog 
     { 
      public int id; 
      public List<CallVariable> callVariables = new List<CallVariable>(); 
      public struct CallVariable 
      { 
       public string name; 
       public string value; 
      } 

     } 

     public List<Dialog> GetDialogsFromXml(string xml) 
     { 
      try 
      { 
       XDocument doc = XDocument.Parse(xml); 
       List<Dialog> dialogs = new List<Dialog>(); 

       foreach (XElement item in doc.Root.Descendants("{http://jabber.org/protocol/pubsub}Dialog")) 
       { 

        int dialogid = int.Parse(item.Element("{http://jabber.org/protocol/pubsub}id").Value); 

        List<Dialog.CallVariable> callvariables = new List<Dialog.CallVariable>(); 

        foreach (XElement callVariableNode in item.Descendants("{http://jabber.org/protocol/pubsub}callvariables").FirstOrDefault().Descendants("{http://jabber.org/protocol/pubsub}CallVariable")) 
        { 
         callvariables.Add(new Dialog.CallVariable() { name=callVariableNode.Element("{http://jabber.org/protocol/pubsub}name").Value, value = callVariableNode.Element("{http://jabber.org/protocol/pubsub}value").Value }); 
        } 

        dialogs.Add(new Dialog() { id = dialogid, callVariables = callvariables }); 

       } 
       return dialogs; 
      } 
      catch (Exception e) 
      { 
       //handle if something goes wrong 
       return null; 

      } 

     } 
-1

使用xml linq。您還需要使用名稱空間來獲取元素。您可以通過像獲取對話框那樣獲取LocalName來避免命名空間。 :

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Xml; 
using System.Xml.Linq; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     const string FILENAME = @"c:\temp\test.xml"; 
     static void Main(string[] args) 
     { 
      XDocument doc = XDocument.Load(FILENAME); 

      XElement dialogs = doc.Descendants().Where(x => x.Name.LocalName == "dialogs").FirstOrDefault(); 
      XNamespace ns = dialogs.GetDefaultNamespace(); 

      var results = dialogs.Elements(ns + "Dialog").Select(x => new { 
       id = (int)x.Element(ns + "id"), 
       associatedDialogUri = (string)x.Element(ns + "associatedDialogUri"), 
       fromAddress = (string)x.Element(ns + "fromAddress"), 
       dnis = (int)x.Descendants(ns + "DNIS").FirstOrDefault(), 
       callType = (string)x.Descendants(ns + "callType").FirstOrDefault(), 
       dialedNumber = (int)x.Descendants(ns + "dialedNumber").FirstOrDefault(), 
       outboundClassification = (string)x.Descendants(ns + "outboundClassification").FirstOrDefault(), 
       callVariables = x.Descendants(ns + "CallVariable").Select(y => new { 
        name = (string)y.Element(ns + "name"), 
        value = (string)y.Element(ns + "value") 
       }).ToList(), 
       participants = x.Descendants(ns + "Participant").Select(y => new 
       { 
        actions = y.Descendants(ns + "action").Select(z => (string)z).ToList(), 
        namemediaAddress = (int)y.Element(ns + "mediaAddress"), 
        mediaAddressType = (string)y.Element(ns + "mediaAddressType"), 
        startTime = (DateTime)y.Element(ns + "startTime"), 
        state = (string)y.Element(ns + "state"), 
        stateCause = (string)y.Element(ns + "stateCause"), 
        stateChangeTime = (DateTime)y.Element(ns + "stateChangeTime") 
       }).ToList(), 
       state = (string)x.Descendants(ns + "state").FirstOrDefault(), 
       toAddress = (int)x.Descendants(ns + "toAddress").FirstOrDefault(), 
       uri = (string)x.Descendants(ns + "uri").FirstOrDefault() 

      }).ToList(); 

     } 
    } 
} 
+2

只是代碼沒有任何解釋isn對於你做出的改變和原因做了徹底的解釋幾乎沒有什麼幫助。 –

+0

一張圖片勝過1000字。編寫具有良好變量名稱的代碼,易於閱讀和組織良好的字詞優於1,000,000,000字。現在您是否必須計算零的數量才能知道數字是十億,還是應該使用十億而不是數字0和1.您認爲我的代碼需要註釋嗎?有什麼意見?編寫代碼然後編寫解釋最好。選擇好的變量名稱可以消除評論的需要。 – jdweng

+1

我沒有徵求意見。我問了解釋。對於爲什麼需要擔心命名空間,您還沒有給出*任何解釋,例如,這是最重要的方面。 (我也考慮過你的方法來*取第一個命名空間 - 如果文檔後來包含其他'dialogs'元素在不同的命名空間中怎麼辦?) –

相關問題