XDocument 和 Linq 如果元素具有 xmlns 属性,则返回 null

本文关键字:属性 返回 null xmlns Linq 如果 元素 XDocument | 更新日期: 2023-09-27 17:55:54

XDocuments和Linq的新手,请提出一个解决方案,从xml字符串中的特定标签中检索数据:

如果我有一个来自网络服务响应的 XML 字符串(为了方便起见,我格式化了 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>

使用以下代码,仅当标签没有"xmlns"属性时GetCashFlowReportResponse我才能获取值。不知道为什么?否则,它始终返回 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);
}

我无法更改 Web 服务以删除该属性。有没有更好的方法来读取响应并将实际数据返回给用户(以更易读的形式)?

编辑:溶液:

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 的响应)。

XDocument 和 Linq 如果元素具有 xmlns 属性,则返回 null

您需要包含命名空间:

XNamespace ns = "http://tempuri.org/";
xDoc.Descendants(ns + "GetCashFlowReportResponse")
XName qualifiedName = XName.Get("GetCashFlowReportResponse", 
    "http://tempuri.org/");
var data = from d in xDoc.Descendants(qualifiedName)

只需使用限定名称请求元素:

// create a XML namespace object
XNamespace ns = XNamespace.Get("http://tempuri.org/");
var data = from c in xDoc.Descendants(ns + "GetCashFlowReportResponse")
           select (string)c.Element(ns + "GetCashFlowReportPdf");

请注意使用重载 + 运算符创建具有 XML 命名空间和本地名称字符串的 QName。