坚持基本的Linq to XML查询

Jer*_*rry 2 c# linq linq-to-xml

我正在尝试从namecheap sandbox api中提取信息,但无法弄清楚为什么我的linq查询无效.

这是一个示例响应.

XML

<ApiResponse Status="OK" xmlns="http://api.namecheap.com/xml.response">
  <Errors />
  <Warnings />
  <RequestedCommand>namecheap.domains.check</RequestedCommand>
  <CommandResponse>
    <DomainCheckResult Domain="google.com" Available="false" />
  </CommandResponse>
  <Server>WEB1-SANDBOX1</Server>
  <GMTTimeDifference>--4:00</GMTTimeDifference>
  <ExecutionTime>0.875</ExecutionTime>
</ApiResponse>
Run Code Online (Sandbox Code Playgroud)

C#

var doc = XDocument.Load(url);
var response = (
    from  r in doc.Root.Descendants("ApiResponse") 
    where 1==1
    select new  { 
        Errors = r.Element("Errors").Value,
        Warnings = r.Element("Warnings").Value,
        RequestedCommand = r.Element("RequestedCommand").Value,
        CommandResponse = r.Element("CommandResponse").Value,
        Server = r.Element("Server").Value
    }
);
Run Code Online (Sandbox Code Playgroud)

我也尝试使用相同的doc查询这个查询,看看是否有一个简单的例子.

var test = doc.Descendants("RequestedCommand").First().Value;
Run Code Online (Sandbox Code Playgroud)

但两者都返回null.那我哪里错了?我最终需要获得CommandResponse中的顶级元素和更深层元素.任何帮助也将不胜感激.

UPDATE

正如Jon的回答所提到的,主要是在引用各种元素时不使用命名空间的问题.也使用doc.Elements()而不是doc.Root.后人().

这是一个更新的工作版本.

XNamespace ns = "http://api.namecheap.com/xml.response";
var response = (
    from r in doc.Elements()
    select new
    {
        Errors = r.Element(ns + "Errors").Value,
        Warnings = r.Element(ns + "Warnings").Value,
        RequestedCommand = r.Element(ns + "RequestedCommand").Value,
        CommandResponse = r.Element(ns + "CommandResponse").Value,
        Server = r.Element(ns + "Server").Value
    }
);
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 5

问题是当你在寻找元素,后代等时你没有使用命名空间:

XNamespace ns = "http://api.namecheap.com/xml.response";
var doc = XDocument.Load(url);
var response = doc.Root
                  .Descendants(ns + "ApiResponse")
                  .Select(r => new {
                              Errors = r.Element(ns + "Errors").Value,
                              ...
                          });
Run Code Online (Sandbox Code Playgroud)

(请注意,where 1 == 1在LINQ 中你永远不需要...我已经从查询表达式语法中改变了它,因为它没有给你任何东西.)

命名空间从<ApiResponse>元素继承,作为所有其他元素的默认命名空间,因为它只是xmlns=...指定别名而不是.

另请注意,如果您向我们展示了整个 XML文档,那么上面将找不到任何元素,因为您要求根ApiReponse元素下面的元素,而它根元素.