FormatException, converting a string to a long - c#

I was getting values from an XML file and placing them inside a dataGridView. I was successful in doing so, but after I want to manipulate data that I got from an XML file, It does not work and i get an error of Input string was not in a correct format. .
My goal is to convert a data captured from an XML File and divide it by 1024. Ain't InnerText a string that I can safely convert to a long? should I add more code to make this work?
During my debugging, i printed out the value of temp and the Value is 53999759360, I also tried not making it ToString() , same error
Here is part of my code: (The value of size is "53999759360")
XmlDocument doc = new XmlDocument();
string xmlFilePath = #"C:\xampp\htdocs\userInfo.xml";
doc.Load(xmlFilePath);
XmlNodeList accountList = doc.GetElementsByTagName("account");
foreach (XmlNode node in accountList)
{
XmlElement accountElement = (XmlElement)node;
foreach (XmlElement dskInterface in node.SelectNodes("systemInfo/dskInfo/dskInterface"))
{
String temp = (dskInterface["size"].InnerText).ToString();
long iasdas = Convert.ToInt64(temp) / 1024; // Error Happens here
}
}

I'm afraid that your code works fine. It must be that the "temp" variable is string.Empty or whitespace.
I created an XmlDocument (from XDocument, sorry. I think it's a lot easier to work with) that looks like what you're targeting and ran your code. It runs fine and gives a proper value:
var xDoc = new XDocument(
new XDeclaration("1.0", "UTF-8", "no"),
new XElement("root",
new XElement("account",
new XElement("systemInfo",
new XElement("dskInfo",
new XElement("dskInterface",
new XElement("size", 53999759360)))))));
var doc = new XmlDocument();
using (var xmlReader = xDoc.CreateReader())
{
doc.Load(xmlReader);
}
XmlNodeList accountList = doc.GetElementsByTagName("account");
foreach (XmlNode node in accountList)
{
XmlElement accountElement = (XmlElement)node;
foreach (XmlElement dskInterface in node.SelectNodes("systemInfo/dskInfo/dskInterface"))
{
String temp = (dskInterface["size"].InnerText).ToString();
long iasdas = Convert.ToInt64(temp) / 1024; // Error Happens here
}
}
Edit:
Here's an easier way to test what's actually happening:
Convert.ToInt64(null); // Doesn't crash
Convert.ToInt64(string.Empty); // Crashes
Convert.ToInt64(""); // Will crash if you comment the line above
Convert.ToInt64(" "); // Will crash if you comment the lines above

Related

How Can I Parse an XML file using XmlNodeList

I have been tasked with taking one XML file and converting it to a new XML I have no experience working with XML documents but I have been able to get some of the data from the first XML document using the code shown below. Note not all code is being shown just a small example.
XmlDocument rssXmlDoc = new XmlDocument();
// Load the RSS file from the RSS URL
rssXmlDoc.Load("https://agency.governmentjobs.com/jobfeed.cfm?agency=ocso");
// Setup name space
XmlNamespaceManager nsmgr = new XmlNamespaceManager(rssXmlDoc.NameTable);
nsmgr.AddNamespace("joblisting", "http://www.neogov.com/namespaces/JobListing");
// Parse the Items in the RSS file
XmlNodeList rssNodes = rssXmlDoc.SelectNodes("rss/channel/item/");
// Iterate through the items in the RSS file
foreach (XmlNode rssNode in rssNodes)
{
XmlNode rssSubNode = rssNode.SelectSingleNode("title");
string title = rssSubNode != null ? rssSubNode.InnerText : "";
using this code I am able to get most of the elements. I have run into a wall when trying to get data from a child element. The portion of the XML I cannot get is shown below.
<joblisting:department>Supply</joblisting:department>
<guid isPermaLink="true">https://www.governmentjobs.com/careers/ocso/Jobs/2594527</guid>
<joblisting:categories>
<joblisting:category xmlns:joblisting="http://www.neogov.com/namespaces/JobListing" xmlns:atom="http://www.w3.org/2005/Atom">
<CategoryCode>ClericalDataEntry</CategoryCode>
<Category>Clerical & Data Entry</Category>
</joblisting:category>
<joblisting:category
</joblisting:categories>
But I cannot get all of the data. How can I get the value for the element that starts with guid isPermaLink="true"
For the joblisting:categories I have used a foreach loop to read those values
foreach (var item in rssSubNode.SelectNodes("joblisting:categories", nsmgr))
{
rssSubNode = rssSubNode = rssNode.SelectSingleNode("joblisting:category", nsmgr);
string category = rssSubNode != null ? rssSubNode.InnerText : "";
}
How can read the values of those child elements?
To read guid node you can use the follow code. note that use selectSingleNode in node contains the "item" node.
public static void test() {
XmlDocument rssXmlDoc = new XmlDocument();
// Load the RSS file from the RSS URL
rssXmlDoc.Load("https://agency.governmentjobs.com/jobfeed.cfm?agency=ocso");
// Setup name space
XmlNamespaceManager nsmgr = new XmlNamespaceManager(rssXmlDoc.NameTable);
nsmgr.AddNamespace("joblisting", "http://www.neogov.com/namespaces/JobListing");
// Parse the Items in the RSS file
XmlNodeList rssNodes = rssXmlDoc.SelectNodes("rss/channel/item");
// Iterate through the items in the RSS file
foreach (XmlNode rssNode in rssNodes) {
var xmlnode = rssNode.SelectSingleNode("guid ");
System.Console.WriteLine("the value of guid is =>" + xmlnode.InnerText);
XmlNode rssSubNode = rssNode.SelectSingleNode("title");
string title = rssSubNode != null ? rssSubNode.InnerText : "";
}
}

Changing value in dtsConfig file from c# code

I have a dtsConfig file with configuration for ssis package variable User::Quote_ID:
<Configuration ConfiguredType="Property"
Path="\Package.Variables[User::Quote_ID].Properties[Value]"
ValueType="String"><ConfiguredValue>77777</ConfiguredValue></Configuration>
I want to change this value from c# code:
XmlDocument xDoc = new XmlDocument();
xDoc.Load(#"\\MyServer\DataFiles$\...\MyConfigFile.dtsConfig");
XmlNode xFile = xDoc.SelectSingleNode("User::Quote_ID");
xFile.Value = quote_ID.ToString();
xDoc.Save(#"\\MyServer\DataFiles$\...\MyConfigFile.dtsConfig");
xDoc = null;
It gives me an error on the third line of my code (XmlNode...):
‘User::Quote_ID’ has an invalid token
What is wrong?
Chris! Your code helped me a lot! In my case it did not work thought. I ran the application in debug mode and I could see that xDoc.Load... opens the right file, but it did not execute foreach loop. The property listOfConfigurationNodes had Count = 0. I checked my xml file again and found that it has outer node and all nodes inside this outer node. So I changed your code
XmlNodeList listOfConfigurationNodes = xDoc.SelectNodes("Configuration");
I made:
XmlNode XMLOuterNode = xDoc.SelectSingleNode("DTSConfiguration");
XmlNodeList listOfConfigurationNodes = XMLOuterNode.SelectNodes("Configuration");
This code works fine for my particular case. Thanks a lot!!!
The node name is "Configuration". Within that, you have an attribute called "Path", whose value is "\Package.Variables[User::Quote_ID].Properties[Value]".
I'm not sure what you need to do in your code, but here is an example of one way to go about making changes in that value:
XmlDocument xDoc = new XmlDocument();
xDoc.Load(#"\\MyServer\DataFiles$\...\MyConfigFile.dtsConfig");
XmlNode xFile = xDoc.SelectSingleNode("Configuration");
xFile.Attributes["Path"].Value = xFile.Attributes["Path"].Value.Replace("User::Quote_ID", "newValue");
xDoc.Save(#"\\MyServer\DataFiles$\...\MyConfigFile.dtsConfig");
xDoc = null;
The above example will change \Package.Variables[User::Quote_ID].Properties[Value] to \Package.Variables[newValue].Properties[Value].
Updated Example
This will replace the 77777 value with quote_ID.ToString() (I'm assuming the 55555 is in there) for the first node (for all nodes, remove break;) where the 'Path' is \Package.Variables[User::Quote_ID].Properties[Value].
XmlDocument xDoc = new XmlDocument();
xDoc.Load(#"\\MyServer\DataFiles$\...\MyConfigFile.dtsConfig");
XmlNodeList listOfConfigurationNodes = xDoc.SelectNodes("Configuration");
foreach (XmlNode node in listOfConfigurationNodes)
{
if (node.Attributes["Path"].Value == #"\Package.Variables[User::Quote_ID].Properties[Value]")
{
node.SelectSingleNode("ConfiguredValue").InnerText = quote_ID.ToString();
break;
}
}
xDoc.Save(#"\\MyServer\DataFiles$\...\MyConfigFile.dtsConfig");
xDoc = null;

Can't parse XML data with C#

I have been trying to extract one value from a XML file, and then store it on the same file but in another node, I tried all the examples i've found on the net, read XPath Syntax documentation like hell and still can't get it to work.
I must take the <Documento ID="F60T33"> ID Value (which may vary) and copy it into <Reference URI="#F60T33">.
But I can't even do that if I can't manage to parse the lines, most of times node/variables/"", or I get an "object reference not established as object instance error".
Here's the code:
// Create a new XML document.
XmlDocument xmlDoc = new XmlDocument();
// Load an XML file into the XmlDocument object.
xmlDoc.PreserveWhitespace = true;
xmlDoc.Load(pfile);
//TEST !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! PROBLEMA
XmlNodeList Documentos = xmlDoc.GetElementsByTagName("//Documento");
XmlNodeList DatosDocumento = ((XmlElement)Documentos[0]).GetElementsByTagName("ID");
foreach (XmlElement nodo in DatosDocumento)
{
int I = 0;
XmlNodeList ID = nodo.GetElementsByTagName("ID");
Console.WriteLine("Elemento nombre ... {0}}", ID[i].InnerText);
}
//
XmlNodeList nodes = xmlDoc.SelectNodes("EnvioDTE");
XmlNode nodesimple = xmlDoc.SelectSingleNode("EnvioDTE");
Console.WriteLine("Lista Nodos: " + nodes.Count);
Console.WriteLine("Nodo Simple: " + nodesimple.InnerText);
foreach (XmlNode node in nodes)
{
string id = node.Attributes["ID"].InnerText;
Console.WriteLine(id);
}
I am almost certain the problem is on the XPath Syntax, but I can't get it to work.
Sadly I can't use XDocument as im using .NET 3.5 for this task, I would really appreciate some help on this, by behand apologize my bad english
As the XML file is too big, I'll put it here on this URL
http://puu.sh/bVNDc/31e4da5a26.xml
If you can get your references right for using System.Linq.XDocument you can do:
string idValue = xDocument.XPathSelectElement("//EnvioDTE/SetDTE")
.Attributes().SingleOrDefault(a => a.Name == "ID").Value;

Parsing Field Values from Sharepoint List Services Lists.GetList

I'm trying to write something that quickly will grab field values (e.g. combo box, lookups, etc) using the Sharepoint Web Services. The following code works, but is slow and seems inefficient. Is there any way to turn this into a LINQ style query with XDocument/XElement? When I try to Parse the OuterXml it seems to load incorrectly.
MSDN - Lists.GetList
ProuductionResultNode = listservice.GetList(productiontable_listGUID);
XmlDocument doc = new XmlDocument();
doc.LoadXml(ProuductionResultNode.OuterXml);
XmlNamespaceManager mg = new XmlNamespaceManager(doc.NameTable);
mg.AddNamespace("sp", "http://schemas.microsoft.com/sharepoint/soap/");
mg.AddNamespace("z", "#RowsetSchema");
mg.AddNamespace("rs", "urn:schemas-microsoft-com:rowset");
mg.AddNamespace("y", "http://schemas.microsoft.com/sharepoint/soap/ois");
mg.AddNamespace("w", "http://schemas.microsoft.com/WebPart/v2");
mg.AddNamespace("d", "http://schemas.microsoft.com/sharepoint/soap/directory");
XmlNodeList FieldsInList = doc.SelectNodes("//sp:Field", mg);
foreach (XmlNode Field in FieldsInList)
{
if (Field.HasChildNodes)
{
if (Field.Attributes["Name"].Value == fieldNameInternal)
{
foreach (XmlNode node in Field.ChildNodes)
{
if (node.HasChildNodes)
{
foreach (XmlNode Newnode in node.ChildNodes)
{
if (Newnode.HasChildNodes)
{
ret.Add(Newnode.InnerText);
}
}
}
}
}
}
}
return ret;
An example dropdown Field looks like this:
<Field Type="Choice" DisplayName="Media Type" Required="FALSE" Format="Dropdown" FillInChoice="FALSE" ID="{d814daf1-0bd2-48cc-8709-a513a3de4ef4}" SourceID="{1c01c034-f1fd-447f-8ed4-d60b997d0c3a}" StaticName="Media_x0020_Type" Name="Media_x0020_Type" ColName="nvarchar4" RowOrdinal="0" Version="3"><Default>CD/DVD</Default><CHOICES><CHOICE>CD/DVD</CHOICE><CHOICE>Hard Drive</CHOICE><CHOICE>Flash Drive</CHOICE><CHOICE>Virtual</CHOICE></CHOICES></Field>
The other queries I am using for GetListItems seems to work beautfiully.
XElement ziprecords = XElement.Parse(ZipItemsResultNode.OuterXml);
XName name = XName.Get("data", "urn:schemas-microsoft-com:rowset");
var iterationNotes =
from ele in ziprecords.Element(name).Elements()
where ele.Attribute("ows_Title").Value.Contains(fileName
where ele.Attribute("ows_Iteration_x0020_Notes") != null
select new { iterationNote = ele.Attribute("ows_Iteration_x0020_Notes").Value,
fileName = ele.Attribute("ows_Title").Value };
My Solution
I came up with a solution after some searching. I'm not sure why regular Parse and other methods didn't work, but this seems to fix whatever mistakes I was making. I"ll leave this here incase somebody can explain why these steps are needed. I suspect there was an issue with the encoding, which I assumed XDcoument/etc would naturally take care of.
ProuductionResultNode = listservice.GetList(productiontable_listGUID);
XmlDocument xdoc = new XmlDocument();
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xdoc.NameTable);
nsmgr.AddNamespace("ans", "http://schemas.microsoft.com/sharepoint/soap/");
byte[] byteArray = Encoding.ASCII.GetBytes(ProuductionResultNode.SelectSingleNode(".//ans:Fields", nsmgr).OuterXml);
MemoryStream stream = new MemoryStream(byteArray);
XElement xe = XElement.Load(stream);
XElement qry =
(from field in xe.Descendants()
where field.Attribute("Name") != null
where field.Attribute("Name").Value == "Ship_x0020_Via"
select field).Single();
List<string> ret = new List<string>();
foreach (XElement xle in qry.XPathSelectElements(".//ans:CHOICES", nsmgr).Elements())
{
ret.Add(xle.Value);
}

How to Parse XML file in c# (youtube api result)?

I'm trying to parse XML returned from the Youtue API. The APIcalls work correctly and creates an XmlDocument. I can get an XmlNodeList of the "entry" tags, but I'm not sure how to get the elements inside such as the , , etc...
XmlDocument xmlDoc = youtubeService.GetSearchResults(search.Term, "published", 1, 50);
XmlNodeList listNodes = xmlDoc.GetElementsByTagName("entry");
foreach (XmlNode node in listNodes)
{
//not sure how to get elements in here
}
The XML document schema is shown here: http://code.google.com/apis/youtube/2.0/developers_guide_protocol_understanding_video_feeds.html
I know that node.Attributes is the wrong call, but am not sure what the correct one is?
By the way, if there is a better way (faster, less memory) to do this by serializing it or using linq, I'd be happy to use that instead.
Thanks for any help!
Here some examples reading the XmlDocument. I don't know whats fastest or what needs less memory - but i would prefer Linq To Xml because of its clearness.
XmlDocument xmlDoc = youtubeService.GetSearchResults(search.Term, "published", 1, 50);
XmlNodeList listNodes = xmlDoc.GetElementsByTagName("entry");
foreach (XmlNode node in listNodes)
{
// get child nodes
foreach (XmlNode childNode in node.ChildNodes)
{
}
// get specific child nodes
XPathNavigator navigator = node.CreateNavigator();
XPathNodeIterator iterator = navigator.Select(/* xpath selector according to the elements/attributes you need */);
while (iterator.MoveNext())
{
// f.e. iterator.Current.GetAttribute(), iterator.Current.Name and iterator.Current.Value available here
}
}
and the linq to xml one:
XmlDocument xmlDoc = youtubeService.GetSearchResults(search.Term, "published", 1, 50);
XDocument xDoc = XDocument.Parse(xmlDoc.OuterXml);
var entries = from entry in xDoc.Descendants("entry")
select new
{
Id = entry.Element("id").Value,
Categories = entry.Elements("category").Select(c => c.Value)
};
foreach (var entry in entries)
{
// entry.Id and entry.Categories available here
}
I realise this has been answered and LINQ to XML is what I'd go with but another option would be XPathNavigator. Something like
XPathNavigator xmlNav = xmlDoc.CreateNavigator();
XPathNodeIterator xmlitr = xmlNav.Select("/XPath/expression/here")
while (xmlItr.MoveNext()) ...
The code is off the top of my head so it may be wrong and there may be a better way with XPathNavigator but it should give you the general idea
You could use XSD.exe to generate a class based on the schema provided. Once generated, you could then parse the XML response into the strongly typed class.
string xmlResponse = GetMyYouTubeStuff();
MyYouTubeClass response = null;
XmlHelper<MyYouTubeClass> xmlHelper = new XmlHelper<MyYouTubeClass>();
response = xmlHelper.Deserialize(xmlResponse);
And the class for deserializing it...
public class XmlHelper<T>
{
public T Deserialize(string xml)
{
XmlSerializer xs = new XmlSerializer(typeof(T));
Byte[] byteArray = new UTF8Encoding().GetBytes(xml);
MemoryStream memoryStream = new MemoryStream(byteArray);
XmlTextReader xmlTextReader = new XmlTextReader(memoryStream);
T retObj = (T)xs.Deserialize(xmlTextReader);
return retObj;
}
}
There's also another way here.

Categories