Descendants in C# do not give the right value

I am very new in XML using C# i have a XML i need to go through specific children in the parent i need to get the id and the call variables variables i did this but every time did not go through the loop

Do i need to go through all of the parent of xml until i got the tree that i want ??

the xml

<message xmlns="jabber:client" to="1072@finesse1.dcloud.cisco.com" id="/finesse/api/User/1072/Dialogs__1072@finesse1.dcloud.cisco.com__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>

that is the Code

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;
}
Jon Skeet
people
quotationmark

The first problem is that you're just calling Descendants("Dialog"), Descendants("CallVariables") etc. Those look for elements in the global namespace - but all the elements you're looking for are actually in a namespace of http://jabber.org/protocol/pubsub due to this:

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

When you see xmlns="..." that sets the default namespace for all descendants. That default can be explicitly overridden by element names that specify a namespace - or it can be changed by another descendant with xmlns=.... (Your document contains multiple levels of defaults.)

Fortunately, LINQ to XML makes it easy to specify namespaces, due to the implicit conversion from string to XNamespace, and the XName +(XNamespace, string) operator:

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"))
{
    ...
}

As a second issue, look at this second loop:

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

There are three problems with this:

  • There are no elements in your document called CallVariables - there's callvariables instead. XML is case-sensitive.
  • I'm sure you don't want the combination of every call variable in every call variables element. Instead, I'd expect something like:

    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
        }
    }
    
  • Currently you're just replacing the list variable in the body of the loop, which means only the last iteration of the loop is actually useful.

There may well be many other things wrong with the code - it seems odd to parse the XML and then check whether the string representation contains a particular string (rather than checking for the existence of a particular element, for example) but those should get you started.

people

See more on this question at Stackoverflow