Reading XML in Asp.net not getting any results - c#

I am using following code to read an XML file from this address.
XmlDocument xdoc = new XmlDocument();
xdoc.Load("https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml");
XmlNodeList nodeList = xdoc.DocumentElement.SelectNodes("//gesmes/Cube/Cube");
if (nodeList == null) lblOutput.Text = "node is null";
foreach (XmlNode node in nodeList)
{
XmlNode innerNode = node.SelectSingleNode(".//Cube");
lblOutput.Text = innerNode.Attributes["currency"].Value;
}
The problem is I don't get any thing. nodeList.Count always gives me 0.

You need to handle the namespaces correctly.
There are probably more then one way to handle them and this is one
XmlDocument xdoc = new XmlDocument();
xdoc.Load("https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml");
XmlNamespaceManager xnm = new XmlNamespaceManager(xdoc.NameTable);
xnm.AddNamespace("gesmes", "http://www.gesmes.org/xml/2002-08-01");
xnm.AddNamespace("eurofxref", "http://www.ecb.int/vocabulary/2002-08-01/eurofxref");
XmlNodeList nodeList = xdoc.DocumentElement.SelectNodes("//gesmes:Envelope/eurofxref:Cube/eurofxref:Cube", xnm);
if (nodeList == null)
{
var text = "node is null";
}
foreach (XmlNode node in nodeList)
{
XmlNode innerNode = node.SelectSingleNode(".//eurofxref:Cube", xnm);
var text = innerNode.Attributes["currency"].Value;
}

I don't know why it has to be this complicated but....
XmlDocument xdoc = new XmlDocument();
xdoc.Load("https://www.ecb.europa.eu/stats/eurofxref/eurofxref-daily.xml");
XmlNamespaceManager xMan = new XmlNamespaceManager(xdoc.NameTable);
xMan.AddNamespace("def", "http://www.ecb.int/vocabulary/2002-08-01/eurofxref");
XmlNodeList nodeList = xdoc.DocumentElement.SelectNodes("//def:Cube", xMan);

Related

Can not read values/nodes from xml using c#

I'm trying to read values from following xml (which is previously fetched from FTP):
<?xml version="1.0" encoding="utf-8"?>
<eventdata xmlns="http://www.demoweb.net/xml/eventdata" >
<site>
<sitelink>demotesting</sitelink>
<user>15101991</user>
<measurement>
<nodelink>012019120312064500</nodelink>
<containername>A1</containername>
<time>2020-04-30T11:25:35</time>
<value type="n_v_unitvalue">0.04</value>
<value type="n_v_unitvalue_diff">0.040</value>
</measurement>
<measurement>
<nodelink>012019120312064501</nodelink>
<containername>A2</containername>
<time>2020-04-30T11:25:35</time>
<value type="n_v_unitvalue">0.0</value>
<value type="n_v_unitvalue_diff">-0.001</value>
</measurement>
<measurement>
<nodelink>012019120312064502</nodelink>
<containername>A3</containername>
<time>2020-04-30T11:25:34</time>
<value type="n_v_unitvalue">0.0</value>
<value type="n_v_unitvalue_diff">0.000</value>
</measurement>
</site>
<createdate>2020-04-30T11:25:35</createdate>
</eventdata>
Before I start, file is sucessfully loaded into memory :)
As you can see root node is eventdata, and site is the node where all data is contained.
So basically I need to loop all measurement nodes and get the data.
I also were struggling to get out user node.. here's what I've tried so far:
using (StreamReader xml_reader = new StreamReader(xml_response.GetResponseStream()))
{
string xml = xml_reader.ReadToEnd();
XmlDocument xmldoc = new XmlDocument();
xmldoc.LoadXml(xml);
XmlNodeList mainFileContent = xmldoc.SelectNodes("eventdata");
// XmlNodeList mainFileContent = xmldoc.SelectNodes("eventdata/site");
XmlElement root = xmldoc.DocumentElement;
if (mainFileContent != null)
{
foreach (XmlNode node in mainFileContent)
{
var user = node["user"].InnerText;
}
}
}
What I'm missing?
THANKS GUYS
CHEERS
Your eventdata node has own xmlns declaration, you should properly handle it using XmlNamespaceManager and select the nodes with x:eventdata/x:site XPath expression
var xmldoc = new XmlDocument();
xmldoc.LoadXml(xml);
var nsmgr = new XmlNamespaceManager(xmldoc.NameTable);
nsmgr.AddNamespace("x", xmldoc.DocumentElement.NamespaceURI);
var mainFileContent = xmldoc.SelectNodes("x:eventdata/x:site", nsmgr);
foreach (XmlNode node in mainFileContent)
{
var user = node["user"]?.InnerText;
}
Use below code to read measurement
using (StreamReader xml_reader = new StreamReader(xml_response.GetResponseStream()))
{
string xml = xml_reader.ReadToEnd();
XmlDocument xmldoc = new XmlDocument();
xmldoc.LoadXml(xml);
var nsmgr = new XmlNamespaceManager(xmldoc.NameTable);
nsmgr.AddNamespace("ns", "http://www.demoweb.net/xml/eventdata");
XmlNodeList mainFileContent = xmldoc.SelectNodes("ns:eventdata/ns:site",nsmgr);
XmlElement root = xmldoc.DocumentElement;
if (mainFileContent != null)
{
foreach (XmlNode site in mainFileContent)
{
var user = site["user"].InnerText;
XmlNodeList measurements = site.SelectNodes("ns:measurement", nsmgr);
if (measurements != null)
{
foreach (XmlNode measurement in measurements)
{
var containername = measurement["containername"].InnerText;
var time = measurement["time"].InnerText;
XmlNodeList values = measurement.SelectNodes("ns:value", nsmgr);
if (values != null)
{
foreach (XmlNode value in values)
{
var type = value.Attributes["type"].Value;
var v2 = value.InnerText;
}
}
}
}
}
}
}

Creating XML document with Two root nodes

I want to create XML with two root nodes, like this
<?xml version="1.0" encoding="IBM437"?>
<header1>
<header2>
<fracc>6004</fracc>
<txncode>HTH</txncode>
<reason>testing</reason>
<timeout>20</timeout>
<rdate>2/3/2015 12:00:00 AM</rdate>
<rtime>6/18/2015 1:20:00 PM</rtime>
<seqno>5</seqno>
<prefix>8</prefix>
<msgtype>trr</msgtype>
<sendto>trr</sendto>
<replyto>trr</replyto>
</header2>
</header1>
My code is like this, I'm unable to add two root elements with my code, it's a must to use XmlDocument class.
XmlDocument xmlDoc = new XmlDocument();
XmlNode rootNode = xmlDoc.CreateElement("header" );
xmlDoc.AppendChild(rootNode);
XmlNode accountNode = xmlDoc.CreateElement("fracc");
accountNode.InnerText = Infracc;
rootNode.AppendChild(accountNode);
XmlNode txnNode = xmlDoc.CreateElement("txncode");
txnNode.InnerText = Intxncode;
rootNode.AppendChild(txnNode);
XmlNode reasonNode = xmlDoc.CreateElement("reason");
reasonNode.InnerText = Inreason;
rootNode.AppendChild(reasonNode);
XmlNode timeoutNode = xmlDoc.CreateElement("timeout");
timeoutNode.InnerText = Intimeout.ToString();
rootNode.AppendChild(timeoutNode);
XmlNode rdateNode = xmlDoc.CreateElement("rdate");
rdateNode.InnerText = Indate.ToString();
rootNode.AppendChild(rdateNode);
XmlNode rtimeNode = xmlDoc.CreateElement("rtime");
rtimeNode.InnerText = Intime.ToString();
rootNode.AppendChild(rtimeNode);
XmlNode seqnoNode = xmlDoc.CreateElement("seqno");
seqnoNode.InnerText = Inseqno.ToString();
rootNode.AppendChild(seqnoNode);
XmlNode prefixNode = xmlDoc.CreateElement("prefix");
prefixNode.InnerText = Inprefix.ToString();
rootNode.AppendChild(prefixNode);
XmlNode msgtypeNode = xmlDoc.CreateElement("msgtype");
msgtypeNode.InnerText = Inmsgtype;
rootNode.AppendChild(msgtypeNode);
XmlNode sendtoNode = xmlDoc.CreateElement("sendto");
sendtoNode.InnerText = Insendto;
rootNode.AppendChild(sendtoNode);
XmlNode replytoNode = xmlDoc.CreateElement("replyto");
replytoNode.InnerText = Inreplyto;
rootNode.AppendChild(replytoNode);
xmlDoc.Save("boc.xml");
xmlDoc.Load("boc.xml");
xmlDoc.Save(Console.Out);
return xmlDoc;
and my output is this
<?xml version="1.0" encoding="IBM437"?>
<header>
<fracc>6004</fracc>
<txncode>ttt</txncode>
<reason>testing</reason>
<timeout>20</timeout>
<rdate>2/3/2015 12:00:00 AM</rdate>
<rtime>6/18/2015 1:20:00 PM</rtime>
<seqno>5</seqno>
<prefix>8</prefix>
<msgtype>tt</msgtype>
<sendto>t</sendto>
<replyto>t</replyto>
</header>
Please help me to add two root nodes.
You are not adding 2 root elements.
Change your lines of code
XmlDocument xmlDoc = new XmlDocument();
XmlNode rootNode = xmlDoc.CreateElement("header" );
xmlDoc.AppendChild(rootNode);
like below -
XmlDocument xmlDoc = new XmlDocument();
XmlNode rootNode1 = xmlDoc.CreateElement("header1");
xmlDoc.AppendChild(rootNode1);
XmlNode rootNode = xmlDoc.CreateElement("header2");
rootNode1.AppendChild(rootNode);
Based on your sample output, it's clear that <header1> is the root element and <header2> is inside <header1>, so all you need to do is append <header2> inside <header1> and append the rest of the elements inside <header2>. This code should work
XmlDocument xmlDoc = new XmlDocument();
XmlNode rootNode = xmlDoc.CreateElement("header1");
xmlDoc.AppendChild(rootNode);
XmlNode rootNode2 = xmlDoc.CreateElement("header2");
rootNode.AppendChild(rootNode2);
XmlNode accountNode = xmlDoc.CreateElement("fracc");
accountNode.InnerText = Infracc;
rootNode2.AppendChild(accountNode);
XmlNode txnNode = xmlDoc.CreateElement("txncode");
txnNode.InnerText = Intxncode;
rootNode2.AppendChild(txnNode);
XmlNode reasonNode = xmlDoc.CreateElement("reason");
reasonNode.InnerText = Inreason;
rootNode2.AppendChild(reasonNode);
XmlNode timeoutNode = xmlDoc.CreateElement("timeout");
timeoutNode.InnerText = Intimeout.ToString();
rootNode2.AppendChild(timeoutNode);
XmlNode rdateNode = xmlDoc.CreateElement("rdate");
rdateNode.InnerText = Indate.ToString();
rootNode2.AppendChild(rdateNode);
XmlNode rtimeNode = xmlDoc.CreateElement("rtime");
rtimeNode.InnerText = Intime.ToString();
rootNode2.AppendChild(rtimeNode);
XmlNode seqnoNode = xmlDoc.CreateElement("seqno");
seqnoNode.InnerText = Inseqno.ToString();
rootNode2.AppendChild(seqnoNode);
XmlNode prefixNode = xmlDoc.CreateElement("prefix");
prefixNode.InnerText = Inprefix.ToString();
rootNode2.AppendChild(prefixNode);
XmlNode msgtypeNode = xmlDoc.CreateElement("msgtype");
msgtypeNode.InnerText = Inmsgtype;
rootNode2.AppendChild(msgtypeNode);
XmlNode sendtoNode = xmlDoc.CreateElement("sendto");
sendtoNode.InnerText = Insendto;
rootNode2.AppendChild(sendtoNode);
XmlNode replytoNode = xmlDoc.CreateElement("replyto");
replytoNode.InnerText = Inreplyto;
rootNode2.AppendChild(replytoNode);
xmlDoc.Save("boc.xml");
xmlDoc.Load("boc.xml");
xmlDoc.Save(Console.Out);
return xmlDoc;
Working fiddle: https://dotnetfiddle.net/EevsJq

append child using array c#

I write the xml using c#, and I want to make this script shorter, anyone know how to do it? I was think about using array,but don't know how to create the array...
XmlDocument doc = new XmlDocument();
XmlNode contentElements = doc.CreateElement("content");
doc.AppendChild(contentElements);
xmlNode itemElement1 = doc.CreateElement("item1");
xmlNode itemElement2 = doc.CreateElement("item2");
xmlNode itemElement3 = doc.CreateElement("item3");
xmlNode itemElement4 = doc.CreateElement("item4");
xmlNode itemElement5 = doc.CreateElement("item5");
contentElements.AppendChild(itemElement1);
contentElements.AppendChild(itemElement2);
contentElements.AppendChild(itemElement3);
contentElements.AppendChild(itemElement4);
contentElements.AppendChild(itemElement5);
Thanks a lot~~~
You can use an array as shown below
XmlDocument doc = new XmlDocument();
XmlNode contentElements = doc.CreateElement("content");
doc.AppendChild(contentElements);
string[] elements = new string[] { "item1", "item2", "item3", "item4", "item5" };
foreach (string element in elements)
{
XmlNode itemElement = doc.CreateElement(element);
contentElements.AppendChild(itemElement);
}

XmlDocument - SelectSingleNode with namespace

This is my code:
XmlTextReader reader = new XmlTextReader(xmlPath);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(reader);
XmlNode root = xmlDoc.DocumentElement;
XmlNode node = root.SelectSingleNode("marketingid");
XML that works:
<confirmsubmit>
<marketingid>-1</marketingid>
</confirmsubmit>
XML that doesn't work:
<confirmsubmit xmlns="http:....">
<marketingid>-1</marketingid>
</confirmsubmit>
What is the way to deal with the xmlns attribute and how can i parse it?
Is it has anything to do with namespace?
EDIT:
This is the code that works:
XmlTextReader reader = new XmlTextReader(xmlPath);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(reader);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("ns", xmlDoc.DocumentElement.NamespaceURI);
XmlNode book = xmlDoc.SelectSingleNode("/ns:confirmsubmit/ns:marketingid", nsmgr);
This all XPath is more complicated than seems, I would recommand to begginers like my to read: http://www.w3schools.com/xpath/xpath_syntax.asp
You need to add a XmlNamespaceManager instance in the game, as shown in this example from the documentation:
public class Sample
{
public static void Main()
{
XmlDocument doc = new XmlDocument();
doc.Load("booksort.xml");
//Create an XmlNamespaceManager for resolving namespaces.
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("bk", "urn:samples");
//Select and display the value of all the ISBN attributes.
XmlNodeList nodeList;
XmlElement root = doc.DocumentElement;
nodeList = root.SelectNodes("/bookstore/book/#bk:ISBN", nsmgr);
foreach (XmlNode isbn in nodeList){
Console.WriteLine(isbn.Value);
}
}
}
Here is how to do it from LINQ to XML. Short and simple
const string xml = #"<confirmsubmit xmlns='http:....'>
<marketingid>-1</marketingid>
</confirmsubmit>";
XElement element = XElement.Parse(xml);
var requestedElement = element.Elements().FirstOrDefault(x => x.Name.LocalName.Equals("marketingid"));
xmlns attribute is used at XHTML and defines namespace for a document. You can parse it like:
XDocument xdoc = XDocument.Load(xmlPath);
var attrib = xdoc.Root.Attribute("xmlns").Value;

How to set attribute to an XML element using linq to xml in C#

i've an xml file like
<Root>
<Steps>
<Step Test="SampleTestOne" Status="Fail" />
<Step Test="SampleTestTwo" Status="Fail" />
</Steps>
</Root>
i need to change or overwrite the attribute value of "Status" in the Step element.
Now i'm using XmlDocument for this
like
XmlDocument XDoc = new XmlDocument();
XDoc.Load(Application.StartupPath + "\\Sample.xml");
XmlNodeList NodeList = XDoc.SelectNodes("//Steps/Step");
foreach (XmlNode Node in NodeList)
{
XmlElement Elem = (XmlElement)Node;
String sTemp = Elem.GetAttribute("Test");
if (sTemp == "SampleTestOne")
Elem.SetAttribute("Status", "Pass");
}
I need search the element and to update the status
is there any way to do this using XDocumentin c#
Thanks in advance
string filename = #"C:\Temp\demo.xml";
XDocument document = XDocument.Load(filename);
var stepOnes = document.Descendants("Step").Where(e => e.Attribute("Test").Value == "SampleTestOne");
foreach (XElement element in stepOnes)
{
if (element.Attribute("Status") != null)
element.Attribute("Status").Value = "Pass";
else
element.Add(new XAttribute("Status", "Pass"));
}
document.Save(filename);
You can use this code:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(xmlFile);
XmlNode node = xmlDoc.SelectSingleNode("Root/Steps/Step");
node.Attributes["Status"].Value = "True";
xmlDoc.Save(xmlFile);

Categories