0
votes

The xml is located here:

https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml 

I want to get the time attribute of the element <Cube time="2016-08-04">.

My code in C# is the following but I get an error.

    private string function()
    {
        XmlDocument Doc = new XmlDocument();
        Doc.Load("https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml");

        XmlNamespaceManager nsmgr = new XmlNamespaceManager(Doc.NameTable);
        nsmgr.AddNamespace("gesmes", "http://www.gesmes.org/xml/2002-08-01");

        XmlNodeList nodes = Doc.SelectNodes("gesmes:Envelope/Cube", nsmgr);
        XmlNode node = nodes[0].SelectSingleNode("Cube");
        return node.Attributes["time"].Value;
    }

The error (I call it from a webservice):

The error is on this line

XmlNode node = nodes[0].SelectSingleNode("Cube");

Error:

The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework SDK documentation and inspect the server trace logs.

Server stack trace:
at System.ServiceModel.Channels.ServiceChannel.ThrowIfFaultUnderstood(Message reply, MessageFault fault, String action, MessageVersion version, FaultConverter faultConverter)
at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]:
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
at IRate.DoWork() at RateClient.DoWork()

2

2 Answers

0
votes

Try xml Linq

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

namespace ConsoleApplication1
{
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            var results = doc.Descendants().Where(x => x.Name.LocalName == "Cube" && x.Attribute("currency") != null).Select(x => new {
                currency = (string)x.Attribute("currency"),
                rate = (double)x.Attribute("rate")
            }).ToList();
        }
    }
}
0
votes

You're ignoring the default XML namespace in the XML!

<gesmes:Envelope 
        xmlns:gesmes="http://www.gesmes.org/xml/2002-08-01" 
        xmlns="http://www.ecb.int/vocabulary/2002-08-01/eurofxref">
        ***** Default XML namespace

Try this code:

XmlDocument Doc = new XmlDocument();
Doc.Load("https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml");

XmlNamespaceManager nsmgr = new XmlNamespaceManager(Doc.NameTable);
nsmgr.AddNamespace("gesmes", "http://www.gesmes.org/xml/2002-08-01");

// add another namespace alias for the *default* namespace
nsmgr.AddNamespace("default", "http://www.ecb.int/vocabulary/2002-08-01/eurofxref");

// *USE* the default namespace for those nodes that don't have an explicit
// XML namespace alias in your XML document
XmlNodeList nodes = Doc.SelectNodes("gesmes:Envelope/default:Cube", nsmgr);
XmlNode node = nodes[0].SelectSingleNode("default:Cube", nsmgr);

string value = node.Attributes["time"].Value;