坚持基本的Linq to XML查询

时间:2012-05-31 15:12:07

标签: 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>

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

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

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

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

更新

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

2 个答案:

答案 0 :(得分: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,
                              ...
                          });

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

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

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

答案 1 :(得分:0)

我刚收到Skeeted;)

这是我在linqpad中为你提供的一个元素

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