C#中的后代没有给出正确的值

C#中的后代没有给出正确的值,c#,xml,linq-to-xml,C#,Xml,Linq To Xml,我对使用C语言的XML非常陌生,我有一个XML,需要在父级中遍历特定的子级 我需要得到id和调用变量,我这样做了,但每次都没有通过循环 在得到所需的树之前,是否需要遍历xml的所有父级 xml <message xmlns="jabber:client" to="1072@finesse1.dcloud.cisco.com" id="/finesse/api/User/1072/Dialogs__1072@finesse1.dcloud.cisco.com__104Y2" from="pu

我对使用C语言的XML非常陌生,我有一个XML,需要在父级中遍历特定的子级 我需要得到id和调用变量,我这样做了,但每次都没有通过循环

在得到所需的树之前,是否需要遍历xml的所有父级

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>

我不确定您真正想要的是什么,但这会将id和callvariables提取到dialog对象列表中。如果要使用ling-to-xml,需要首先解析XDocument,然后循环遍历所需的子体。最后,通过另一个循环从callvariables获取值

别忘了,在最后关心例外

        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;

            }

        }
公共类对话框
{
公共int id;
public List callVariables=new List();
公共结构调用变量
{
公共字符串名称;
公共字符串值;
}
}
公共列表GetDialogsFromXml(字符串xml)
{
尝试
{
XDocument doc=XDocument.Parse(xml);
列表对话框=新建列表();
foreach(doc.Root.substands(“{http://jabber.org/protocol/pubsub}对话框“))
{
int dialogid=int.Parse(item.Element(“{http://jabber.org/protocol/pubsub}(i)价值);
List callvariables=new List();
foreach(项中的XElement callVariableNode.subjects(“{http://jabber.org/protocol/pubsub}callvariables”).FirstOrDefault()子体(“{http://jabber.org/protocol/pubsub}调用变量“))
{
添加(新建对话框.CallVariable(){name=callVariableNode.Element(“{http://jabber.org/protocol/pubsub}name“).Value,Value=callVariableNode.Element(“{http://jabber.org/protocol/pubsub}值“).value});
}
Add(newdialog(){id=dialogid,callVariables=callVariables});
}
返回对话框;
}
捕获(例外e)
{
//如果出了什么问题就处理
返回null;
}
}

我不确定您真正想要什么,但这会将id和callvariables提取到对话框对象列表中。如果要使用ling-to-xml,需要首先解析XDocument,然后循环遍历所需的子体。最后,通过另一个循环从callvariables获取值

别忘了,最后要关心例外情况

        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;

            }

        }
公共类对话框
{
公共int id;
public List callVariables=new List();
公共结构调用变量
{
公共字符串名称;
公共字符串值;
}
}
公共列表GetDialogsFromXml(字符串xml)
{
尝试
{
XDocument doc=XDocument.Parse(xml);
列表对话框=新建列表();
foreach(doc.Root.substands(“{http://jabber.org/protocol/pubsub}对话框“))
{
int dialogid=int.Parse(item.Element(“{http://jabber.org/protocol/pubsub}(i)价值);
List callvariables=new List();
foreach(项中的XElement callVariableNode.subjects(“{http://jabber.org/protocol/pubsub}callvariables”).FirstOrDefault()子体(“{http://jabber.org/protocol/pubsub}调用变量“))
{
添加(新建对话框.CallVariable(){name=callVariableNode.Element(“{http://jabber.org/protocol/pubsub}name“).Value,Value=callVariableNode.Element(“{http://jabber.org/protocol/pubsub}值“).value});
}
Add(newdialog(){id=dialogid,callVariables=callVariables});
}
返回对话框;
}
捕获(例外e)
{
//如果出了什么问题就处理
返回null;
}
}

使用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();

        }
    }
}

使用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();

        }
    }
}

第一个问题是,您只是调用
子体(“对话框”)
子体(“调用变量”)
等。这些子体在全局命名空间中查找元素,但您查找的所有元素实际上都在
的命名空间中http://jabber.org/protocol/pubsub
因此:

<notification xmlns="http://jabber.org/protocol/pubsub">
作为第二个问题,请看第二个循环:

foreach (XElement callVariables in xmlroots.Descendants("CallVariables"))
{
    foreach (XElement callVariable in xmlroots.Descendants("CallVariable"))
    {
        list = callVariable.Element("value").Value;
    }
}
这有三个问题:

  • 文档中没有名为
    CallVariables
    的元素-而是有
    CallVariables
    。XML区分大小写
  • 我确信您不希望在每个callvariables元素中组合每个call变量。相反,我希望得到如下结果:

    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
        }
    }
    
  • 目前,您只是替换循环体中的
    列表
    变量,这意味着只有循环的最后一次迭代才是真正有用的


代码可能还有很多其他方面的错误——解析XML,然后检查字符串表示是否包含特定字符串(而不是检查特定元素的存在,例如)似乎有些奇怪第一个问题是,您只是在调用
子体(“Dialog”)
子体(“CallVariables”)
等。这些元素在全局命名空间中查找元素-但您查找的所有元素实际上都在
的命名空间中http://jabber.org/protocol/pubsub
因此: