2017-09-15 53 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'元素在不同的命名空间中怎么办?) –

相关问题