.Net Core - 使用 LINQ to XML 从 SOAP 响应中按名称获取元素
.Net Core - Use LINQ to XML to get element by name from SOAP response
我发现了很多此类问题的实例,但出于某种原因 none 所有这些问题的答案都对我有用。
我得到的 SOAP 响应非常简单:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<GetDataAsStringResponse xmlns="http://tempuri.org/">
<GetDataAsStringResult>true</GetDataAsStringResult>
</GetDataAsStringResponse>
</s:Body>
</s:Envelope>
这些是我为解析它并到达 "GetDataAsStringResult" 元素而尝试过的所有选项:
var doc = XDocument.Parse(responseString);
XNamespace xmlns = "xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"";
XNamespace nsTempuri = "xmlns=\"http://tempuri.org/\"";
var namespacePrefix = doc.Root.GetNamespaceOfPrefix("s");
var resultElement = doc.Descendants("GetDataAsStringResult"); //yields no results
var resultElement1 = doc.Descendants(nsTempuri + "GetDataAsStringResult"); //yields no results
var resultElement2 = doc.Descendants(xmlns + "GetDataAsStringResult"); //yields no results
var resultElement3 = doc.Descendants(namespacePrefix + "GetDataAsStringResult"); //yields no results
var resultElement4 = doc.Descendants(namespacePrefix + "Body"); //Gets s:Body element with descendants
var resultElement5 = resultElement3.Descendants("GetDataAsStringResponse"); //yields no results
var resultElement6 = resultElement3.Descendants(nsTempuri + "GetDataAsStringResponse"); //yields no results
var resultElement7 = resultElement3.Descendants(namespacePrefix + "GetDataAsStringResponse"); //yields no results
var resultElement8 = resultElement4.Descendants(); //Gets IEnumerable with both GetDataAsStringResponse and GetDataAsStringResult
基于所有这些实验,我可以执行以下操作:
var doc = XDocument.Parse(responseString);
var namespacePrefix = doc.Root.GetNamespaceOfPrefix("s");
var dataAsStringResult = from data in doc.Descendants(namespacePrefix + "Body")
let descendats = data.Descendants()
select descendats.TakeLast(1).Single();
看起来我需要的步骤太多了,特别是根据 SO 中的一些答案,我应该能够以更简单的方式完成它。
任何关于为什么我无法使用 "Descendants" 方法直接访问 GetDataAsStringResult 的见解,即使在添加命名空间时也将不胜感激。
谢谢。
经过几个小时的疯狂处理后,结果证明这是一个 "you missed the semicolon" 问题。命名空间对象应该在没有 "xlmns=" 部分的情况下声明,如下所示:
XNamespace nsTempuri = "http://tempuri.org/";
通过这样做,以下工作:
doc.Descendants(nsTempuri + "GetDataAsStringResult");
我发现了很多此类问题的实例,但出于某种原因 none 所有这些问题的答案都对我有用。
我得到的 SOAP 响应非常简单:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<GetDataAsStringResponse xmlns="http://tempuri.org/">
<GetDataAsStringResult>true</GetDataAsStringResult>
</GetDataAsStringResponse>
</s:Body>
</s:Envelope>
这些是我为解析它并到达 "GetDataAsStringResult" 元素而尝试过的所有选项:
var doc = XDocument.Parse(responseString);
XNamespace xmlns = "xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"";
XNamespace nsTempuri = "xmlns=\"http://tempuri.org/\"";
var namespacePrefix = doc.Root.GetNamespaceOfPrefix("s");
var resultElement = doc.Descendants("GetDataAsStringResult"); //yields no results
var resultElement1 = doc.Descendants(nsTempuri + "GetDataAsStringResult"); //yields no results
var resultElement2 = doc.Descendants(xmlns + "GetDataAsStringResult"); //yields no results
var resultElement3 = doc.Descendants(namespacePrefix + "GetDataAsStringResult"); //yields no results
var resultElement4 = doc.Descendants(namespacePrefix + "Body"); //Gets s:Body element with descendants
var resultElement5 = resultElement3.Descendants("GetDataAsStringResponse"); //yields no results
var resultElement6 = resultElement3.Descendants(nsTempuri + "GetDataAsStringResponse"); //yields no results
var resultElement7 = resultElement3.Descendants(namespacePrefix + "GetDataAsStringResponse"); //yields no results
var resultElement8 = resultElement4.Descendants(); //Gets IEnumerable with both GetDataAsStringResponse and GetDataAsStringResult
基于所有这些实验,我可以执行以下操作:
var doc = XDocument.Parse(responseString);
var namespacePrefix = doc.Root.GetNamespaceOfPrefix("s");
var dataAsStringResult = from data in doc.Descendants(namespacePrefix + "Body")
let descendats = data.Descendants()
select descendats.TakeLast(1).Single();
看起来我需要的步骤太多了,特别是根据 SO 中的一些答案,我应该能够以更简单的方式完成它。
任何关于为什么我无法使用 "Descendants" 方法直接访问 GetDataAsStringResult 的见解,即使在添加命名空间时也将不胜感激。
谢谢。
经过几个小时的疯狂处理后,结果证明这是一个 "you missed the semicolon" 问题。命名空间对象应该在没有 "xlmns=" 部分的情况下声明,如下所示:
XNamespace nsTempuri = "http://tempuri.org/";
通过这样做,以下工作:
doc.Descendants(nsTempuri + "GetDataAsStringResult");