Stuck on basic Linq to XML query

限于喜欢 提交于 2019-12-11 00:06:33

问题


I'm trying to extract the information from the namecheap sandbox api and can't figure out why my linq queries aren't working.

Here's a sample response.

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

I've also tried this query with the same doc just to see if a simple example worked.

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

But both return null. So where am I going wrong? I'll eventually need to get at the top level elements and the deeper elements within CommandResponse. Any help with that would also be appreciated.

UPDATE

As Jon's answer mentioned, it was mainly an issue with not using the namespace when referencing the various elements. Also used doc.Elements() rather then doc.Root. Descendants().

Here's an updated working version.

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

回答1:


The problem is that you're not using the namespace when you're looking for elements, descendants etc:

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

(Note that you never need where 1 == 1 in LINQ... I've changed this from query expression syntax as it wasn't giving you anything.)

The namespace is inherited from the <ApiResponse> element as the default namespace for all the other elements, as it's just xmlns=... rather than specifying an alias.

Also note that if you've shown us the whole XML document, then the above won't find any elements, as you're asking for ApiReponse elements below the root element, whereas it is the root element.




回答2:


I just got Skeeted ;)

Here's something I did in linqpad to get you one of the elements in the 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();


来源:https://stackoverflow.com/questions/10836330/stuck-on-basic-linq-to-xml-query

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!