I have an XML file like this, in it there is more than one table and I am trying to add a new node at the end of a specific table in the xml file. The user will choose the table and enter his data into a DataGridView.
<?xml version="1.0" encoding="UTF-8"?>
<table name="emloyees">
<emloyees>
<emp_num>employee 1</emp_num>
<department>sales</department>
<salary>1000</salary>
</employees>
<employees>
<emp_num>employee 2</emp_num>
<department>IT</department>
<salary>2000</salary>
</employees>
((for example I want to add new employees node here))
<table name="projects">
<projects>
<proj_num>project 1</proj_num>
<name>hosbital system</name>
<num_mempers>5 members</num_mempers>
</projects>
<projects>
<proj_num>project 2</proj_num>
<name>library system</name>
<num_mempers>4 members</num_mempers>
</projects>
</table>
</table>
I wrote this code, but instead of inserting a new node, the last node of the table gets replaced with the new node instead. How do I fix this?
private void button4_Click(object sender, EventArgs e)
{
XmlDocument doc = new XmlDocument();
doc.Load("Data.xml");
string tablename = comboBox1.SelectedItem.ToString();
XmlNodeList row = doc.GetElementsByTagName(tablename);
int c = row.Count;
for (int j = 0; j < dataGridView1.Rows.Count - 1; j++)
{
XmlNodeList child = row[c - 1].ChildNodes;
XmlElement element = doc.CreateElement(tablename);
for (int k = 0; k < child.Count; k++)
{
XmlElement node = doc.CreateElement(child[k].ToString());
child[k].InnerText = dataGridView1.Rows[j].Cells[k].Value.ToString();
element.AppendChild(node);
}
XmlElement root = doc.DocumentElement;
root.AppendChild(element);
doc.Save("Data.xml");
}
dataGridView1.Rows.Clear();
MessageBox.Show("Successfully Added !!");
}
It seems the problem is here.
for (int k = 0; k < child.Count; k++)
{
XmlElement node = doc.CreateElement(child[k].ToString());
child[k].InnerText = dataGridView1.Rows[j].Cells[k].Value.ToString(); // < here
element.AppendChild(node);
}
You are setting the child[k]'s inner text, not the value of the node you created.
Change child[k] to node
node.InnerText = dataGridView1.Rows[j].Cells[k].Value.ToString();
Your title asks to place the node at a specific place, but your code isn't doing it. You'll need to use the parentNode.InsertAfter(newNode, refNode) method.
So instead of root.AppendChild(element);. Which puts the node at the bottom of the file, use root.InsertAfter(element, child[child.Count - 1]) to put the new node after the last child type you are setting.
AppendChild MSDN docs.
Related
i'm trying to get the sub item from this XML document:
XML CODE HERE :
<RUNNABLES>
<RUNNABLE-ENTITY UUID="1661dcae-c4b9-4f47-8b68-cb99c677bdd6">
<SHORT-NAME>RCtApElg_mlm</SHORT-NAME>
<DESC>
<L-2 L="FOR-ALL">The unique runnable entity of the Main Lights SW Component</L-2>
</DESC>
</RUNNABLES>
So far, this is what i made:
C# code here
XmlDocument xmlReader = new XmlDocument();
xmlReader.PreserveWhitespace = false;
xmlReader.Load(strfilename);
XmlNodeList elemList = xmlReader.SelectNodes("/RUNNABLES/RUNNABLE-ENTITY/SHORT-NAME");
How I can specify to read SHORT-NAME tag and get "RCtApElg_mlm" value as result?
Provided you fix the sample xml (it misses the closure tag for RUNNABLE-ENTITY), this should work:
XmlDocument xmlReader = new XmlDocument();
xmlReader.PreserveWhitespace = false;
xmlReader.Load(strfilename);
XmlNodeList elemList = xmlReader.SelectNodes("//RUNNABLES/RUNNABLE-ENTITY/SHORT-NAME");
string value = elemList.Item(0).InnerText;
I think you need to use:
.Value
XmlNodeList elemList = xmlReader.SelectNodes("/RUNNABLES/RUNNABLE-ENTITY/SHORT-NAME").Value;
Well this is what I did:
XmlNode node = xmlReader.DocumentElement.FirstChild;
XmlNodeList lstPackage = node.ChildNodes;
for (int i = 0; i < 2; i++)
{
//MessageBox.Show(lstPackage[i].Name.ToString());
if (lstPackage[i].Name == "AR-PACKAGE")
{
aux++;
}
if(aux==2)
{
aux = 0;
XmlNodeList lstShortname = lstPackage[i].FirstChild.ChildNodes;
// Display the value of its first child node
for (int j = 0; j < lstShortname.Count; j++)
MessageBox.Show(lstShortname[j].InnerText);
}
}
Dont know if its the best option, but I get as result.
Thanks!
I'm a beginner in C# and have a simple question about TreeView.
I want to do something like this:
> -Root
> -child1
> -child2
> -child3
> -....
I have this:
child.Text = des[j];
root.Nodes.Add(child);
But it just yields something like this:
> -Root
> -child1
I want:
To have a child of a child.
To create 10 TreeNodes in a for statement.
With different names like: root1, root2, root3, etc.
for (i = 0; i < 10; i++)
{
TreeNode root = new TreeNode();
}
You need to add the TreeNode to the Nodes collection of the child, not the root.
child.Text = des[j];
root.Nodes.Add(child);
TreeNode NextChild = new TreeNode();
NextChild.Text = "something";
child.Nodes.Add(NextChild);
For your second Question, you would need to store those treenodes in some kind of datastructure. If you want to name each one, a hashtable would be a good bet.
Hashtable myHT = new Hashtable();
for (int i = 0; i < 10; i++)
{
TreeNode root = new TreeNode();
myHT.Add("Root" + i, root);
}
You would then access them like,
TreeNode myRoot = (TreeNode)myHT["Root1"];
If you are comfortable with Generics you can use the System.Collections.Generic.Dictionary instead for a generic version.
You only need to keep track of the current node and the child to be inserted.
At i = 0, the current node value is the root node.
At i > 0, the current node value is the last child node inserted.
Then, you can try something like this...
TreeNode current = new TreeNode(); // Root node.
current.Text = string.Format("Root");
for (int i = 0; i < 10; i++)
{
TreeNode child = new TreeNode();
child.Text = string.Format("Child: {0}", i);
current.Nodes.Add(child);
current = child;
}
The result of this code will be:
Root
Child: 0
Child: 1
Child: 2
<?xml version="1.0" encoding="UTF-8" ?>
<properties>
<general>
<title type="textbox">title1</title>
<subtitle type="textbox">subtitle1</subtitle>
<radius type="textbox">20</radius>
</general>
<behavior>
<sorting>
<enable type="checkbox">True</enable>
<by type="dropdown">Data</by>
<order type="dropdown">Descending</order>
</sorting>
</behavior>
<appearance>
<series>
<innerseries type="colorpicker">#996666</innerseries>
<innerseries type="colorpicker"></innerseries>
<innerseries type="colorpicker"></innerseries>
<transparency type="slider">19</transparency>
</series>
</appearance>
</properties>
Above is my XML.
In My .ASPX Page:
<asp:TreeView ID="TreeView1" runat="server"
OnSelectedNodeChanged="TreeView1_SelectedNodeChanged1" ImageSet="Arrows"
EnableTheming="true">
</asp:TreeView>
<asp:Button ID="Button1" runat="server" Text="Submit" OnClick="Button1_Click" />
In my Codebehind I dynamically load an xml and build a treeview
protected void Button1_Click(object sender, EventArgs e)
{
doc.LoadXml("XmlFile");
XmlNode node = doc.DocumentElement;
TreeView1.Nodes.Clear();
TreeView1.Nodes.Add(new TreeNode(doc.DocumentElement.Name));
TreeNode tNode = new TreeNode();
tNode = TreeView1.Nodes[0];
Property obj = new Property();
obj.AddChildNode(node, tNode);
}
In my Property.cs (Class File)
public void AddChildNode(XmlNode inXmlNode, TreeNode inTreeNode)
{
XmlNode xNode;
TreeNode tNode;
XmlNodeList nodeList;
int i;
// Loop through the XML nodes until the leaf is reached.
// Add the nodes to the TreeView during the looping process.
//if (inXmlNode.HasChildNodes)
if (inXmlNode.ChildNodes.Count >= 1 && inXmlNode.ChildNodes[0].HasChildNodes)
{
nodeList = inXmlNode.ChildNodes;
for (i = 0; i <= nodeList.Count - 1; i++)
{
xNode = inXmlNode.ChildNodes[i];
inTreeNode.ChildNodes.Add(new TreeNode(xNode.Name));
tNode = inTreeNode.ChildNodes[i];
AddChildNode(xNode, tNode);
}
}
else
{
if (inXmlNode.ChildNodes.Count > 1)
{
nodeList = inXmlNode.ChildNodes;
for (i = 0; i <= nodeList.Count - 1; i++)
{
xNode = inXmlNode.ChildNodes[i];
inTreeNode.ChildNodes.Add(new TreeNode(xNode.Name));
tNode = inTreeNode.ChildNodes[i];
AddChildNode(xNode, tNode);
}
}
// Here you need to pull the data from the XmlNode based on the
// type of node, whether attribute values are required, and so forth.
else
{
if (inXmlNode.ChildNodes.Count == 0)
{
inTreeNode.Text = (inXmlNode.Name).Trim();
inTreeNode.Target = inXmlNode.Attributes[0].Value;
}
else
{
inTreeNode.Text = (inXmlNode.Name).Trim();
inTreeNode.Target = inXmlNode.Attributes[0].Value;
inTreeNode.Value = inXmlNode.ChildNodes[0].Value;
}
}
//inTreeNode.Value = (inXmlNode.OuterXml).Trim();
}
}
The Problem here is, when i run my code and select the Title or Subtile node,the focus is set to that node and SelectIndexChanged event is fired.But, when i select the First Child (Innerseries )it wirks perfectly.When second Innerseries Child is selected,the selection is focused on that node.But, when i Select the Third Child(Innereseries), the focus is on the Second Child .So, it looks like when the node name and value are same ,it selects the first node .
I am new to C#/ASP.Net. and I have a project now that involves binding a tree from two SQL Table. I've done some home work.. and I was able to bind my tree. first here are my tables. My goal is to group my child to it's corresponding parent. but what happens is it the child goes into all the parents. I know i am almost there but i got stuck. :(
tblCategory(parentnodes)
categoryID(varchar(20))
Category(varchar(50))
active(char(1))
tblDocuments(childnodes)
id(int)
description(varchar(100))
title(varchar(20))
categoryid(varchar(20))
tblcategory.categoryid = tbldocuments.categoryid
here are my codes.
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
//bindtree
DataTable dtCategoryNodes = new DataTable();
dtCategoryNodes = content.dtCategoryNodes();
dtCategoryNodes.AcceptChanges();
DataTable dtNodes = new DataTable();
dtNodes = content.GetNodes();
dtNodes.AcceptChanges();
TreeNode CategoryNode = null;
for (int i = 0; i < dtCategoryNodes.Rows.Count; i++)
{
string categoryid = dtCategoryNodes.Rows[i]["CategoryID"].ToString();
CategoryNode = new TreeNode(dtCategoryNodes.Rows[i]
"CATEGORY"].ToString());
CategoryNode.Collapse();
for (int j = 0; j < dtNodes.Rows.Count; j++)
{ string parentid = dtNodes.Rows[j]["parentid"].ToString();
TreeNode childNode = new TreeNode(dtNodes.Rows[j]["TITLE"].ToString());
CategoryNode.ChildNodes.Add(childNode);
}
tvContents.Nodes.Add(CategoryNode);
tvContents.DataBind();
}
}
}
but i had a problem here. here is what happened to my tree.
a. Crift Items
a.1Configuring DCOM
b.Internal Refresher Trainings
b.1Configuring DCOM
c. Product/Process Update
c.1 Configuring DCOM
d.Promotions/Discounts
d.1 Configuring DCOM
e.QA Update
e.1 Configuring DCOM
below is my data
tbldocument
id Title File CategoryID
1 Configuring DCOM DCOM.doc PRODUPDT
tblCategory
CategoryID Category active
CRIFT Crift Items Y
IRTRAIN Internal Refresher Trainings Y
PRODUPDT Product/Process Update Y
PROMODISCS Promotions/Discounts Y
QAUPDT QA Update Y
Appreciate all comments and suggestions! Thanks in advance!
Replace
for (int j = 0; j < dtNodes.Rows.Count; j++)
{ string parentid = dtNodes.Rows[j]["parentid"].ToString();
TreeNode childNode = new TreeNode(dtNodes.Rows[j]["TITLE"].ToString());
CategoryNode.ChildNodes.Add(childNode);
}
With
foreach(DataRow drChild in dtNodes.Select("CategoryID=" + categoryid))
{
TreeNode childNode = new TreeNode(drChild["TITLE"].ToString());
CategoryNode.ChildNodes.Add(childNode);
}
I am trying to write all the dropped elements prperties in a xml document to save in the database.When the user delete a dropped element ,i need to remove that element from the Xml doc.
XmlDocument oXmlDocument = new XmlDocument();
oXmlDocument.Load(#"D:\VanithaApps\SenMail\DiagramData.xml");
Boolean nodeExits = false;
XmlNode oXmlRootNode = oXmlDocument.SelectSingleNode("records");
XmlNodeList xmlnode = oXmlDocument.GetElementsByTagName("record");
if (delete=="1")
{
if (xmlnode.Count > 0)
{
for (int i = 0; i < xmlnode.Count; i++)
{
string tempVar = element.Substring(0, element.Length - 1);
if (xmlnode[i].ChildNodes[2].InnerText == tempVar)
{
try
{
oXmlRootNode.RemoveChild(xmlnode[i]);
goto Found;
}
catch(Exception ex)
{
ex.ToString();
}
}
}
}
}
if (xmlnode.Count > 0)
{
for (int i = 0; i < xmlnode.Count; i++)
{
string tempVar = element.Substring(0, element.Length-1);
if (xmlnode[i].ChildNodes[2].InnerText == tempVar)
{
nodeExits = true;
XmlNode XAxis = xmlnode[i].ChildNodes[0];
XAxis.InnerText = Convert.ToString(x);
XmlNode YAxis = xmlnode[i].ChildNodes[1];
YAxis.InnerText = Convert.ToString(y);
}
}
if (nodeExits == false)
{
CreateNewNode(x, y, element, userid, oXmlDocument, oXmlRootNode);
}
}
else
{
CreateNewNode(x, y, element, userid, oXmlDocument, oXmlRootNode);
}
Found:
int result = 0;
return result;
I haven't used xml extensively before
<?xml version="1.0" encoding="utf-8"?>
<records>
<record>
<X-Cordinate>774</X-Cordinate>
<Y-Cordinate>173</Y-Cordinate>
<Element>drag595</Element>
<UserID>1</UserID>
</record>
</records>
i want to delete whose child 'Element' value is equal to tempVar.Here if the Element value is equal to drag595 ,i want to remove that entry from my XML .
Change
oXmlRootNode.RemoveChild(xmlnode[i]);//not working//
to
xmlnode[i].ParentNode.RemoveChild(xmlnode[i]);
Children can only be removed from their respective parents.