2012-05-31 2 views
1

Это ответвление этого вопроса Stuck on basic Linq to XML queryОчистка XML LINQ запрос

Я пытаюсь получить лучше писать LINQ и узнать о LINQ к XML. Запрос LINQ возвращает ожидаемые результаты, но код не выглядит чистым. Есть ли лучший способ написать это?

XML

<ApiResponse xmlns="http://api.namecheap.com/xml.response" Status="OK"> 
     <Errors/> 
     <Warnings/> 
     <RequestedCommand>namecheap.domains.check</RequestedCommand> 
     <CommandResponse> 
      <DomainCheckResult Domain="gooaagle.com" Available="true"/> 
     </CommandResponse> 
     <Server>WEB1-SANDBOX1</Server> 
     <GMTTimeDifference>--4:00</GMTTimeDifference> 
     <ExecutionTime>0.859</ExecutionTime> 
    </ApiResponse> 

C#

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 = new 
         { 
         Domain= r.Element(ns + "CommandResponse").Element(ns + "DomainCheckResult").Attribute("Domain"), 
         Available = r.Element(ns + "CommandResponse").Element(ns + "DomainCheckResult").Attribute("Available") 
         }, 
     Server = r.Element(ns + "Server").Value 
    }); 

ответ

2

Ну вы используете выражение запроса без причины, и у вас есть лишние скобки, и очень длинные строки .. но кроме этого это выглядит хорошо. Один из вариантов, чтобы сделать его чище, чтобы избежать использования анонимных типов - создать класс (например, ApiResponse) с помощью метода FromXElement, что позволяет написать:

var response = doc.Elements().Select(x => ApiResponse.FromXElement(x)); 

Или в C# 4:

var response = doc.Elements().Select(ApiResponse.FromXElement); 

You затем может взять проекцию из запроса и записать его в обычном методе. Вы можете разбить это на несколько утверждений или нет - это ваш звонок.

По-прежнему неясно, действительно ли вы ожидаете более одного элемента - документ может содержать только один элемент верхнего уровня, и если вы действительно действительно только ожидаете, что корневой элемент будет полезен, затем полностью избавиться от запрашивающей части.

Вы также можете найти его четче, чтобы избежать строковых литералов (и повторил ns + ... в вашем коде, как это:

private static readonly XNamespace ResponseNs = 
    "http://api.namecheap.com/xml.response"; 
private static readonly XName ErrorsName = ResponseNs + "Errors"; 
private static readonly XName WarningsName = ResponseNs + "Warnings"; 
// etc 

Затем вы можете использовать:

Errors = r.Element(ErrorsName).Value