5

次のような XML を返すサードパーティの Web サービスを使用します (簡潔にするために省略しています)。

<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">-u@surfuk1</a>
        </block>
      </block>
    </block>
    <block>
      <a name="product-id" format="counting">1236</a>
      <block name="realms">
        <block>
          <a name="realm" format="text">-u@surfuk2</a>
        </block>
      </block>
    </block>
    <block>
      <a name="product-id" format="counting">1237</a>
      <block name="realms">
        <block>
          <a name="realm" format="text">-u@surfuk3</a>
        </block>
      </block>
    </block>
  </block>
  <status no="0" />
</Response>

特定の製品コードについて、realm名前、つまり次の内部テキストを取得する必要があります。

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

すべての要素名がいずれ<block><a>であるか、linq to 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;
4

2 に答える 2

2

as providedの定義はrealm、単純な と同等です

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

realm実際、これは元の質問で提供された の定義よりも読みやすく、コンパクトです。

効率が懸念されるため、1 つの XPath 式を評価する方がより効率的である可能性もありますが、これが正しいかどうかを確認するには、2 つのメソッドのタイミングを比較するアプリケーションを作成する必要があります。

于 2009-01-12T20:08:53.187 に答える
0

そう思われますが、なぜすべてのToList()呼び出しが必要なのですか?これらの呼び出しが3つありますが、必要ではないと思うので、コードの速度が低下するだけです。しかし、繰り返しになりますが、Linq-to-XMlはあまり使用していません。

于 2009-01-12T19:05:25.593 に答える