2009-01-12 55 views
5

我们利用返回XML它看起来像一个第三方网络服务(上剪下来的简洁):这是表达此XDocument查询的最有效方式吗?

<Response> 
    <block name="availability"> 
    <block name="cqual"> 
     <a name="result-code" format="text">L</a> 
    </block> 
    <block name="exchange"> 
     <a name="code" format="text">MRDEN</a> 
    </block> 
    <block name="mqual"> 
     <a name="rate-adaptive" format="text">G</a> 
    </block> 
    </block> 
    <block name="products"> 
    <block> 
     <a name="product-id" format="counting">1235</a> 
     <block name="realms"> 
     <block> 
      <a name="realm" format="text">[email protected]</a> 
     </block> 
     </block> 
    </block> 
    <block> 
     <a name="product-id" format="counting">1236</a> 
     <block name="realms"> 
     <block> 
      <a name="realm" format="text">[email protected]</a> 
     </block> 
     </block> 
    </block> 
    <block> 
     <a name="product-id" format="counting">1237</a> 
     <block name="realms"> 
     <block> 
      <a name="realm" format="text">[email protected]</a> 
     </block> 
     </block> 
    </block> 
    </block> 
    <status no="0" /> 
</Response> 

对于一个特定的产品代码,我需要获得realm名即内部文本:

<a name="realm" format="text">-u @ surfuk2</a>

因为每一个元素名称是<block><a>这是一个有点麻烦与LINQ解析到XML或查询表达式。

以下是获得特定产品领域名称的最有效/最有效/最具表现力的方法,例如: 1235:

List<XElement> products = response 
    .Element("Response") 
    .Elements("block") 
    .Where(x => x.Attribute("name").Value == "products") 
    .Elements("block").ToList(); 
// 
// I broke down the query to aid readability 
// 
string realm = products.Elements("a") 
    .Where(x => x.Attribute("name").Value == "product-id") 
    .Where(y => y.Value == "1235") // hardcoded for example use 
    .Ancestors() 
    .First() 
    .Elements("block") 
    .Where(z => z.Attribute("name").Value == "realms") 
    .Elements("block") 
    .Elements("a") 
    .First().Value; 

回答

2

作为提供的realm定义的简单等效:

string realm = (string) products.XPathEvaluate(
    "string(
     /*/blocks[@name='products'] 
       /*/a[@name='product-id' and . = '1236'] 
           /following-sibling::block[1] 
     ) 
    " 
            ) 

这实际上是既更可读的和比原来的问题所提供的的realm定义更紧凑

效率而言,它很可能是在评估一个XPath表达式可能会变成更有效率,也不过发现,如果这是真的,我们需要编写一个应用程序,它会比较的时机这两种方法。

+0

感谢您的回复。我知道我可以更加简洁地使用XPath,但是我认为今天在这一点上延伸了我的LINQ腿:-) – Kev 2009-01-12 20:16:04

0

似乎是这样,但为什么你需要所有的ToList()调用?我看到三个这样的电话,我不认为他们是需要的,所以他们只是减慢你的代码。但是再次,我没有使用很多Linq-to-XMl。

+0

呃......有一个调试会话的剩饭。现在排序。 – Kev 2009-01-12 19:09:30

相关问题