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 解析为 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实际上,这比原始问题中提供的定义更具可读性和紧凑性。

就效率而言,很可能评估单个 XPath 表达式也可能更有效,但是要确定这是否正确,我们需要编写一个应用程序来比较两种方法的时间。

于 2009-01-12T20:08:53.187 回答
0

看起来是这样,但为什么你需要所有的ToList()电话?我看到其中三个调用,我认为它们不是必需的,因此它们只会减慢您的代码速度。但是话又说回来,我没有使用太多的 Linq-to-XMl。

于 2009-01-12T19:05:25.593 回答