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);
}
Related
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.
I am trying append a serialized object to an existing xml file beneath the root element, which I thought would be simple but is proving to be a little challenging.
The problem is in the AddShortcut method but I added some more code for completeness.
I believe what I need to do is:
load the file into an XmlDocument.
navigate to the node I want to append beneath (here the node name is Shortcuts).
create some type of writer and then serialize the object.
save the XmlDocument.
The trouble is in steps 2 and 3. I have tried different variations but I think using XPathNavigator somehow to find the "root" node to append under is a step in the right direction.
I have also looked at almost every question on Stack Overflow on the subject.
Any suggestions welcome. Here is my code
class XmlEngine
{
public string FullPath { get; set; } // the full path to the xmlDocument
private readonly XmlDocument xDoc;
public XmlEngine(string fullPath, string startElement, string[] rElements)
{
FullPath = fullPath;
xDoc = new XmlDocument();
CreateXmlFile(FullPath, startElement, rElements);
}
public void CreateXmlFile(string path, string startElement, string[] rElements)
{
try
{
if (!File.Exists(path))
{
// create a txt writer
XmlTextWriter wtr = new XmlTextWriter(path, System.Text.Encoding.UTF8);
// make sure the file is well formatted
wtr.Formatting = Formatting.Indented;
wtr.WriteProcessingInstruction("xml", "version='1.0' encoding='UTF-8'");
wtr.WriteStartElement(startElement);
wtr.Close();
// write the top level root elements
writeRootElements(path, rElements);
}
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex.Message);
Console.WriteLine("Could not create file: " + path);
}
}
public void AddShortcut(Shortcut s)
{
xDoc.Load(FullPath);
rootNode = xDoc.AppendChild(xDoc.CreateElement("Shortcuts"));
var serializer = new XmlSerializer(s.GetType());
using (var writer = new StreamWriter(FullPath, true))
{
XmlWriterSettings ws = new XmlWriterSettings();
ws.OmitXmlDeclaration = true;
serializer.Serialize(writer, s);
}
xDoc.Save(FullPath);
}
}
This code sample worked for me:
xml:
<?xml version="1.0" encoding="UTF-8"?>
<Launchpad>
<Shortcuts>
<Shortcut Id="1">
<Type>Folder</Type>
<FullPath>C:\SomePath</FullPath>
<Name>SomeFolderName</Name>
</Shortcut>
</Shortcuts>
</Launchpad>
Method:
public void AddShortcut(Shortcut s)
{
xDoc.Load(FullPath);
var rootNode = xDoc.GetElementsByTagName("Shortcuts")[0];
var nav = rootNode.CreateNavigator();
var emptyNamepsaces = new XmlSerializerNamespaces(new[] {
XmlQualifiedName.Empty
});
using (var writer = nav.AppendChild())
{
var serializer = new XmlSerializer(s.GetType());
writer.WriteWhitespace("");
serializer.Serialize(writer, s, emptyNamepsaces);
writer.Close();
}
xDoc.Save(FullPath);
}
load the file into an XmlDocument.
navigate to the node I want to append beneath (here the node name is Shortcuts).
create some type of writer and then serialize the object.
save the XmlDocument
So:
public void AddShortcut(Shortcut s)
{
// 1. load existing xml
xDoc.Load(FullPath);
// 2. create an XML node from object
XmlElement node = SerializeToXmlElement(s);
// 3. append that node to Shortcuts node under XML root
var shortcutsNode = xDoc.CreateElement("Shortcuts")
shortcutsNode.AppendChild(node);
xDoc.DocumentElement.AppendChild(shortcutsNode);
// 4. save changes
xDoc.Save(FullPath);
}
public static XmlElement SerializeToXmlElement(object o)
{
XmlDocument doc = new XmlDocument();
using(XmlWriter writer = doc.CreateNavigator().AppendChild())
{
new XmlSerializer(o.GetType()).Serialize(writer, o);
}
return doc.DocumentElement;
}
This post
I have the following code for writing XML file based on datacontracts
public static void LogDataContractToFile(string XMLStringToLog, string filePathAndName)
{
//String documentPath = string.Empty;
String xmlObject = string.Empty;
FileInfo fileinfo;
XmlDocumentFragment xmlDocumentFragment;
XmlTextWriter xmlWriter;
XmlDocument xmlDocument = null;
lock (LogDataContractToFileLock)
{
filePathAndName = filePathAndName.ToLower();
while (_workingWithFile.Contains(filePathAndName))
Thread.Sleep(1000);
_workingWithFile.Add(filePathAndName.ToLower());
try
{
#region Create XMLFile
fileinfo = new FileInfo(filePathAndName);
if (!fileinfo.Exists)
{
DirectoryInfo info = new DirectoryInfo(fileinfo.DirectoryName);
if (info.Exists == false)
info.Create();
using (xmlWriter = new XmlTextWriter(filePathAndName, System.Text.Encoding.UTF8))
{
xmlWriter.Formatting = Formatting.Indented;
xmlWriter.WriteStartDocument();
xmlWriter.WriteStartElement("root");
xmlWriter.WriteStartElement("objects");
xmlWriter.WriteEndElement();
xmlWriter.WriteEndElement();
xmlWriter.WriteEndDocument();
xmlWriter.Close();
}
}
else
{
//Se så att filen är 50 MB eller mindre
while (fileinfo.Length > 52428800)
{
xmlDocument = new XmlDocument();
xmlDocument.Load(filePathAndName);
xmlDocument.RemoveChild(xmlDocument.LastChild);
xmlDocument.Save(filePathAndName);
xmlDocument = null;
}
}
#endregion
xmlObject = XMLStringToLog;
//Open document
xmlDocument = new XmlDocument();
xmlDocument.Load(filePathAndName);
//Create a new fragment in current document
xmlDocumentFragment = xmlDocument.CreateDocumentFragment();
xmlDocumentFragment.InnerXml = xmlObject;
//Add new fragment after the first child
xmlDocument.DocumentElement.InsertBefore(xmlDocumentFragment, xmlDocument.DocumentElement.FirstChild);
xmlDocument.Save(filePathAndName);
xmlDocument = null;
}
finally
{
_workingWithFile.Remove(filePathAndName.ToLower());
}
}
}
The problem is that from time to time I get a The process cannot access the file exception? XmlDocument do not have any dispose so I can´t use using. How should this be handled properly?
Note that Im stuck on .NET 4.0.
To safely check for an element and add it if it doesn't exist you should use a ConcurrentDictionary:
private readonly ConcurrentDictionary<string,bool> _workingWithFile = new ConcurrentDictionary<string,bool>();
public static void LogDataContractToFile(string XMLStringToLog, string filePathAndName)
{
...
lock (LogDataContractToFileLock)
{
...
while(!_workingWithFile.TryAdd(filePathAndName, true))
{
Thread.Sleep(1000);
}
...
try
{
...
}
finally
{
//Perhaps check the result here.
bool result;
_workingWithFile.TryRemove(filePathAndName, out result);
}
}
}
I have an XML file with nodes and data...I need to write that into a text file as normal data. The nodes being the headers of the data
that follow.
EG XML:
<Bank>
<accountholder>Georgina Wax</accountholder>
<accountnumber>408999703657</accountnumber>
<accounttype>cheque</accounttype>
<bankname>National Bank</bankname>
<branch>Africa</branch>
<amount>2750.00</amount>
<date>12/01/2012</date>
</Bank>
To txt file and formatted as :
accountholder accountnumber accounttype bankname
Georgina Wax 408999703657 cheque National Bank
I can't seem to have it to have spaces between the data and hearders.
Below is what I tried :
StreamWriter writer = File.CreateText(#"C:\\Test.txt");
XmlDocument doc = new XmlDocument();
doc.Load(#"C:\\bank.xml");
writer.WriteLine(string.Join("|",doc.SelectSingleNode("/debitorders/deduction").ChildNodes.C ast<XmlElement>().Select(e => doc.SelectSingleNode("/debitorders/deduction/bankname").ToString())));
foreach (XmlElement book in doc.SelectNodes("/debitorders/deduction"))
{
writer.WriteLine(book.ChildNodes.Cast<XmlElement>().Select(e => e.InnerText).ToArray());
}
Please help.
This will produce output like you want.
private static void LoadAndWriteXML()
{
string headerFiles = "";
string values = "";
using (XmlReader reader = XmlReader.Create(#"C:\\bank.xml"))
{
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element && !reader.Name.Equals("Bank")) // we have to skip root node means bank node.
{
headerFiles += reader.Name + " ";
values += reader.ReadString() + " ";
}
}
}
StreamWriter writer = new StreamWriter(#"C:\\Test.txt");
writer.WriteLine(headerFiles.Trim());
writer.WriteLine(values.Trim());
writer.Close();
}
XDocument xdoc = new XDocument();
xdoc = XDocument.Load(fname);
xdoc.Save(fname1);
will save the file with the tags alignment formating
I have an XML file, and I want to retrieve the brandname when brandcode is 001 from the following XML.
<Root>
- <data>
<Companycode>TF</Companycode>
<Productcode>00001</Productcode>
<Productname>VPU</Productname>
<Brandcode>001</Brandcode>
<Brandname>DB</Brandname>
</data>
- <data>
<Companycode>TF</Companycode>
<Productcode>00002</Productcode>
<Productname>SENDERCARD</Productname>
<Brandcode>002</Brandcode>
<Brandname>LINSN</Brandname>
</data>
</Root>
This is my code; I need to assign Brand Name here:
XmlTextReader textReader = new XmlTextReader(#"codedata.xml");
textReader.Read();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(textReader);
XmlNodeList BCode = xmlDoc.GetElementsByTagName("Brandcode");
XmlNodeList BName = xmlDoc.GetElementsByTagName("Brandname");
for (int i = 0; i < BCode.Count; i++)
{
if (BCode[i].InnerText =="001")
{
string brandname = BName[i].InnerText;
}
//Console.WriteLine(BName[i].InnerText);
}
Try In this way...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
namespace XmlReading
{
class Program
{
static void Main(string[] args)
{
//Create an instance of the XmlTextReader and call Read method to read the file
XmlTextReader textReader = new XmlTextReader("D:\\myxml.xml");
textReader.Read();
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(textReader);
XmlNodeList BCode = xmlDoc.GetElementsByTagName("Brandcode");
XmlNodeList BName = xmlDoc.GetElementsByTagName("Brandname");
for (int i = 0; i < BCode.Count; i++)
{
if (BCode[i].InnerText == "001")
Console.WriteLine(BName[i].InnerText);
}
Console.ReadLine();
}
}
}
Try this XPath: //Brandname[../Brandcode[text()='001']]
Using XmlDocument.SelectSingleNode:
var document = new XmlDocument();
var Brandcode = "001";
var xpath = String.Format(#"//Brandname[../Brandcode[text()='{0}']]",
Brandcode);
var Brandname = document.SelectSingleNode(xpath).InnerText;
and using XDocument.XPathSelectElement:
var document = XDocument.Load("fileName");
var name = document.XPathSelectElement(xpath).Value;
YOu can use Xml.Linq namespace, with XDocument class to load and select the exact element from the xml file:
XDocument doc = XDocument.Load(#"filePath");
var query = doc.Descendants("Root").Where(w => w.Element("Brandcode").Value == "001").Select(s => new { s.Element("Brandname").Value }).FirstOrDefault();
string brandname = query.Value;
Define the brandname as string and assign null to it and then use the brand name where ever you want....
namespace XmlReading
{
class Program
{
static void Main(string[] args)
{
//Create an instance of the XmlTextReader and call Read method to read the file
XmlTextReader textReader = new XmlTextReader("D:\\myxml.xml");
textReader.Read();
string brandname = null;
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(textReader);
XmlNodeList BCode = xmlDoc.GetElementsByTagName("Brandcode");
XmlNodeList BName = xmlDoc.GetElementsByTagName("Brandname");
for (int i = 0; i < BCode.Count; i++)
{
if (BCode[i].InnerText == "001")
{
brandname = BName[i].InnerText;
}
}
Console.WriteLine(brandname);
Console.ReadLine();
}
}
}