2

我正在尝试从 namecheap 沙箱 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>

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
    }
);

我也用同一个文档尝试了这个查询,只是为了看看一个简单的例子是否有效。

var test = doc.Descendants("RequestedCommand").First().Value;

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

更新

正如乔恩的回答所提到的,这主要是在引用各种元素时不使用命名空间的问题。还使用了 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
    }
);
4

2 回答 2

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,
                              ...
                          });

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

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

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

于 2012-05-31T15:14:22.233 回答
0

我刚刚得到了Skeeted ;)

这是我在 linqpad 中为您获取 XML 中的元素之一所做的事情

var myxml = @"<ApiResponse Status=""OK"" xmlns=""http://api.namecheap.com/xml.response"">
<Server>WEB1-SANDBOX1</Server>
<Errors />
<Warnings />
<RequestedCommand>namecheap.domains.check</RequestedCommand>
<CommandResponse>
    <DomainCheckResult Domain=""google.com"" Available=""false"" />
</CommandResponse>

<GMTTimeDifference>--4:00</GMTTimeDifference>
<ExecutionTime>0.875</ExecutionTime>
</ApiResponse>";

//myxml.Dump();

XNamespace p = "http://api.namecheap.com/xml.response";
var doc1 = XElement.Parse(myxml);
var x = from n in doc1.Elements(p + "Server")  select n;
x.First().Value.Dump();
于 2012-05-31T16:14:05.727 回答