. Net Core - используйте LINQ для XML, чтобы получить элемент по имени из ответа SOAP - PullRequest
2 голосов
/ 10 марта 2020

Я обнаружил довольно много случаев такого вопроса, но по какой-то причине ни один из ответов на все эти вопросы не сработал для меня.

Ответ 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, я должен быть в состоянии сделать это за много более простой способ.

Любая идея о том, почему я не могу напрямую получить доступ к GetDataAsStringResult с помощью метода «Потомки», даже при добавлении пространства имен, будет очень признательна.

Спасибо.

1 Ответ

1 голос
/ 10 марта 2020

После нескольких часов сумасшествия это оказалось вопросом "Вы пропустили точку с запятой". Объект пространства имен должен быть объявлен без части "xlmns =" ​​ следующим образом:

XNamespace nsTempuri = "http://tempuri.org/";

Таким образом выполняются следующие действия:

doc.Descendants(nsTempuri + "GetDataAsStringResult");
...