Новичок с XDocuments и Linq, предложите решение для извлечения данных из определенного тега в строке xml:
Если у меня есть XML-строка из ответа webservice (я отформатировал xml для удобства):
<?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>
<GetCashFlowReportResponse xmlns="http://tempuri.org/">
<GetCashFlowReportPdf>Hello!</GetCashFlowReportPdf>
</GetCashFlowReportResponse>
</soap:Body>
</soap:Envelope>
Используя следующий код, я могу получить значение, только если тег GetCashFlowReportResponse
не имеет атрибута "xmlns"
. Не знаете почему? В противном случае он всегда возвращает null.
string inputString = "<?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><GetCashFlowReportResponse xmlns=\"http://tempuri.org/\"><GetCashFlowReportPdf>Hello!</GetCashFlowReportPdf></GetCashFlowReportResponse></soap:Body></soap:Envelope>"
XDocument xDoc = XDocument.Parse(inputString);
//XNamespace ns = "http://tempuri.org/";
XNamespace ns = XNamespace.Get("http://tempuri.org/");
var data = from c in xDoc.Descendants(ns + "GetCashFlowReportResponse")
select (string)c.Element("GetCashFlowReportPdf");
foreach (string val in data)
{
Console.WriteLine(val);
}
Я не могу изменить веб-службу, чтобы удалить этот атрибут. Есть ли лучший способ прочитать ответ и вернуть фактические данные пользователю (в более читаемой форме)?
Отредактировано: РЕШЕНИЕ:
XDocument xDoc = XDocument.Parse(inputString);
XNamespace ns = "http://tempuri.org/";
var data = from c in xDoc.Descendants(ns + "GetCashFlowReportResponse")
select (string)c.Element(ns + "GetCashFlowReportPdf");
foreach (string val in data)
{
Console.WriteLine(val);
}
Примечание. Даже если все дочерние элементы не имеют атрибута пространства имен, код будет работать, если вы добавите "ns" к элементу, так как я полагаю, что дочерние элементы наследуют пространство имен от родителя (см. ответ от SLaks).