Child node is repeating, can't get it to work - c#

i have an xml code that create an xml file and this works great however i am a bit confused on why one of the parent node still opens and it does not group by employee first ( the employee hours and workdays should only open up once as long as the employee id is the same and close at the end when all days have been created) see attached code `
// Create a new <Employees> element and add it to the root node
XmlElement Employees = xmlDoc.CreateElement("employees");
xmlDoc.DocumentElement.AppendChild(Employees);
// Create a new <staffingHours> element and add it to the root node
XmlElement parentNode = xmlDoc.CreateElement("CompanyHours");
// Set attribute name and value!
parentNode.SetAttribute("processType", "merge");
xmlDoc.DocumentElement.PrependChild(parentNode);
string catid = "";
string nurseCode = GridView1.Rows[0].Cells[0].Text;
foreach ( GridViewRow row in GridView1.Rows)
{
//first part of EMPLOYEES ELEMENTS AND CHILD ELEMENTS
string fromFormat = "MM/dd/yyyy";
string toFormat = "yyyy-MM-dd";
if (catid != row.Cells[0].Text)
{
XmlElement employee = xmlDoc.CreateElement("employee");
xmlDoc.DocumentElement.AppendChild(employee);
Employees.AppendChild(employee);
//create the element
XmlElement NurseId1 = xmlDoc.CreateElement("employeeId");
employee.AppendChild(NurseId1);
NurseId1.InnerText = row.Cells[0].Text;
XmlElement HireDate1 = xmlDoc.CreateElement("hireDate");
employee.AppendChild(HireDate1);
DateTime newdate = DateTime.ParseExact(row.Cells[6].Text, fromFormat, null);
HireDate1.InnerText = newdate.ToString(toFormat);//row.Cells[6].Text;
xmlDoc.DocumentElement.InsertAfter(Employees, xmlDoc.DocumentElement.LastChild);
}
XmlElement EmployeeHours = xmlDoc.CreateElement("EmployeeHours");
if (catid != row.Cells[0].Text)
{
XmlElement NurseId = xmlDoc.CreateElement("employeeId");
staffHours.AppendChild(NurseId);
NurseId.InnerText = row.Cells[0].Text;
}
XmlElement WorkDays = xmlDoc.CreateElement("workDays");
XmlElement WorkDay = xmlDoc.CreateElement("workDay");
//Third node and data source
XmlElement Date = xmlDoc.CreateElement("date");
WorkDay.AppendChild(Date);
DateTime converteddate = DateTime.ParseExact(row.Cells[1].Text,
fromFormat, null);
Date.InnerText = converteddate.ToString(toFormat);
XmlElement hourEntries = xmlDoc.CreateElement("hourEntries");
xmlDoc.DocumentElement.PrependChild(hourEntries);
WorkDay.AppendChild(hourEntries);
XmlElement HourEntry = xmlDoc.CreateElement("hourEntry");
xmlDoc.DocumentElement.PrependChild(HourEntry);
hourEntries.AppendChild(HourEntry);
//Fourth node and data source
XmlElement Hours = xmlDoc.CreateElement("hours");
HourEntry.AppendChild(Hours);
Hours.InnerText = row.Cells[2].Text;
XmlElement JobTitleCode = xmlDoc.CreateElement("jobTitleCode");
HourEntry.AppendChild(JobTitleCode);
JobTitleCode.InnerText = row.Cells[3].Text;
XmlElement payTypeCode = xmlDoc.CreateElement("payTypeCode");
HourEntry.AppendChild(payTypeCode);
payTypeCode.InnerText = row.Cells[4].Text;
staffHours.AppendChild(WorkDays);
WorkDays.AppendChild(WorkDay);
parentNode.AppendChild(EmployeeHours);
xmlDoc.DocumentElement.InsertAfter(parentNode,
xmlDoc.DocumentElement.LastChild);
catid = row.Cells[0].Text;}
now once this code runs it create the attached image but i don't want the highlighted lines repeating inside the same parent node...
[1]: https://i.stack.imgur.com/eirsv.png

My issue was the element was inside of my loop i needed a new set of eyes to look into this. Good catch Tamas Szabo. issue is resolved.

Related

XML element not displaying for empty values

I am using an xml file to import into the database using the below code
CS:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(pathPMO + "Data.xml");
XmlNodeList nodeList = xmlDoc.DocumentElement.SelectNodes("/DocumentElement/Profile");
bool insertProfile = false;
foreach (XmlNode node in nodeList)
{
strYear = node.SelectSingleNode("Profile_x0020_Year").InnerText;
strID = node.SelectSingleNode("Profile_x0020_ID").InnerText;
strLead = node.SelectSingleNode("Profile_x0020_Leader").InnerText;
insertProfile = ImportProfile(strYear, strID, strLead);
}
For instance the profile leader values are empty for certain rows and when I try to insert them I get an error object not set to an instance of an object because of that particular element missing in few rows.
Can anyone suggest how to solve this?
You should ensure that each XmlNode object is not null. You can use a simple method like that:
private string GetXmlNodeString(string nodeName, XmlNode node)
{
if(String.IsNullOrWhiteSpace(nodeName))
return String.Empty;
var singleNode = node.SelectSingleNode(nodeName);
if(singleNode ==null)
return String.Empty;
return singleNode.InnerText;
}
then change your code like that:
foreach (XmlNode node in nodeList)
{
strYear = GetXmlNodeString("Profile_x0020_Year",node);
strID = GetXmlNodeString("Profile_x0020_ID",node);
strLead = GetXmlNodeString("Profile_x0020_Leader",node);
insertProfile = ImportProfile(strYear, strID, strLead);
}

How do I store values from textbox in C#

I created this program to get texts from textboxes and store in a xml file but it doesn't store. Also if I close the form and reopen it and enter data again how can it update the same existing file without replacing the previous data.? please fix my code
private void button1_Click(object sender, EventArgs e)
{
string name = this.txtName.Text;
string occupation = this.txtOccupation.Text;
string dob = this.txtDob.Text;
string nic = this.txtNic.Text;
double id = double.Parse(this.lblID.Text);
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.CreateXmlDeclaration("1.0", "utf-8", "yes");
XmlNode rootNode = xmlDoc.CreateElement("Users");
XmlNode subNode = xmlDoc.CreateElement("Users");
XmlAttribute nameAtt = xmlDoc.CreateAttribute("Name");
nameAtt.Value = name;
XmlAttribute occupationAtt = xmlDoc.CreateAttribute("Occupation");
occupationAtt.Value = occupation;
XmlAttribute dobAtt = xmlDoc.CreateAttribute("Date of Birth");
dobAtt.Value = dob;
XmlAttribute nicAtt = xmlDoc.CreateAttribute("NIC");
nicAtt.Value = nic;
XmlAttribute idAtt = xmlDoc.CreateAttribute("ID");
idAtt.Value = idAtt.ToString();
subNode.Attributes.Append(nameAtt);
subNode.Attributes.Append(occupationAtt);
subNode.Attributes.Append(dobAtt);
subNode.Attributes.Append(nicAtt);
subNode.Attributes.Append(idAtt);
rootNode.AppendChild(subNode);
subNode.AppendChild(rootNode);
xmlDoc.Save("E:/Data.xml");
Hide();
}
}
}
This is just a simple working example based on the code you provided, but probably there are better ways to accomplish what you are trying to do:
private void button1_Click(object sender, EventArgs e)
{
string name = this.txtName.Text;
string occupation = this.txtOccupation.Text;
string dob = this.txtDob.Text;
string nic = this.txtNic.Text;
double id = double.Parse(this.lblID.Text);
// XML file path.
string xmlPath = "E:/Data.xml";
XmlDocument xmlDoc = new XmlDocument();
// If specified file does not exist, create a new one.
if (!File.Exists(xmlPath))
{
XmlDeclaration xmlDeclaration = xmlDoc.CreateXmlDeclaration("1.0", "UTF-8", "yes");
XmlElement rootNode = xmlDoc.DocumentElement;
xmlDoc.InsertAfter(xmlDeclaration, rootNode);
XmlNode parentNode = xmlDoc.CreateElement("Users");
XmlNode subNode = xmlDoc.CreateElement("User");
XmlAttribute nameAtt = xmlDoc.CreateAttribute("Name");
nameAtt.Value = name;
XmlAttribute occupationAtt = xmlDoc.CreateAttribute("Occupation");
occupationAtt.Value = occupation;
XmlAttribute dobAtt = xmlDoc.CreateAttribute("Date_Of_Birth");
dobAtt.Value = dob;
XmlAttribute nicAtt = xmlDoc.CreateAttribute("NIC");
nicAtt.Value = nic;
XmlAttribute idAtt = xmlDoc.CreateAttribute("ID");
idAtt.Value = id.ToString();
subNode.Attributes.Append(nameAtt);
subNode.Attributes.Append(occupationAtt);
subNode.Attributes.Append(dobAtt);
subNode.Attributes.Append(nicAtt);
subNode.Attributes.Append(idAtt);
xmlDoc.AppendChild(parentNode);
parentNode.AppendChild(subNode);
// Save new XML file.
xmlDoc.Save(xmlPath);
}
// If specified file exists, read and update it.
else
{
// Open existing XML file.
xmlDoc.Load(xmlPath);
// Set to true if current name is already found in the XML file,
// of course it should be better to check the ID instead the name,
// supposing that ID is unique.
bool nameFound = false;
// Get all "User" nodes and check if one of them already contains
// the specified name.
foreach (XmlNode user in xmlDoc.SelectNodes("Users/User"))
{
if (user.Attributes.GetNamedItem("Name").Value == name)
{
nameFound = true;
break;
}
}
// If the name is not already in the file, insert a new user
// with that name.
if (nameFound == false)
{
XmlNode subNode = xmlDoc.CreateElement("User");
XmlAttribute nameAtt = xmlDoc.CreateAttribute("Name");
nameAtt.Value = name;
XmlAttribute occupationAtt = xmlDoc.CreateAttribute("Occupation");
occupationAtt.Value = occupation;
XmlAttribute dobAtt = xmlDoc.CreateAttribute("Date_Of_Birth");
dobAtt.Value = dob;
XmlAttribute nicAtt = xmlDoc.CreateAttribute("NIC");
nicAtt.Value = nic;
XmlAttribute idAtt = xmlDoc.CreateAttribute("ID");
idAtt.Value = id.ToString();
subNode.Attributes.Append(nameAtt);
subNode.Attributes.Append(occupationAtt);
subNode.Attributes.Append(dobAtt);
subNode.Attributes.Append(nicAtt);
subNode.Attributes.Append(idAtt);
xmlDoc.SelectSingleNode("Users").AppendChild(subNode);
xmlDoc.Save(xmlPath);
}
}
}
And this is a sample output XML file:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Users>
<User Name="John" Occupation="student" Date_Of_Birth="1990" NIC="NIC" ID="123" />
<User Name="David" Occupation="professor" Date_Of_Birth="1973" NIC="NIC" ID="452" />
</Users>

Combine two XMLDocuments rss

I've got two rss feeds I would like to merge together to make one. I've actually managed to merge the two feeds together and place the items in correct place - however the data in each attribute, i.e. title contains title+link+description+author+pubDate - and that repeats for link, description, author and pubdate. Can someone help me dubug it please?
Object rssData = new object();
Cms.UI.CommonUI.ApplicationAPI AppAPI = new Cms.UI.CommonUI.ApplicationAPI();
rssData = AppAPI.ecmRssSummary(50, true, "DateCreated", 0, "");
Response.ContentType = "text/xml";
Response.ContentEncoding = System.Text.Encoding.UTF8;
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(rssData.ToString());
//************************************************************
// Obtain 5 data items from second list
Object rssData1 = new object();
Cms.UI.CommonUI.ApplicationAPI AppAPI1 = new Cms.UI.CommonUI.ApplicationAPI();
rssData1 = AppAPI1.ecmRssSummary(60, true, "DateCreated", 5, "");
XmlDocument xmlDocument1 = new XmlDocument();
xmlDocument1.LoadXml(rssData1.ToString());
XmlNodeList nl = xmlDocument1.SelectNodes("/rss/channel");
XmlNode root = nl[0]; //do I need this line?
foreach (XmlNode xnode1 in root.ChildNodes)
{
string title = xnode1.InnerText;
string link = xnode1.InnerText;
string desc = xnode1.InnerText;
string auth = xnode1.InnerText;
string pdate = xnode1.InnerText;
//Merge new nodes
node = xmlDocument.CreateNode(XmlNodeType.Element, "item", null);
//node.InnerText = "this is new node";
//create title node
XmlNode nodeTitle = xmlDocument.CreateElement("title");
nodeTitle.InnerText = title;
//create Link node
XmlNode nodeLink = xmlDocument.CreateElement("link");
nodeLink.InnerText = link;
XmlNode nodeDesc = xmlDocument.CreateElement("description");
nodeDesc.InnerText = desc;
XmlNode nodeAuthor = xmlDocument.CreateElement("author");
nodeAuthor.InnerText = auth;
XmlNode nodepubDate = xmlDocument.CreateElement("pubDate");
nodepubDate.InnerText = pdate;
//add to parent node
node.AppendChild(nodeTitle);
node.AppendChild(nodeLink);
node.AppendChild(nodeDesc);
node.AppendChild(nodeAuthor);
node.AppendChild(nodepubDate);
//add to elements collection
//xmlDocument.DocumentElement.AppendChild(node);
xmlDocument.DocumentElement.SelectNodes("/rss/channel")[0].AppendChild(node);
}
//********************************************
xmlDocument.Save(Response.Output);
As you rightly suspected, the problem is here:
string title = xnode1.InnerText;
string link = xnode1.InnerText;
string desc = xnode1.InnerText;
string auth = xnode1.InnerText;
string pdate = xnode1.InnerText;
No wonder that
the data in each attribute, i.e. title contains
title+link+description+author+pubDate - and that repeats for link,
description, author and pubdate.
You need to read the values of specific subelements of each node. Probably something like:
string title = xnode1["title"].InnerText;
etc.
See http://www.csharp-examples.net/xml-nodes-by-name/ for reference.
Konrad's answer is clear, but it might not work if there's nested tags within the title tag.
Say, <title> TEXT <tag1> OTHER_TEXT </tag1></title>
On my computer, it will return you a concatenation of TEXT and OTHER_TEXT.
This should work:
string title = xnode1["title"].FirstChild.Value;
FirstChild will get you the TEXT no matter whether there is other tags with the title or not.

SqlDataReader not producing XML document

I am trying to dynamically create a XML for a webservice but when I test the service I get the following error
XML Parsing Error: no element found
Location: http://stuiis.cms.gre.ac.uk/dd615/aspweb/WatCoursework/Service.asmx/getMusicdetailsSql
Line Number 1, Column 39:
--------------------------------------^
// Make a new XML document in memory.
XmlDocument doc = new XmlDocument();
// Fill this document with a root element
// named <Inventory>.
XmlElement musicInformation = doc.CreateElement("musicInformation");
using (SqlDataReader oDr = myCommand.ExecuteReader())
{
while (oDr.Read())
{
// Now, make a sub element named <Car> with
// an ID attribute.
XmlElement musicdetails = doc.CreateElement("musicdetails");
musicdetails.SetAttribute("m_id", oDr["m_id"].ToString());
// Build the data within the <Car> element.
XmlElement p_id = doc.CreateElement("p_id");
p_id.InnerText = oDr["p_id"].ToString();
XmlElement artistname = doc.CreateElement("artistname");
artistname.InnerText = oDr["artistname"].ToString();
XmlElement recordname = doc.CreateElement("recordname");
recordname.InnerText = oDr["recordname"].ToString();
XmlElement recordtype = doc.CreateElement("recordtype");
recordtype.InnerText = oDr["recordtype"].ToString();
XmlElement format = doc.CreateElement("format");
format.InnerText = oDr["format"].ToString();
XmlElement price = doc.CreateElement("price");
price.InnerText = oDr["price"].ToString();
musicdetails.AppendChild(p_id);
musicdetails.AppendChild(artistname);
musicdetails.AppendChild(recordname);
musicdetails.AppendChild(recordtype);
musicdetails.AppendChild(format);
musicdetails.AppendChild(price);
musicInformation.AppendChild(musicdetails);
}
return doc;
}
I think you forgot to add the musicInformation to the document:
}
doc.AppendChild(musicInformation);
return doc;
}

Problem in iterating sharepoint folder content

I am trying to access Folder from Document Library using web services in C#.
I am using SiteData's EnumerateFolder() method to get sub folders and files. But the method gives me only 3 properties for each entry.
IsFolder
Url
Last modified date
So how can we get 'Modified By' field value.
Or there is another solution for enumerating folders and subfolders.
Thanks.
You need to use the List API in order to get more properties from your objects.
[Edit - complete code sample]
The sample needs to be cleaned up, but should give you what you need
public void SomeFunction()
{
Lists lists = new Lists(); //http://server/_vti_bin/Lists.asmx
XmlNode coll = lists.GetListCollection();
XmlNamespaceManager nsMgr = new XmlNamespaceManager(coll.OwnerDocument.NameTable);
nsMgr.AddNamespace("sp", "http://schemas.microsoft.com/sharepoint/soap/");
nsMgr.AddNamespace("z", "#RowsetSchema");
XmlDocument xmlDoc = new XmlDocument();
XmlElement query = xmlDoc.CreateElement("Query");
XmlElement viewFields = xmlDoc.CreateElement("ViewFields");
XmlElement queryOptions = xmlDoc.CreateElement("QueryOptions");
viewFields.InnerXml = "<FieldRef Name=\"Modified_x0020_By\" />";
queryOptions.InnerXml = "<ViewAttributes Scope=\"RecursiveAll\"/>";
XmlNodeList siteLists = coll.SelectNodes("//sp:List", nsMgr);
foreach (XmlNode list in siteLists)
{
if (list.Attributes["ServerTemplate"].Value != "101") continue; //101=DocLib
XmlNode listItemCollection = lists.GetListItems(list.Attributes["Name"].Value, string.Empty, query,
viewFields, "4000",
queryOptions, null);
XmlNodeList listItems = listItemCollection.SelectNodes("//z:row", nsMgr);
foreach (XmlNode listItem in listItems)
{
if (listItem.Attributes["ows_FSObjType"] == null) continue;
if (!listItem.Attributes["ows_FSObjType"].Value.EndsWith("#1")) continue;
PrintModifiedBy(listItem);
}
}
}
private void PrintModifiedBy(XmlNode listItem)
{
string modifiedBy;
if (listItem.Attributes["Modified_x0020_By"] != null)
modifiedBy = listItem.Attributes["ows_Modified_x0020_By"].Value;
else
modifiedBy = listItem.Attributes["ows_Editor"].Value;
Console.WriteLine(modifiedBy);
}

Categories