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.Root ではなく doc.Elements() を使用しました。子孫()。

これが更新された作業バージョンです。

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

(LINQでは必要ないことwhere 1 == 1に注意してください...何も与えられなかったので、これをクエリ式の構文から変更しました。)

名前空間は、エイリアスを指定するのではなく<ApiResponse>、他のすべての要素のデフォルトの名前空間として要素から継承されます。xmlns=...

また、XML ドキュメント全体を表示した場合、ルート要素のApiReponseの要素を要求しているため、上記では要素が見つからないことに注意してください。これルート要素です。

于 2012-05-31T15:14:22.233 に答える
0

私はスキートを手に入れました;)

XMLの要素の1つを取得するために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();
于 2012-05-31T16:14:05.727 に答える