清理XML LINQ查询

时间:2012-05-31 18:47:17

标签: c# linq linq-to-xml

这是此问题Stuck on basic Linq to XML query

的分支

我正在努力学习LINQ并学习LINQ to 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
    });

1 个答案:

答案 0 :(得分:2)

嗯,你没有任何理由使用查询表达式,并且你有不必要的括号和非常长的行......但除此之外看起来没问题。使其更清晰的一个选择是避免使用匿名类型 - 使用ApiResponse方法创建一个类(例如FromXElement),允许您编写:

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

或者在C#4中:

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

然后,您可以对查询进行投影 out ,并以普通方法编写。你可以把它分成几个陈述 - 这是你的电话。

顺便说一下,你是否真的期待不止一个元素仍然不清楚 - 一个文档只能有一个顶级元素,如果你真的只期望根元素为了有用,然后完全摆脱查询部分。

您可能还会发现更清楚地避免使用字符串文字(并在代码中重复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