C#中的后代没有给出正确的值
我是非常新的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;
}
第一个问题是,你只是打电话Descendants("Dialog")
,Descendants("CallVariables")
等那些寻求在全局命名空间的元素 - 但你正在寻找的元素实际上在http://jabber.org/protocol/pubsub
命名空间由于这样的:
<notification xmlns="http://jabber.org/protocol/pubsub">
当你看到xmlns="..."
,设置为所有后代的默认命名空间。该缺省值可以被指定名称空间的元素名称显式覆盖 - 或者可以由xmlns=...
由另一个后代进行更改。 (您的文档包含默认的多层次。)
幸运的是,LINQ到XML可以很容易地指定命名空间,因为从string
到XNamespace
隐式转换,以及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,然后检查字符串表示是否包含一个特定的字符串(而不是检查特定元素的存在,例如),但这些应该让你开始。
感谢您的回答,我正在寻找什么,我不知道名称空间感谢很多的解释也 请你能告诉我为什么有人给我 - 在问题中提高自己下一次 – bavs
我不知道你真正想要的,但这提取的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;
}
}
使用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();
}
}
}
只是代码没有任何解释isn对于你做出的改变和原因做了彻底的解释几乎没有什么帮助。 –
一张图片胜过1000字。编写具有良好变量名称的代码,易于阅读和组织良好的字词优于1,000,000,000字。现在您是否必须计算零的数量才能知道数字是十亿,还是应该使用十亿而不是数字0和1.您认为我的代码需要注释吗?有什么意见?编写代码然后编写解释最好。选择好的变量名称可以消除评论的需要。 – jdweng
我没有征求意见。我问了解释。对于为什么需要担心命名空间,您还没有给出*任何解释,例如,这是最重要的方面。 (我也考虑过你的方法来*取第一个命名空间 - 如果文档后来包含其他'dialogs'元素在不同的命名空间中怎么办?) –
你的代码和xml不一致。我不知道你需要什么。 “如果”条款没有任何意义。不知道parsingmsg指的是什么。使用后代而不是祖先要容易得多。 – jdweng
@jdweng 请帮助我我想从这个XML中得到id我该怎么办我不知道什么是代码来获取ID我试过这段代码但没有帮我 – bavs