reading namespace kml error NullReferenceException c# [duplicate] - c#

This question already has answers here:
What is a NullReferenceException, and how do I fix it?
(27 answers)
Closed 9 years ago.
i want to parse kml in my c# app.
XmlDocument doc = new XmlDocument();
doc.Load(fileKml);
XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);
ns.AddNamespace("x", "http://www.opengis.net/kml/2.2");
XmlNode nodeKmlns = doc.SelectSingleNode("/x:kml", ns); string sKmlns = nodeKmlns.InnerText;
XmlNode nodeName = doc.SelectSingleNode("GroundOverlay/name"); string sName = nodeName.InnerText;
XmlNode nodehref = doc.SelectSingleNode("GroundOverlay/Icon/href"); string shref = nodehref.InnerText;
XmlNode north = doc.SelectSingleNode("GroundOverlay/LatLonBox/north"); string snorth = north.InnerText; double yn = Convert.ToDouble(snorth);
XmlNode south = doc.SelectSingleNode("GroundOverlay/LatLonBox/south"); string ssouth = south.InnerText; double ys = Convert.ToDouble(ssouth);
XmlNode east = doc.SelectSingleNode("GroundOverlay/LatLonBox/east"); string seast = east.InnerText; double xe = Convert.ToDouble(seast);
XmlNode west = doc.SelectSingleNode("GroundOverlay/LatLonBox/west"); string swest = west.InnerText; double xw = Convert.ToDouble(swest);
and here is my .kml
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
<GroundOverlay>
<name>osm_bandung</name>
<Icon>
<href>files/osm_bandung.png</href>
<viewBoundScale>0.75</viewBoundScale>
</Icon>
<LatLonBox>
<north>-6.928631334672425</north>
<south>-6.956054957857409</south>
<east>107.6467976125619</east>
<west>107.6030622981136</west>
</LatLonBox>
</GroundOverlay>
</kml>
i use addNameSpace but still error
when running, the code error in line
XmlNode nodeName = doc.SelectSingleNode("GroundOverlay/name"); string sName = nodeName.InnerText;
the error is NullReferenceException Object reference not set to an instance of an object.
how to fix that?

I suggest you to use LINQ to XML:
var xdoc = XDocument.Load("data.xml");
XNamespace ns = xdoc.Root.GetDefaultNamespace();
var overlay = xdoc.Root.Element(ns + "GroundOverlay");
var icon = overlay.Element(ns + "Icon");
var box = overlay.Element(ns + "LatLonBox");
var groundOverlay = new
{
Name = (string)overlay.Element(ns + "name"),
Icon = new
{
Href = (string)icon.Element(ns + "href"),
ViewBoundScale = (double)icon.Element(ns + "viewBoundScale")
},
LatLonBox = new
{
North = (double)box.Element(ns + "north"),
South = (double)box.Element(ns + "south"),
East = (double)box.Element(ns + "east"),
West = (double)box.Element(ns + "west")
}
};
Then you can simply use
groundOverlay.LatLonBox.East // 107.6467976125619
Consider also creating custom classes instead of using anonymous types here

Since you specify at least one namespace in your document, all the nodes belong to that namespace. Therefore, you need to always specify the namespace when accessing a node, just like you do when accessing the nodeKmlns node:
XmlDocument doc = new XmlDocument();
doc.Load(fileKml);
XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);
ns.AddNamespace("x", "http://www.opengis.net/kml/2.2");
XmlNode nodeKmlns = doc.SelectSingleNode("/x:kml", ns);
string sKmlns = nodeKmlns.InnerText;
XmlNode nodeName = doc.SelectSingleNode("GroundOverlay/name", ns);
string sName = nodeName.InnerText;
XmlNode nodehref = doc.SelectSingleNode("GroundOverlay/Icon/href", ns);
string shref = nodehref.InnerText;
XmlNode north = doc.SelectSingleNode("GroundOverlay/LatLonBox/north", ns);
string snorth = north.InnerText; double yn = Convert.ToDouble(snorth);
XmlNode south = doc.SelectSingleNode("GroundOverlay/LatLonBox/south", ns);
string ssouth = south.InnerText; double ys = Convert.ToDouble(ssouth);
XmlNode east = doc.SelectSingleNode("GroundOverlay/LatLonBox/east", ns);
string seast = east.InnerText; double xe = Convert.ToDouble(seast);
XmlNode west = doc.SelectSingleNode("GroundOverlay/LatLonBox/west", ns);
string swest = west.InnerText; double xw = Convert.ToDouble(swest);

Related

'This document already has a 'DocumentElement' node.'

I am trying to create a xml document of following format
<TemplateID>xxxxx</TemplateID>
<CaptionOptions>
<CaptionField>
<Field>xxx</Field>
<Text>xxx</Text>
</CaptionField>
<CaptionField>
<Field>xxxx</Field>
<Text>""</Text>
</CaptionField>
</CaptionOptions>
Here is the code that I wrote
XmlDocument xml2 = new XmlDocument();
XmlElement e = xml2.CreateElement("TemplateID");
e.InnerText = "xxxx";
xml2.AppendChild(e);
XmlElement root2 = xml2.CreateElement("CaptionOptions");
xml2.AppendChild(root2); //error here
XmlElement child2a = xml2.CreateElement("CaptionField");
root2.AppendChild(child2a);
XmlElement child2aa = xml2.CreateElement("Field");
child2a.InnerText = "xxxx";
XmlElement child2ab = xml2.CreateElement("Text");
child2a.InnerText = "xxxx";
child2a.AppendChild(child2aa);
child2a.AppendChild(child2ab);
child2a.AppendChild(child2aa);
child2a.AppendChild(child2ab);
My real code was different from the one I was trying to ask earlier....
You could use
XmlElement child = xml.CreateElement("Players");
child.SetAttribute("Nationality", "England");
child.InnerText = "Rooney";
You need to create attributes and append them to the Player element. But your xml hierarchy doesn't look right.
As discussed, now edited.
XmlDocument doc = new XmlDocument();
XmlElement template = doc.CreateElement("Template");
XmlNode id = doc.CreateElement("TemplateID");
id.InnerText = "123456";
template.AppendChild(id);
doc.AppendChild(template);
XmlElement options = doc.CreateElement("CaptionOptions");
XmlElement captionField = doc.CreateElement("CaptionField");
XmlElement field1 = doc.CreateElement("Field");
field1.InnerText = "Field1Text";
XmlElement text1 = doc.CreateElement("Field");
text1.InnerText = "Text1Text";
captionField.AppendChild(field1);
captionField.AppendChild(text1);
options.AppendChild(captionField);
template.AppendChild(options);
string xml = doc.OuterXml;
Hope that helps.

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

How to read xml file c#

<CPT xmlns="http://www.example.org/genericClientProfile" xmlns:ns2="http://www.blahblah.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/genericClientProfile genericClientProfile.xsd">
<header>
<serviceId>CPT-UK</serviceId>
<versionId>1.0</versionId>
<brandCode>CUK</brandCode>
<creationTime>2013-09-26T13:55:32.31+02:00</creationTime>
</header>
</CPT>
I need to be able to read the elements in the header tag. I'm struggling to read the values for some reason, which i'm not sure of. What i've tried:
public ActionResult readxmldata()
{
using (var db = new CPTEntities())
{
var file = System.IO.Directory.GetFiles("C:\\Workspace\\CPTStaging","*.xml");
foreach (var xmldoc in file)
{
XmlDocument docpath = new XmlDocument();
docpath.Load(xmldoc);
CPTPROFILE doc = new CPTPROFILE();
db.SaveChanges();
H_HEADER header = new H_HEADER();
header.SERVICEID = docpath.SelectSingleNode("//CPT/header/#serviceId").Value;
header.VERSIONID = Convert.ToDecimal(docpath.SelectSingleNode("//CPT/header/#versionId").Value);
header.CREATIONTIME = Convert.ToDateTime(docpath.SelectSingleNode("//CPT/header/#creationTime").Value);
header.BRANDCODE = docpath.SelectSingleNode("//CPT/header/#brandCode").Value;
db.CPTPROFILEs.AddObject(doc);
db.SaveChanges();
}
}
Your XML uses namespaces. xmlns attribute declares default namespace. You should use it for each element of the XML.
XNamespace ns = "http://www.example.org/genericClientProfile";
XDocument doc = XDocument.Load(xmldoc);
XElement header = doc.Root.Element(ns + "header");
For comparison, here is one way to do it with Linq-to-XML:
XDocument doc = XDocument.Load(xmlFileName);
XNamespace ns = "http://www.example.org/genericClientProfile";
var header = doc.Descendants(ns+"header").Single();
H_HEADER header = new H_HEADER();
header.SERVICEID = (string) header.Element(ns + "serviceId");
header.VERSIONID = (double) header.Element(ns + "versionId");
header.BRANDCODE = (string) header.Element(ns + "brandCode");
header.CREATIONTIME = (DateTime) header.Element(ns + "creationTime");

xml nodes editing based on an xmlElement

I have tried two ways but they both didnt work..
the first way::
string filepath = Server.MapPath[this is not a link]("XMLFile2.xml");
XmlDocument xdoc = new XmlDocument();
xdoc.Load(filepath);
XmlNode root = xdoc.DocumentElement;
XmlNode idNode = root.SelectSingleNode("/students/student/id");
if (idNode.Value == 9.ToString())
{
var nodeOfStudent = xdoc.SelectNodes("/students/student[#id='9']");
nodeOfStudent[1].InnerXml = TextBox_firstname.Text;
nodeOfStudent[2].InnerXml = TextBox_lastname.Text;
nodeOfStudent[3].InnerXml = TextBox_dob.Text;
nodeOfStudent[4].InnerXml = TextBox_class.Text;
nodeOfStudent[5].InnerXml = TextBox_section.Text;
nodeOfStudent[6].InnerXml = TextBox_telephone.Text;
}
the second way::
string filepath = Server.MapPath("XMLFile2.xml");
XmlDocument xdoc = new XmlDocument();
xdoc.Load(filepath);
XmlNode root = xdoc.DocumentElement;
XmlNode idNode = root.SelectSingleNode("/students/student/id");
xdoc.SelectSingleNode("/students/student[#id='10']/firstname").InnerXml = TextBox_firstname.Text;
xdoc.DocumentElement.AppendChild(firstname);
xdoc.SelectSingleNode("/students/student[#id='10']/lastname").InnerXml = TextBox_firstname.Text;
xdoc.SelectSingleNode("/students/student[#id='10']/dob").InnerXml = TextBox_firstname.Text;
xdoc.SelectSingleNode("/students/student[#id='10']/class").InnerXml = TextBox_firstname.Text;
xdoc.SelectSingleNode("/students/student[#id='10']/section").InnerXml = TextBox_firstname.Text;
xdoc.SelectSingleNode("/students/student[#id='10']/telephone").InnerXml = TextBox_firstname.Text;
xdoc.Save(filepath);
is there something wrong i dont see...
my xml file looks like this::
<students>
<student>
<id>1</id>
<first_name>ahmad</first_name>
<last_name>hani</last_name>
<DOB>12/5/1998</DOB>
<class>sixth</class>
<section>A</section>
<telephone>06555632</telephone>
</student>
</students>
and i used a query string to load the values from a gridView located in another page using "QueryString"....
thanks in advance.
You can easily do this with Linq to xml:
int id = 9;
XDocument xdoc = XDocument.Load(filepath);
var student = xdoc.Descendants("student")
.Where(s => (int)s.Element("id") == id)
.SingleOrDefault();
if (student != null)
{
student.Element("first_name").Value = TextBox_firstname.Text;
student.Element("last_name").Value = TextBox_lastname.Text;
student.Element("DOB").Value = TextBox_dob.Text;
student.Element("class").Value = TextBox_class.Text;
// etc
}
xdoc.Save(filepath);

Sharepoint via web service : checking if item exists in list

Because Microsoft did not include a way to have unique constraints in sharepoint, this has to be done manually.
I am inserting items into a sharepoint list via a web service method.
How can I check if an existing list item already exists with the same field ID value?
I've learnt I should be using wsLists.getListitems web service method, but its not exactly "user friendly". MSDN documentation is again not really great at explaining what should be an easy thing to do.
private bool itemDoesntExist()
{
XmlDocument doc = new XmlDocument();
doc.LoadXml("<Document><Query><Where><Contains><FieldRef Name=\"ID\" /><Value Type=\"Text\">" + this.ID + "</Value></Contains></Where></Query><ViewFields /><QueryOptions /></Document>");
XmlNode listQuery = doc.SelectSingleNode("//Query");
XmlNode listViewFields = doc.SelectSingleNode("//ViewFields");
XmlNode listQueryOptions = doc.SelectSingleNode("//QueryOptions");
XmlNode items = this.wsLists.GetListItems(this.ListName , string.Empty, listQuery, listViewFields, string.Empty, listQueryOptions, null);
if (items.ChildNodes[1].Attributes["ItemCount"].Value == "0")
{
return true;
}
else
{
return false;
}
}
Here's a procedure I wrote 2 years ago that pulls the ID of a document with a given filename... I think you could easily revise it to return true/false if a given ID exists in a list.
protected string GetDocumentID(Lists.Lists ls, string ListGUID, string FileName)
{
string strDocumentID = "-1";
string strViewGUID = "";
string strRowLimit = "50000";
XmlDocument xmlDoc = new XmlDocument();
XmlNode query = xmlDoc.CreateNode(XmlNodeType.Element, "Query", "");
XmlNode viewFields = xmlDoc.CreateNode(XmlNodeType.Element, "ViewFields", "");
XmlNode queryOptions = xmlDoc.CreateNode(XmlNodeType.Element, "QueryOptions", "");
query.InnerXml = "";
viewFields.InnerXml = "";
queryOptions.InnerXml = "<IncludeAttachmentUrls>TRUE</IncludeAttachmentUrls>";
System.Xml.XmlNode nodeListItems = ls.GetListItems(ListGUID, strViewGUID, query, viewFields, strRowLimit, queryOptions, null);
XmlDocument doc = new XmlDocument();
doc.LoadXml(nodeListItems.InnerXml);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("z", "#RowsetSchema");
nsmgr.AddNamespace("rs", "urn:schemas-microsoft-com:rowset");
foreach (XmlNode node in doc.SelectNodes("/rs:data/z:row", nsmgr))
{
if (node.Attributes["ows_LinkFilename"].Value == FileName)
{
strDocumentID = node.Attributes["ows_ID"].Value;
break;
}
}
return strDocumentID;
}
Here's the code that calls it...
Lists.Lists ls = new Lists.Lists();
ls.PreAuthenticate = true;
ls.Credentials = System.Net.CredentialCache.DefaultCredentials;
ls.Url = SharePointSiteURL + #"/_vti_bin/lists.asmx";
string DocID = GetDocumentID(ls, ListGUID, FileName);

Categories