How to retrieve all Elements from XML file using c# - c#

I am trying to retrieve all elements from an XML file, but I just can reach one, is there any way I can retrieve all?
HttpWebResponse objResponse = (HttpWebResponse)objRequest.GetResponse();
using (XmlReader reader = XmlReader.Create(new StreamReader(objResponse.GetResponseStream())))
{
while (reader.Read())
{
#region Get Credit Score
//if (reader.ReadToDescendant("results"))
if (reader.ReadToDescendant("ssnMatchIndicator"))
{
string ssnMatchIndicator = reader.Value;
}
if (reader.ReadToDescendant("fileHitIndicator"))
{
reader.Read();//this moves reader to next node which is text
result = reader.Value; //this might give value than
Res.Response = true;
Res.SocialSecurityScore = result.ToString();
//break;
}
else
{
Res.Response = false;
Res.SocialSecurityScore = "Your credit score might not be available. Please contact support";
}
#endregion
#region Get fileHitIndicator
if (reader.ReadToDescendant("fileHitIndicator"))
{
reader.Read();
Res.fileHitIndicator = reader.Value;
//break;
}
#endregion
}
}
Can somebody help me out with this issue?
I am also using objResponse.GetResponseStream() because the XML comes from a response from server.
Thanks a lot in advance.

Try this :
XmlDataDocument xmldoc = new XmlDataDocument();
XmlNodeList xmlnode ;
int i = 0;
string str = null;
FileStream fs = new FileStream("product.xml", FileMode.Open, FileAccess.Read);
xmldoc.Load(fs);
xmlnode = xmldoc.GetElementsByTagName("Product");
for (i = 0; i <= xmlnode.Count - 1; i++)
{
xmlnode[i].ChildNodes.Item(0).InnerText.Trim();
str = xmlnode[i].ChildNodes.Item(0).InnerText.Trim() + " " + xmlnode[i].ChildNodes.Item(1).InnerText.Trim() + " " + xmlnode[i].ChildNodes.Item(2).InnerText.Trim();
MessageBox.Show (str);
}

I don't know why what you're doing is not working, but I wouldn't use that method. I've found the following to work well. Whether you're getting the xml from a stream, just put it into a string and bang...
StreamReader reader = new StreamReader(sourcepath);
string xml = reader.ReadToEnd();
reader.Close();
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
XmlNodeList list = doc.GetElementsByTagName("*");
foreach (XmlNode nd in list)
{
switch (nd.Name)
{
case "ContactID":
var ContactIdent = nd.InnerText;
break;
case "ContactName":
var ContactName = nd.InnerText;
break;
}
}
To capture what is between the Xml tags, if there are no child Xml tags, use the InnerText property, e.g. XmlNode.InnerText. To capture what is between the quotes in the nodes' attributes, use XmlAttribute.Value.
As for iterating through the attributes, if one of your nodes has attributes, such as the elements "Name", "SpectralType" and "Orbit" in the Xml here:
<System>
<Star Name="Epsilon Eridani" SpectralType="K2v">
<Planets>
<Planet Orbit="1">Bill</Planet>
<Planet Orbit="2">Moira</Planet>
</Planets>
</Star>
</System>
Detect them using the Attributes property, and iterate through them as shown:
if (nd.Attributes.Count > 0)
{
XmlAttributeCollection coll = nd.Attributes;
foreach (XmlAttribute cn in coll)
{
switch (cn.Name)
{
case "Name":
thisStar.Name = cn.Value;
break;
case "SpectralType":
thisStar.SpectralClass = cn.Value;
break;
}
}
}
You might find some more useful information HERE.

Related

XML ReadLine to txt file

I have a problem with saving data from XML URL nodes, using XMLReader, to a text file. Can you please help me out? I don't know how to do it.
Here is the code:
namespace XMLdemo2
{
class Program
{
static void Main(string[] args)
{
// Start with XmlReader object
String URLString = "https://www.shortcut.lv/xmls/tiesraide/ltv1.xml";
XmlTextReader reader = new XmlTextReader(URLString);
{
while (reader.Read())
{
if (reader.IsStartElement())
{
switch (reader.Name.ToString())
{
case "auth_token":
Console.WriteLine("Tokens IR : " + reader.ReadString());
break;
}
//Console.WriteLine("");
}
}
Console.ReadKey();
}
}
}
}
You can try something easier like this (if it's only one line you want to read)
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("https://www.shortcut.lv/xmls/tiesraide/ltv1.xml");
XmlNode authTokenNode = xmlDoc.SelectSingleNode("//auth_token");
if(authTokenNode != null)
Console.WriteLine(authTokenNode.InnerText);
If it is multiple lines
XmlDocument xmlDoc = new XmlDocument();
XmlNodeList itemNodes = xmlDoc.SelectNodes("//auth_token");
foreach(XmlNode itemNode in itemNodes)
{
if((itemNode != null)
Console.WriteLine(itemNode.InnerText);
}

How to loop XmlTextReader properly (C#)?

Below is a sample of the type of XML file I am trying to handle. If I have only one part along with an accompanying number/character I can process the data extraction without the necessity of the 'if (!reader.EOF)' control structure. However when I try to include this structure so that I can loop back to checking for another part, number, and character group, it deadlocks.
Any advice as to how to do this properly? This was the most efficient idea that popped into my head. I am new to reading data from XMLs.
Sample Xml:
<?xml version="1.0" encoding="UTF-8"?>
<note>
<part>100B</part>
<number>45</number>
<character>a</character>
<part>100C</part>
<number>55</number>
<character>b</character>
</note>
Code:
String part = "part";
String number = "number";
String character = "character";
String appendString = "";
StringBuilder sb = new StringBuilder();
try
{
XmlTextReader reader = new XmlTextReader("myPath");
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element: // The node is an element.
myLabel:
if (reader.Name == part)
{
part = reader.ReadInnerXml();
}
if (reader.Name == number)
{
number = reader.ReadInnerXml();
number = double.Parse(number).ToString("F2"); //format num
}
if (reader.Name == character)
{
character = reader.ReadInnerXml();
}
//new string
appendString = ("Part: " + part + "\nNumber: " + number +
"\nCharacter: " + character + "\n");
//concatenate
sb.AppendLine(appendString);
if (reader.EOF != true)
{
Debug.Log("!eof");
part = "part";
number = "number";
character = "character";
goto myLabel;
}
//print fully concatenated result
sb.ToString();
//reset string builder
sb.Length = 0;
break;
}
}
}
catch (XmlException e)
{
// Write error.
Debug.Log(e.Message);
}
catch (FileNotFoundException e)
{
// Write error.
Debug.Log(e);
}
catch(ArgumentException e)
{
// Write error.
Debug.Log(e);
}
XmlReader class has many useful methods. Use it.
See this:
var sb = new StringBuilder();
using (var reader = XmlReader.Create("test.xml"))
{
while (reader.ReadToFollowing("part"))
{
var part = reader.ReadElementContentAsString();
sb.Append("Part: ").AppendLine(part);
reader.ReadToFollowing("number");
var number = reader.ReadElementContentAsDouble();
sb.Append("Number: ").Append(number).AppendLine();
reader.ReadToFollowing("character");
var character = reader.ReadElementContentAsString();
sb.Append("Character: ").AppendLine(character);
}
}
Console.WriteLine(sb);
Alexander's answer is fine, I just want to add sample using XDocument, according comments of Jon Skeet:
var sb = new StringBuilder();
var note = XDocument.Load("test.xml").Root.Descendants();
foreach (var el in note)
{
sb.Append(el.Name).Append(": ").AppendLine(el.Value);
}
Console.WriteLine(sb);

How to read XML node from URL using C#?

I'm having program like below. The concept is Read XML value from URL, but my program read the xml structure only, not the code datas. Like <Billing Address></Billing Address>... etc only. But the original XML value is <Billing Address>Strre1</Billing Address>. The Program does not read the inside value.
public static void zohoCRMReadAccounts()
{
var val = auth();
var val1= val[0];
var val2= val[1];
String xmlURL = "URL";
XmlTextReader xmlReader = new XmlTextReader(xmlURL);
while (xmlReader.Read())
{
switch (xmlReader.NodeType)
{
case XmlNodeType.Element: // The node is an element.
Console.Write("<" + xmlReader.Name);
// Read the attributes:
while (xmlReader.MoveToNextAttribute())
Console.Write(" " + xmlReader.Name + "=’"
+ xmlReader.Value + "’");
Console.WriteLine(">");
break;
case XmlNodeType.Text: //Display the text in each element.
Console.WriteLine(xmlReader.Value);
break;
case XmlNodeType.EndElement: //Display the end of the element.
Console.Write("</" + xmlReader.Name);
Console.WriteLine(">");
break;
}
}
Console.WriteLine("Press any key to continue…");
Console.ReadLine(); //Pause
}
Please help me to fix
XML Elements cannot have spaces in their names. Try to remove them first
First download the XML. Then Use like,
try {
//read xml
XmlDocument xdoc = new XmlDocument();
xdoc.Load("XMLFilePath");
XmlNodeList nodes = xdoc.SelectNodes(#"rss/channel/item");
foreach (XmlNode node in nodes)
{
XmlNode titleNode = node.SelectSingleNode("title");
string title = titleNode == null ? string.Empty : titleNode.InnerText;
};
}

Xml bulk Nodes appending issue

I want to generate a million record xml file.For this i have a sample xml file with only one value set.Using this xml file fill ramdom values a million times.
I created a solutin but it is very time consuming one.My code is
try
{
label1.Text = "File creation in progress ...";
Random rnd = new Random();
string sStartupPath = Application.StartupPath;
string sName = "";
int flag = 0;
XmlDocument XmlFile = new XmlDocument();
XmlFile.Load(sStartupPath + #"..\..\..\BankStatement.xml");
XmlFile.Save(#"C:\XmlData\Bank.xml");
XmlDocument XmlF = new XmlDocument();
XmlF.Load(#"C:\XmlData\Bank.xml");
long k = Convert.ToInt32(textBox1.Text);
for (int j = 1; j < k; j++)
{
XmlTextReader objXmlTextReader = new XmlTextReader(sStartupPath + #"..\..\..\BankStatement.xml");
while (objXmlTextReader.Read())
{
switch (objXmlTextReader.NodeType)
{
case XmlNodeType.Element:
sName = objXmlTextReader.Name;
if (sName == "DataXml")
{
if (flag == 0)
flag = 1;
}
break;
case XmlNodeType.Text:
if (flag == 1)
{
XmlNodeList elemList = XmlFile.GetElementsByTagName(sName);
for (int i = 0; i < elemList.Count; i++)
{
if (elemList[i].Name == "Name")
elemList[i].InnerXml = generateNames();
else if (elemList[i].Name == "EmailID")
elemList[i].InnerXml = generatemailids();
else
elemList[i].InnerXml = rnd.Next(500000).ToString();
}
}
break;
case XmlNodeType.EndElement:
sName = objXmlTextReader.Name;
if (sName == "DataXml")
{
if (flag == 1)
flag = 0;
}
break;
}
}
XmlDocument dd = new XmlDocument();
dd.LoadXml(XmlFile.InnerXml);
XmlNodeList node=dd.GetElementsByTagName("Customers");
XmlDocumentFragment xfrag = XmlF.CreateDocumentFragment();
xfrag.RemoveAll();
for (int i = 0; i < 1; i++)
{
xfrag.InnerXml = node[i].InnerXml;
XmlF.DocumentElement.FirstChild.AppendChild(xfrag);
}
XmlF.Save(#"C:\XmlData\Bank.xml");
}
label1.Visible = false;
MessageBox.Show("File creation success..!");
}
catch (Exception ex)
{
label1.Text = "";
MessageBox.Show("Error Occured");
}
Please give me a better solution.
The fastest method I know to write XML (short of building the XML fragments manually) is to use XmlWriter
The XmlWriter class is an abstract base class that provides a
forward-only, write-only, non-cached way of generating XML streams. It
can be used to build XML documents that conform to the W3C Extensible
Markup Language (XML) 1.0 (fourth edition) recommendation and the
Namespaces in XML recommendation.
MSDN has a walkthrough on how to use the abstract XmlWriter class.
For writing large XML files you should use XmlTextWriter.

Use XMLReader to access child nodes with duplicate names

Using the XML fragment below, how would I access the child node <amt> of the node <salesTaxAmt> using XMLReader? If I iterate over the nodes looking for a node name of "amt" I return the last node amount of <sourceCurrAmt> which is 0.00.
<transactionUnit>
<transactionDetails>
<transactionId>11883382</transactionId>
<currencyAmount>
<amt>30.00</amt>
<currCode>USD</currCode>
</currencyAmount>
<gstAmount>
<amt>60.00</amt>
<currCode>USD</currCode>
</gstAmount>
<pstNqstAmt>
<amt>0.00</amt>
<currCode>USD</currCode>
</pstNqstAmt>
<salesTaxAmt>
<amt>1.00</amt>
<currCode>USD</currCode>
</salesTaxAmt>
<sourceCurrAmt>
<amt>0.00</amt>
</sourceCurrAmt>
</transactionDetails>
</transactionUnit>
Is the code below even the best way to do this?
Test Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
namespace TestConsole
{
public class ParseXML
{
static void Main(string[] args)
{
try
{
FileStream file;
XmlReader baseReader;
XmlTextReader reader;
XmlReaderSettings readerSettings;
file = new FileStream(#"C:\Data.xml", FileMode.Open, FileAccess.Read);
file.Seek(0, SeekOrigin.Begin);
reader = new XmlTextReader(file, XmlNodeType.Element, null);
reader.Normalization = false;
readerSettings = new XmlReaderSettings();
readerSettings.ConformanceLevel = ConformanceLevel.Fragment;
readerSettings.IgnoreWhitespace = false;
readerSettings.IgnoreComments = true;
readerSettings.CheckCharacters = false;
baseReader = XmlReader.Create(reader, readerSettings);
int x = 0;
while (baseReader.Read())
{
if (baseReader.Name.Equals("transactionUnit") && (baseReader.NodeType == XmlNodeType.Element))
{
string amt = null;
XmlReader inner = reader.ReadSubtree();
while (inner.Read())
{
if (inner.Name.Equals("ns:amt"))
{
amt = inner.ReadElementString();
}
}
Console.WriteLine("amt: {0}", amt);
inner.Close();
x = x + 1;
}
}
Console.WriteLine("{0} transactions found", x.ToString());
baseReader.Close();
file.Close();
}
catch (XmlException xe)
{
Console.WriteLine("XML Parsing Error: " + xe);
}
catch (IOException ioe)
{
Console.WriteLine("File I/O Error: " + ioe);
}
}
}
}
From your example code it looks like you can use LINQ to XML, this would be a more succinct solution for your problem:
XDocument xDoc = XDocument.Load(#"C:\Data.xml");
string amt = xDoc.Descendants("salesTaxAmt")
.Elements("amt")
.Single().Value;
If you can use it LINQ to XML should definitely be your choice, it provides an easy and powerful syntax for retrieving data from XML and plays nicely with LINQ to objects.
A simpler way to get the node value is to use XPath.
Note that this is possible only if you node the path to the node whose value is to be retreived.
private string GetNodeValue(string xmlFilePath, string xpath)
{
string nodeValue = string.Empty;
using (StreamReader reader = new StreamReader(xmlFilePath))
{
XPathDocument xPathDocument = new XPathDocument(reader);
XPathNavigator navigator = xPathDocument.CreateNavigator();
XPathNodeIterator iter = navigator.Select(xpath);
iter.MoveNext();
nodeValue = iter.Current.Value;
//iter.Current.ValueAsDouble;
}
return nodeValue;
}
The usage for your sample xml should be:
string nodeValue = GetNodeValue(#"C:\Data.xml", "//transactionUnit/transactionDetails/salesTaxAmt/amt");
In addition, you could rename the method as 'GetNodeValueAsDouble' and use iter.Current.ValueAsDouble instead of iter.Current.Value to get the double value.
More Information
XPathNavigator class
XPathDocument class

Categories