【问题标题】:Is this the most efficient way to express this XDocument query?这是表达此 XDocument 查询的最有效方式吗?
【发布时间】:2009-01-12 18:42:45
【问题描述】:

我们使用第三方 Web 服务,它返回类似于以下内容的 XML(为简洁起见):

<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 名称,即:的内部文本:

&lt;a name="realm" format="text"&gt;-u@surfuk2&lt;/a&gt;

因为每个元素名称都是&lt;block&gt;&lt;a&gt;,所以用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;

【问题讨论】:

    标签: c# xml .net-3.5 linq-to-xml


    【解决方案1】:

    所提供的realm 的定义等同于更简单的

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

    这实际上比原始问题中提供的realm 的定义更具可读性和更紧凑

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

    【讨论】:

    • 感谢您的回复。我知道我可以用 XPath 更简洁,但我想今天在那个上伸展我的 LINQ 腿:-)
    【解决方案2】:

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

    【讨论】:

    • 呃...调试会话有剩余。现已排序。
    猜你喜欢
    • 1970-01-01
    • 2016-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-05
    相关资源
    最近更新 更多