如何从XMLDocument中提取SMSText与Status元素数据?
从SOAP响应XML中提取SMSText和Status数据
我来帮你搞定这个XML提取的问题!你的SOAP响应因为包含命名空间和DiffGram结构,直接用简单的标签查找会踩坑,先看看你当前代码的几个问题:
- 没有将SOAP响应内容加载到
XmlDocument实例中(缺少LoadXml或Load操作) GetElementsByTagName方法不支持完整XPath路径,它只能按标签名查找,且没处理XML命名空间- 实际的短信数据不在
GetMessage节点下,而是嵌套在diffgr:diffgram/NewDataSet/inLogSMS层级中
下面给你两种可行的解决方案:
方案一:使用XmlDocument(适配你当前的代码风格)
你需要先处理XML命名空间,再用XPath定位到目标节点:
// 假设soapResponse是你的SOAP响应字符串 string soapResponse = @"<?xml version=""1.0"" encoding=""utf-8""?> <soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema""> <soap:Body> <GetMessage xmlns=""http://tempuri.org/""> <GetMessageResult> <xs:schema id=""NewDataSet"" xmlns="""" xmlns:xs=""http://www.w3.org/2001/XMLSchema"" xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata""> <!-- 省略schema内容 --> </xs:schema> <diffgr:diffgram xmlns:msdata=""urn:schemas-microsoft-com:xml-msdata"" xmlns:diffgr=""urn:schemas-microsoft-com:xml-diffgram-v1""> <NewDataSet xmlns="""""> <inLogSMS diffgr:id=""SMS1"" msdata:rowOrder=""0""> <SMSText>Test2</SMSText> <Status>New</Status> </inLogSMS> <inLogSMS diffgr:id=""SMS2"" msdata:rowOrder=""1""> <SMSText>TEST</SMSText> <Status>New</Status> </inLogSMS> </NewDataSet> </diffgr:diffgram> </GetMessageResult> </GetMessage> </soap:Body> </soap:Envelope>"; var responseXml = new XmlDocument(); responseXml.LoadXml(soapResponse); // 创建命名空间管理器,处理XML中的各个命名空间 XmlNamespaceManager nsManager = new XmlNamespaceManager(responseXml.NameTable); nsManager.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/"); nsManager.AddNamespace("tempuri", "http://tempuri.org/"); nsManager.AddNamespace("diffgr", "urn:schemas-microsoft-com:xml-diffgram-v1"); // 用XPath定位到所有inLogSMS节点 XmlNodeList smsNodes = responseXml.SelectNodes("//diffgr:diffgram/NewDataSet/inLogSMS", nsManager); foreach (XmlNode smsNode in smsNodes) { string smsText = smsNode["SMSText"]?.InnerText ?? "无内容"; string status = smsNode["Status"]?.InnerText ?? "无内容"; Console.WriteLine($"短信内容: {smsText}, 状态: {status}"); }
方案二:使用LINQ to XML(更简洁易用)
如果可以使用LINQ to XML,代码会更简洁,处理命名空间也更直观:
XDocument doc = XDocument.Parse(soapResponse); // 定义需要用到的命名空间 XNamespace diffgrNs = "urn:schemas-microsoft-com:xml-diffgram-v1"; // 查找所有inLogSMS节点 var smsItems = doc.Descendants(diffgrNs + "diffgram") .Elements("NewDataSet") .Elements("inLogSMS"); foreach (var item in smsItems) { string smsText = item.Element("SMSText")?.Value ?? "无内容"; string status = item.Element("Status")?.Value ?? "无内容"; Console.WriteLine($"短信内容: {smsText}, 状态: {status}"); }
两种方案都能正确提取到<SMSText>和<Status>的内容,运行后会输出:
短信内容: Test2, 状态: New 短信内容: TEST, 状态: New
内容的提问来源于stack exchange,提问作者user9475328
相关产品推荐
相关产品推荐

