【问题标题】:Get specific node from Xml usin Linq使用 Linq 从 Xml 获取特定节点
【发布时间】:2017-05-11 16:06:04
【问题描述】:

我想使用 Linq 从我的 XML 响应中获取特定节点 我的 XML:

<DataSet xmlns="http://www.bnr.ro/xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bnr.ro/xsd nbrfxrates.xsd">
    <Header>
        <Publisher>National Bank of Romania</Publisher>
        <PublishingDate>2016-12-30</PublishingDate>
        <MessageType>DR</MessageType>
    </Header>
    <Body>
        <Subject>Reference rates</Subject>
        <OrigCurrency>RON</OrigCurrency>
        <Cube date="2016-01-04">
            <Rate currency="AED">1.1272</Rate>
            <Rate currency="EUR">4.5169</Rate>
            <Rate currency="BGN">2.3094</Rate>
            <Rate currency="HUF" multiplier="100">1.4320</Rate>
            <Rate currency="INR">0.0622</Rate>
            <Rate currency="JPY" multiplier="100">3.4798</Rate>
            <Rate currency="KRW" multiplier="100">0.3481</Rate>
            <Rate currency="MDL">0.2107</Rate>
        </Cube>
        <Cube>
        ...
        </Cube>
    </Body>
</DataSet>

所以我想定位在日期等于日期参数的立方体上。然后我想限制货币等于“欧元”的汇率值。 我正在尝试使用 Linq 执行此操作,但它不起作用 我的 Linq 代码:

 WebClient webClient = new WebClient();
 string url = "http://www.bnr.ro/files/xml/years/nbrfxrates" + year + ".xml";
 HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
 HttpWebResponse response = request.GetResponse() as HttpWebResponse;

 XDocument systemXml = XDocument.Load(response.GetResponseStream());

 XElement cube = (from cubeElement in systemXml.Elements("Cube")
                 where cubeElement.Attribute("date").ToString().Equals(data)
                 select cubeElement).Single();

 XElement rate = (from rateElement in cube.Elements("Rate")
                  where rateElement.Attribute("currency").ToString().Equals("EUR")
                  select rateElement).Single();

我的问题是systemXml.Elements("Cube") 返回null。 这是我的网络请求网址http://www.bnr.ro/files/xml/years/nbrfxrates2017.xml

【问题讨论】:

标签: c# xml linq


【解决方案1】:

看起来你需要命名空间。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;

namespace ConsoleApplication55
{
    class Program
    {
        static void Main(string[] args)
        {
            string url = "http://www.bnr.ro/files/xml/years/nbrfxrates2017.xml";

            XDocument systemXml = XDocument.Load(url);
            XNamespace ns = ((XElement)systemXml.FirstNode).GetDefaultNamespace();

            DateTime date = DateTime.Parse("2017-01-05");
            var results = systemXml.Descendants(ns + "Cube")
                .Where(x => ((DateTime)x.Attribute("date") == date))
                .Descendants(ns + "Rate")
                .Where(x => (string)x.Attribute("currency") == "EUR")
                .FirstOrDefault();
            var value = (decimal)results;

        }
    }

}

【讨论】:

  • jdweng,你为什么不用systemXml.Root 而不是((XElement)systemXml.FirstNode)
【解决方案2】:

您的 Root 元素是 DataSet,它有子元素,其中之一是 Body,它有子 Cube。您还需要指定元素的命名空间 {http://www.bnr.ro/xsd}。所以这里是为你工作的 LINQ。

       XDocument systemXml = XDocument.Load(path);

        XElement cube = (from cubeElement in systemXml.Elements("{http://www.bnr.ro/xsd}DataSet").Elements("{http://www.bnr.ro/xsd}Body").Elements("{http://www.bnr.ro/xsd}Cube")
                             where cubeElement.Attribute("date").Value.Equals("2017-01-03")
                         select cubeElement).Single();

        XElement rate = (from rateElement in cube.Elements("{http://www.bnr.ro/xsd}Rate")
                         where rateElement.Attribute("currency").Value.Equals("EUR")
                         select rateElement).Single();

享受吧!!

【讨论】:

  • @S.over17 我已经更新了我的答案。现在它正在工作
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-29
  • 2019-12-03
相关资源
最近更新 更多