Exception occuring while extracting the value of the node in xdocument - c#

I have an xml like :
<RunResult>
<PreviewRecords></PreviewRecords>
<RecordsProcessed>100</RecordsProcessed>
<LogError>false</LogError>
</RunResult>
I am using the following command to fetch the value of the node RecordsProcessed ,
int NofRecords = 0;
NofRecords = Convert.ToInt32(xdRunResultDoc.Root.Element("RunResult").Element("RecordsProcessed").Value;
But at this line it is throwing exception " object reference not set to an instance of an object".
Please suggest where I am going wrong.

xdRunResultDoc.Root already points to <RunRdesult> element, so you don't have to call Element("RunResult") again.
And I suggest using (int) casting on XElement instead of Convert.ToInt32: XElement Explicit Conversion (XElement to Int32)
int NofRecords = (int)xdRunResultDoc.Root.Element("RecordsProcessed");

Try this
int NofRcord = Convert.ToInt32(xdRunResultDoc.Root.Element("RecordsProcessed").Value);
See this link for more details http://msdn.microsoft.com/en-us/library/bb675196.aspx

this works for me:
string xmlstring = #"<?xml version='1.0' encoding='utf-8'?>
<RunResult>
<PreviewRecords></PreviewRecords>
<RecordsProcessed>100</RecordsProcessed>
<LogError>false</LogError>
</RunResult>";
System.Xml.Linq.XDocument doc = XDocument.Parse(xmlstring);
int NofRecords = 0;
NofRecords = Convert.ToInt32(doc.Element("RunResult").Element("RecordsProcessed").Value);

You can Find the solution by your self, Why don't you debug and see which causing "object reference not set to an instance of an object" error?
You can add watch to xdRunResultDoc and in the run time you can check what is root node and what you get for xdRunResultDoc.Root.Element("RunResult") etc..
Here your root node is RunResult you can't find Elements inside root node called RunResult
You better check this code project tutorial.

Try this code
read entire text from the xml file and load that to a XmlDocument
XmlNode rootNode = xDoc.SelectSingleNode("RunResult");
if (rootNode.HasChildNodes)
{
foreach (XmlNode node in rootNode.ChildNodes)
{
if (node.Name =="RecordsProcessed")
{
NofRecords=Convert.ToInt32(node.InnerText);
}
}
}

Related

Unable to get values from xml nodes

I am trying to parse through xml and get some values and have tried multiple approaches but i am unable to get the values.
this is what i have tried so far
string fileName = #"C:\Users\one\OneDrive\Desktop\PP\SnippetWithImage.idms";
string xmlString = System.IO.File.ReadAllText(fileName);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(fileName);
XmlNodeList spreadNodes = xmlDoc.GetElementsByTagName("spread");
foreach (XmlNode spreadNode in spreadNodes)
{
var linkNodes = spreadNode.SelectNodes("//rectangle/image/link");
foreach (XmlNode linkNode in linkNodes)
{
Console.WriteLine("path : " + linkNode.SelectSingleNode("LinkResourceURI").InnerText);
}
}
Here spreadNodes count is always 0.
I have tried this with XElements as well and used Decendents but sill the same result.
Here is the xml structure https://codebeautify.org/xmlviewer/y22db1f26
the file which i am loading is an InDesign Snippet file. I am trying to get the linkResourceURI property value from links which is a child of image which is a child of rectangle which is a child of spread.
Some quick debugging shows that spreadNodes is empty, to start with. The most obvious cause is that the element name is Spread not spread, and if we make this change, we see spreadNodes has one element.
Next, it's obvious that spreadNode.SelectNodes("//rectangle/image/link") isn't returning anything. Again, that's probably capitalisation: change it to //Rectangle/Image/Link, and we get a NullReferenceException. Progress, at least.
We're getting that exception because linkNode.SelectSingleNode("LinkResourceURI") is returning null. It turns out that's because LinkResourceURI is an attribute, and you're looking for an element. Change that to linkNode.Attributes["LinkResourceURI"].InnerText, and everything works as expected.
XmlNodeList spreadNodes = xmlDoc.GetElementsByTagName("Spread");
foreach (XmlNode spreadNode in spreadNodes)
{
var linkNodes = spreadNode.SelectNodes("//Rectangle/Image/Link");
foreach (XmlNode linkNode in linkNodes)
{
Console.WriteLine("path : " + linkNode.Attributes["LinkResourceURI"].InnerText);
}
}

Transfer the local name of a XML XElement to string

Hy at all,
i am new in C# programming so maybe this is a easy question.
I try to read an XML-file with XDocument and write out the local name of a Element as string.
For the output i use the listing window of SiemensNX but every other output window or txt-file is suitable.
Here is the Input-XML:
<?xml version="1.0" encoding="utf-8"?>
<Rootlvl>
<Lvl_1>
<Lvl_2/>
</Lvl_1>
</Rootlvl>
Here is the C# code:
using System.Xml.Linq;
using NXOpen;
namespace XmlElementName
{
class Program
{
private static ListingWindow lw = s.ListingWindow;
public static void Main()
{
string XmlFilePath = #"C:\Users\XXX\Desktop\TestXML.xml"; //XML path
string testnode = "Lvl_2"; //local name of a optional XML element
lw.Open(); //open NX listinwindow for output
//=============LoadXmlFile================
//get main Input
XDocument xml = XDocument.Load(XmlFilePath); //load XmlFile
//====================WriteOutElementName====================
XElement node;
if (testnode == null) //if no optional Element name --> take root element of XML
{
node = xml.Root;
}
else
{
// Find node to passed string "testnode" --> here "Lvl_2"
node = xml.Element(testnode);
}
lw.WriteLine("Test"); //Test if output works --> !yes it works
if(node != null)
{
string output = node.Name.LocalName;
//local name of XElement-variable "node" to string
lw.WriteLine(output); //output the local name of variable "node"
}
else
{
lw.WriteLine("Element with Name = " + testnode + "not found")
}
}
}
}
The Output if variable testnode = "Lvl_2" should be:
Test
Lvl_2
The Output if variable testnode = null schould be:
Test
Rootlvl
The VS Debugger show me that
node = xml.Element(testnode); //testnode = Lvl_2
can't find an element in the XML with the the name "Lvl_2". So it set "node" to "Null" and throw the following exeption:
"System.NullReferenceException: Object reference not set to an instance of an object."
But i know that "Lvl_2" is a subelement of the XML. What can i do to found this element "Lvl_2" in the XML?
What should i change in this line
node = xml.Element(testnode)
to find the element by name?
Thanks for your help guys.
According to MSDN:
Method XDocument.Element(XName) gets the first (in document order)
child element with the specified XName.
So, in your case,
node = xml.Element(testnode)
returns null if testnode = "Lvl_2", because Lvl_2 is not a child element of the xml document (only the root node Rootlvl is considered as a child element is this context).
Try using Descendants method instead:
node = xml.Descendants(testnode).FirstOrDefault();
If you put a testnode that is not present in the xml then node is null and it causes an exception, do the check before printing
if (node!=null){
string output = node.Name.LocalName;
//local name of XElement-variable "node" to string
lw.WriteLine(output); //output the local name of variable "node"
}
Thanks #jdweng,
i take the following changes. Now it works.
using system.linq;
and replace
node.xml.Element(testnode);
with
node = xml.Descendents(testnode).FirstOrDefault();

Failing to read value XML attribute in C#

I am trying to read a file produced by another developer. The file looks something like this. I am trying to read in the value for 'ProfileName', but when I look at the object in memory, I see null for the Value (capital V) attribute. The only place I can see the string "GolfLeague-Dual" is in the outerxml attribute, but I would have to parse through a bunch of just to get it.
<?xml version="1.0"?>
<TopNode>
<ProfileSettings>
<ProfileName value="GolfLeague-Dual" />
</ProfileSettings>
</TopNode>
Here is my code to try to read this:
XmlDocument doc = new XmlDocument();
doc.Load(directory + #"\Settings.xml");
XmlElement root = doc.DocumentElement;
XmlNodeList nodes = root.SelectNodes("//ProfileSettings");
foreach (XmlNode node in nodes) {
Console.WriteLine(node["ProfileName"].Value);
}
Your code is trying to get the inner value of the node, not an attribute called value. Try this instead...
foreach (XmlNode node in nodes) {
Console.WriteLine(node["ProfileName"].Attributes["value"].Value);
}
Here's a working dotnetfiddle...
https://dotnetfiddle.net/pmJKbX

Why is my xml doc considered an element?

I am trying to load an xml file into an xmlDocument but receive an error that it cannot cast the xmlelement to a xmldocument why?
XML
<VR>
<SubscriberID>xxxx</SubscriberID>
<EmailAddress>m#gmail.com</EmailAddress>
<FirstName>m</FirstName>
<LastName>x</LastName>
<State>CO</State>
<Country/>
<BirthDate>11/16/3004</BirthDate>
<SendEmail>False</SendEmail>
<Preference Value="true" Key="life"/>
<Preference Value="true" Key="yo"/>
</VR>
C# Test
preferenceHelper target = new preferenceHelper(); // TODO: Initialize to an appropriate value
XmlDocument docIn = new XmlDocument();
docIn.Load(#"C:/INTG/trunk/src/VRI.Integration.Email/Test/xmlIn.xml");
XmlDocument expected = null; // I know this will fail in the test, but it should compile, right?
XmlDocument actual;
actual = target.preferencesXmlDoc(docIn);
Assert.AreEqual(expected, actual);
Assert.Inconclusive("Verify the correctness of this test method.");
C# function:
public class preferenceHelper
{
public preferenceHelper() { }
XmlDocument docOut = new XmlDocument();
public XmlDocument preferencesXmlDoc(XmlDocument docIn)
{
foreach (XmlDocument root in docIn.SelectNodes("//VR"))
{
foreach (XmlDocument node in root.SelectNodes("//Preference"))
{
XmlNode Name = docIn.CreateElement("Name");
Name.InnerText = node.InnerText = node.Attributes["Key"].Value;
XmlNode Value = docIn.CreateElement("Value");
Value.InnerText = node.InnerText = node.Attributes["Value"].Value;
docOut.CreateElement("Property").AppendChild(Name).AppendChild(Value);
}
}
return docOut;
}
}
Error
Test method Test.preferenceHelperTest.preferencesXmlDocTest threw exception:
System.InvalidCastException: Unable to cast object of type 'System.Xml.XmlElement' to type 'System.Xml.XmlDocument'.
I will not be adding a namespace to the xmlIn, if this is required - how might I load in my xml File?
Where it fails: actual = target.preferencesXmlDoc(docIn);
Thanks
Your problems are in these statements:
foreach (XmlDocument root in SelectNodes(...))
foreach implicitly casts each value in the sequence to the type you specify. The statement is expanded to:
using(var e = sequence.GetEnumerator())
{
while (e.MoveNext())
{
XmlDocument v = (XmlDocument)e.Current;
// loop body
}
}
The reason this is crashing with an InvalidCastException is that the type of node you're selecting is XmlElement, not XmlDocument. To fix the issue, simply switch the type in your foreach statement to XmlElement.
You can also improve readability by using XPath to reach the Preference elements, replacing both loops with a single:
foreach (XmlElement node in docIn.SelectNodes("/VR/Preference"))
Your outer SelectNodes loop is actually completely redundant because //Preference will get all Preference descendants from the root of the document already, not just from that specific child VR.
The proplem is here:
foreach (XmlDocument root in docIn.SelectNodes("//VR"))
and here:
foreach (XmlDocument node in root.SelectNodes("//Preference"))
XmlNode.SelectNodes() returns an XmlNodeList, which is an IEnumerable of XmlNodes. It will not contain any XmlDocuments.
So do this:
foreach (XmlNode root in docIn.SelectNodes("//VR"))
and this:
foreach (XmlElement node in root.SelectNodes("//Preference"))
XmlDocument.SelectNodes("//VR") returns an XmlNodeList, not an XmlDocument. So at the least you need to change your code to:
public XmlDocument preferencesXmlDoc(XmlDocument docIn)
{
foreach (XmlNode root in docIn.SelectNodes("//VR"))
{
foreach (XmlNode node in root.SelectNodes("//Preference"))
{
A document usually has a header:
<?xml version="1.0"?>
Without the header it is considered an element.
Try adding one.

Create loops and parsing XML nodes value for Selenium tests

I am trying to write a test function in C# that read data from an XML file and parse into Selenium testing methods , the XML code is like:
<home>
<ask_frame>
<button>
<id>Object ID<id>
<xpath>Object XPath<xpath>
<textbox>
<id>Object ID<id>
<xpath>Object XPath<xpath>
</ask_frame>
<search_frame>
<id>Object ID<id>
<xpath>Object XPath<xpath>
</search_frame>
<home>
I am trying to create a loop that read the id and xpath value from these nodes and parse them into an method for searching a webpage element by id and xpath. My initial attempt was:
Code updated
public void CheckIdTest()
{
driver.Navigate().GoToUrl(baseURL + "FlightSearch");
XmlDocument xd = new XmlDocument();
xd.Load(#"C:\XMLFile1.xml");
XmlNodeList mainlist = xd.SelectNodes("//home/*");
XmlNode mainroot = mainlist[0];
foreach (XmlNode xnode in mainroot)
{
string objID = xnode.SelectSingleNode("id").InnerText;
string objXPath = xnode.SelectSingleNode("XPath").InnerText;
objID = objID.Trim();
objXPath = objXPath.Trim();
String checkValue = "ObjID value is: " + objID + Environment.NewLine+ "ObjXPath value is: " + objXPath;
System.IO.File.WriteAllText(#"C:\checkvalue.txt", checkValue);
objectCheck(objXPath, objID);
}
}
I have put a String and checked that correct values for ObjID and ObjXPath have been achieved, but this loop also went only twice (checked 2 nodes in first branch). How could I make it runs through every node in my XML?
Any suggestions and explanations to the code will be highly appreciated.
Basically these two lines are using incorrect XPath :
XmlNodeList idlist = xd.SelectNodes("id");
XmlNodeList xpathlist = xd.SelectNodes("XPath");
<id> and <xpath> nodes aren't located directly at the root level, so you can't access it just like above. Besides, xpath is case-sensitive so you should've used "xpath" instead of "XPath". Try to fix it like this :
XmlNodeList idlist = xd.SelectNodes("//id");
XmlNodeList xpathlist = xd.SelectNodes("//xpath");
or more verbose :
XmlNodeList idlist = xd.SelectNodes("home/*/id");
XmlNodeList xpathlist = xd.SelectNodes("home/*/xpath");
UPDATE :
Responding to your comment about looping problem, I think you want to change it like this :
foreach (XmlNode xnode in mainroot.ChildNodes)
{
string objID = xnode.SelectSingleNode("id").InnerText;
string objXPath = pathroot.SelectSingleNode("xpath").InnerText;
objectCheck(objID, objXPath);
}
You are getting this error because you are trying to use an object that is null i.e not instantiated.
Put in a breakpoint at the line
XmlDocument xd = new XmlDocument();
and step through line by line till you find where the nothing.null reference is.
It should not take long to find out what the problem is.

Categories

Resources