2009-01-12 89 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

相關問題