There's my code:
private void removeToolStripMenuItem_Click(object sender, EventArgs e)
{
if (treeView1.SelectedNode != null)
{
if (treeView1.SelectedNode.Parent == null) treeView1.SelectedNode.Remove();
else if (treeView1.SelectedNode.Parent.Nodes.Count == 1) treeView1.SelectedNode.Parent.Remove();
else treeView1.SelectedNode.Remove();
}
XDocument doc = XDocument.Load("test.xml");
if (treeView1.SelectedNode.Parent != null)
{
var xElement = (from q in doc.Elements("dogs").Elements("dog")
where q.Attribute("id").Value == treeView1.SelectedNode.Tag.ToString()
select q);
foreach (var a in xElement)
a.Remove();
doc.Save("test.xml");
}
I want to search through my file for id value and if program will find it, it compares it to tag of selected node, and if it finds it, it'll delete this node. And everytime I'm trying to delete any node, error NullReferenceException was unhandled appears.
When you call:
treeView1.SelectedNode.Remove();
This will either set your treeView1.SelectedNode to null or set the SelectedNode to the removed node's parent or to the next available node.
Also this code will set the parent, of the node you removed, to null. These two cases are likely the root cause of your exception. I would suggest simply setting a temporary variable to point to the node you want removed:
TreeNode node = treeView1.SelectedNode;
treeView1.SelectedNode.Remove();
Then simply change your code to:
TreeNode node = treeView1.SelectedNode;
if (treeView1.SelectedNode != null)
{
if (treeView1.SelectedNode.Parent == null)
treeView1.SelectedNode.Remove();
else if (treeView1.SelectedNode.Parent.Nodes.Count == 1)
treeView1.SelectedNode.Parent.Remove();
else
treeView1.SelectedNode.Remove();
}
XDocument doc = XDocument.Load("test.xml");
var xElement = (from q in doc.Elements("dogs").Elements("dog")
where q.Attribute("id").Value == node.Tag.ToString()
select q);
foreach (var a in xElement)
a.Remove();
doc.Save("test.xml");
Related
I want to add an XmlNode to another XmlNode if it doesn't contain this node (the comparison should be based on the node name and its contents)
System.Xml.XmlDocument doc;
...
XmlNode newNode = doc.CreateElement(name);
newNode.InnerXml = something
XmlNode parentNode = doc.GetElementsByTagName(parentName);
if (parentNode.???? (newNode))
{
parentNode.AppendChild(newNode);
}
How can I check this existence? parentNode.ChildNodes doesn't have a Contain method.
I think this will do the trick:
private void doSomething()
{
XmlDocument doc = new XmlDocument();
XmlNode newNode = doc.CreateElement("name");
newNode.InnerXml = "something";
XmlNode parentNode = doc.GetElementsByTagName("parentName")[0];
// I just stuck an index on end of above line...
// Note that GetElementsByTagName returns an XmlNodeList
int huh = 0;
foreach (XmlNode n in parentNode.ChildNodes)
{
// If I understood you correctly, you want these checks?
if (n.InnerXml == newNode.InnerXml && n.Name == newNode.Name) huh++;
}
if (huh == 0) parentNode.AppendChild(newNode);
}
You could do this using LINQ to XML making use of the XNode.DeepEquals method to compare your child nodes for equality. An example might look like this - the duplicateChild will not be added but newChild will be:
var doc = new XDocument(
new XElement("parent",
new XElement("child", 1)));
var parent = doc.Descendants("parent").Single();
var duplicateChild = new XElement("child", 1);
var newChild = new XElement("child", 2);
if (!parent.Elements().Any(e => XNode.DeepEquals(e, duplicateChild)))
{
parent.Add(duplicateChild);
}
if (!parent.Elements().Any(e => XNode.DeepEquals(e, newChild)))
{
parent.Add(newChild);
}
A demo here: https://dotnetfiddle.net/1t4Q1b
When I write this code, I get only the parent tag value. I want to get their childnodes value also, please tell me about this.
XmlDocument DOC = new XmlDocument();
DOC.RemoveAll();
DOC.Load("C:\\Users\\DIGITEL EYE SYSTEM\\Desktop\\response.xml");
foreach (XmlNode AllNodes in ParentNode)
{
Project.Name = AllNodes["Name"].InnerText;
if (AllNodes.ChildNodes == DOC.GetElementsByTagName("AppBuilderForms"))
{
// Project.Forms = DOC.GetElementsByTagName("");
// String sb = AllNodes["Forms"].InnerText;
}
else if (AllNodes.ChildNodes==DOC.GetElementsByTagName("CheckMarkObject"))
{
checkmark.Name = AllNodes["Name"].InnerText;
checkmark.Label = AllNodes["Label"].InnerText;
// checkmark.IsChecked = AllNodes["IsChecked"].InnerText;
}
else if (ParentNode == DOC.GetElementsByTagName("DateTimeObject"))
{
DateTime.Name = AllNodes["Name"].InnerText;
DateTime.Label = AllNodes["Label"].InnerText;
}
else if (ParentNode == DOC.GetElementsByTagName("LocationObject"))
{
Location.Name = AllNodes["Name"].InnerText;
Location.Label = AllNodes["Label"].InnerText;
Location.Longitude = AllNodes["Longitude"].InnerText;
Location.Latitude = AllNodes["Latitude"].InnerText;
}
else if (ParentNode==DOC.GetElementsByTagName("SwitchObject"))
{
Switch.Name = AllNodes["Name"].InnerText;
Switch.Label = AllNodes["Label"].InnerText;
// Switch.IsChecked =AllNodes["IsChecked"].InnerText;
}
else if(ParentNode==DOC.GetElementsByTagName("TextViewObject"))
{
TextView.Name = AllNodes["Name"].InnerText;
TextView.Value = AllNodes["Value"].InnerText;
}
else if (ParentNode ==DOC.GetElementsByTagName("TextFieldObject"))
{
TextField.Name = AllNodes["Name"].InnerText;
TextField.Value = AllNodes["Value"].InnerText;
}
else if (ParentNode == DOC.GetElementsByTagName("PhotoPickerObject"))
{
PhotoPicker.Name = AllNodes["Name"].InnerText;
PhotoPicker.Label = AllNodes["Label"].InnerText;
}
else if (ParentNode == DOC.GetElementsByTagName("SpinWheelPickerObject"))
{
SpinWheelPicker.Name = AllNodes["Name"].InnerText;
SpinWheelPicker.Label = AllNodes["Label"].InnerText;
// SpinWheelPicker.Columns = AllNodes["Columns"].InnerText;
}
}
var xdoc = XDocument.Load(#"C:\Users\DIGITEL EYE SYSTEM\Desktop\response.xml");
var allElements = xdoc.Root.Elements();
foreach (string element in allElements)
{
//TODO add logic
}
First we'll load up the xml into a XDocument (needs .Net 3.5),
nothing odd going on here.
Second we'll select the root node and ALL
the elements under the root into a IEnumrable. You can add a filter here in the Elements() method.
Third we'll start iterating over the elements in our IEnumerable and implicitly
cast them to a string, this is a operator in the LINQ to XML lib
that just returns the XElement.Value (so if you think that's more
readable or need the whole Element for some other reason write
that! I.E XElement element in allElements)
Don't know how to do it in XmlDocument, I've totally forgotten, hopefully this might help you in case you'll go down that path (pun intended).
<main>
<myself>
<pid>1</pid>
<name>abc</name>
</myself>
<myself>
<pid>2</pid>
<name>efg</name>
</myself>
</main>
that is my XML file named simpan. I have two button. next and previous. What i want to do is, all the info will shows off on the TextBox when the user click the button. The searching node will be based on the pid.
Next button will adding 1 value of pid (let's say pid=2) and it will search on the node that have the same value of pid=2. it also will show the name for the pid=2. (showing name=abc)
Same goes to the previous button where it will reduce 1value of pid (pid=1).
Does anybody knows how to do this?
//-------------EDIT------------------
thanks to L.B, im trying to use his code. however i got an error.
is my implementation of code correct?
private void previousList_Click(object sender, EventArgs e)
{
pid = 14;
XDocument xDoc = XDocument.Parse("C:\\Users\\HDAdmin\\Documents\\Fatty\\SliceEngine\\SliceEngine\\bin\\Debug\\simpan.xml");
var name = xDoc.Descendants("myself")
.First(m => (int)m.Element("PatientID") == pid)
.Value;
textETA.Text = name;
////////////////////
}
int pid = 2;
XDocument xDoc = XDocument.Parse(xml); //Load
var name = xDoc.Descendants("myself")
.First(m => (int)m.Element("pid") == pid)
.Element("name")
.Value;
You can use the following XPath to list all Myself tags, then look for what you want using a simple Linq command:
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(AppDomain.CurrentDomain.BaseDirectory + "file1.xml");
var resNodes = xmlDoc.SelectNodes("//myself");
XmlNode res = null;
var val = textBox1.Text;
var item = from XmlNode x in resNodes
select x;
foreach (var nodP in item) {
foreach (XmlNode nod in nodP.ChildNodes) {
if (nod.InnerText == val) {
res = nodP;
}
}
}
if (res == null)
// not found!
;
else
// show the result
;
Call me old fashioned but you could use an XPath, for example:
string xml =
#"<main>
<myself>
<pid>1</pid>
<name>abc</name>
</myself>
<myself>
<pid>2</pid>
<name>efg</name>
</myself>
</main>";
using System.Xml;
....
XmlDocument xmlDocument = new XmlDocument();
xmlDocument.LoadXml(xml);
// Replace "2" in the string below with the desired pid
XmlNode xmlNode =
xmlDocument.DocumentElement.SelectSingleNode("myself/name[../pid=2]");
// xmlNode contains the <name>efg</name> XmlElement. For example:
string name = xmlNode.Value;
If it can match multiple nodes, for example there could be multiple <myself> elements with a child element <pid> set to 2, use the following instead:
foreach(XmlNode xmlNode in
xmlDocument.DocumentElement.SelectNodes("myself/name[../pid=2]"))
{
// xmlNode contains the matching <name> element
}
In both cases, the value can be extracted from the XmlNode using the Value property.
public class simpman
{
private static XElement root = XElement.Load("Simpman.xml");
public static string GetItem(int index)
{
XElement item =
(from element in root.Elements("myself")
where (int)element.Element("pid") == index
select element.Element("name")).SingleOrDefault();
return item != null ? item.Value : "Please check the Index";
}
}
Initialize a static itemIndex to 1 and use it further like itemIndex++ (for Next) and itemIndex-- (for Prev).
private void previousList_Click(object sender, EventArgs e)
{
pid = 14;
XDocument xDoc = XDocument.Load(#"C:\Users\HDAdmin\Documents\Fatty\SliceEngine\SliceEngine\bin\Debug\simpan.xml");
var name = xDoc.Root
.Descendants("myself")
.FirstOrDefault(e => e.Element("pid")
.Value
.Equals(pid.ToString(CultureInfo.InvariantCulture)))
.Element("name")
.Value;
textETA.Text = name;
}
XmlDocument doc = new XmlDocument();
FileStream fs = new FileStream(rootXMLPath, FileMode.Open, FileAccess.Read);
doc.Load(fs);
XmlNode node = doc.DocumentElement;
nodeName = "/main/myself";
var child1 = node.SelectSingleNode(nodeName).ChildNodes[0].FirstChild.InnerXml;
var child2 = node.SelectSingleNode(nodeName).ChildNodes[0].LastChild.InnerXml;
var child3 = node.SelectSingleNode(nodeName).ChildNodes[1].FirstChild.InnerXml;
var child4 = node.SelectSingleNode(nodeName).ChildNodes[1].LastChild.InnerXml;
I have the the following code sample
private TreeNode AddNode(TreeNode node, string key)
{
var child = node.ChildNodes.Cast<TreeNode>().FirstOrDefault(_ => _.Value == key);
if (child != null)
return child;
child = new TreeNode(key, key);
child.SelectAction = TreeNodeSelectAction.SelectExpand;
child.Selected = true;
node.ChildNodes.Add(child);
return child;
}
I'm not able to select the node. When I invoke treeview_SelectedNodeChanged, I'm getting NULL..
string v = ((TreeView)sender).SelectedNode.Value;
Use treeview.SelectedNode and check the code in page_load handler,
if(!IsPostBack)
{
//code to add nodes
}
How can someone validate that a specific element exists in an XML file? Say I have an ever changing XML file and I need to verify every element exists before reading/parsing it.
if(doc.SelectSingleNode("//mynode")==null)....
Should do it (where doc is your XmlDocument object, obviously)
Alternatively you could use an XSD and validate against that
You can iterate through each and every node and see if a node exists.
doc.Load(xmlPath);
XmlNodeList node = doc.SelectNodes("//Nodes/Node");
foreach (XmlNode chNode in node)
{
try{
if (chNode["innerNode"]==null)
return true; //node exists
//if ... check for any other nodes you need to
}catch(Exception e){return false; //some node doesn't exists.}
}
You iterate through every Node elements under Nodes (say this is root) and check to see if node named 'innerNode' (add others if you need) exists. try..catch is because I suspect this will throw popular 'object reference not set' error if the node does not exist.
//if the problem is "just" to verify that the element exist in the xml-file before you
//extract the value you could do like this
XmlNodeList YOURTEMPVARIABLE = doc.GetElementsByTagName("YOUR_ELEMENTNAME");
if (YOURTEMPVARIABLE.Count > 0 )
{
doctype = YOURTEMPVARIABLE[0].InnerXml;
}
else
{
doctype = "";
}
Not sure what you're wanting to do but using a DTD or schema might be all you need to validate the xml.
Otherwise, if you want to find an element you could use an xpath query to search for a particular element.
How about trying this:
using (XmlTextReader reader = new XmlTextReader(xmlPath))
{
while (reader.Read())
{
if (reader.NodeType == XmlNodeType.Element)
{
//do your code here
}
}
}
additionally to sangam code
if (chNode["innerNode"]["innermostNode"]==null)
return true; //node *parentNode*/innerNode/innermostNode exists
You can validate that and much more by using an XML schema language, like XSD.
If you mean conditionally, within code, then XPath is worth a look as well.
Following is a simple function to check if a particular node is present or not in the xml file.
public boolean envParamExists(String xmlFilePath, String paramName){
try{
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File(xmlFilePath));
doc.getDocumentElement().normalize();
if(doc.getElementsByTagName(paramName).getLength()>0)
return true;
else
return false;
}catch (Exception e) {
//error handling
}
return false;
}
A little bit late, but if it helps, this works for me...
XmlNodeList NodoEstudios = DocumentoXML.SelectNodes("//ALUMNOS/ALUMNO[#id=\"" + Id + "\"]/estudios");
string Proyecto = "";
foreach(XmlElement ElementoProyecto in NodoEstudios)
{
XmlNodeList EleProyecto = ElementoProyecto.GetElementsByTagName("proyecto");
Proyecto = (EleProyecto[0] == null)?"": EleProyecto[0].InnerText;
}
//Check xml element value if exists using XmlReader
using (XmlReader xmlReader = XmlReader.Create(new StringReader("XMLSTRING")))
{
if (xmlReader.ReadToFollowing("XMLNODE"))
{
string nodeValue = xmlReader.ReadElementString("XMLNODE");
}
}
Just came across the same problem and the null-coalescing operator with SelectSingleNode worked a treat, assigning null with string.Empty
foreach (XmlNode txElement in txElements)
{
var txStatus = txElement.SelectSingleNode(".//ns:TxSts", nsmgr).InnerText ?? string.Empty;
var endToEndId = txElement.SelectSingleNode(".//ns:OrgnlEndToEndId", nsmgr).InnerText ?? string.Empty;
var paymentAmount = txElement.SelectSingleNode(".//ns:InstdAmt", nsmgr).InnerText ?? string.Empty;
var paymentAmountCcy = txElement.SelectSingleNode(".//ns:InstdAmt", nsmgr).Attributes["Ccy"].Value ?? string.Empty;
var clientId = txElement.SelectSingleNode(".//ns:OrgnlEndToEndId", nsmgr).InnerText ?? string.Empty;
var bankSortCode = txElement.SelectSingleNode(".//ns:OrgnlEndToEndId", nsmgr).InnerText ?? string.Empty;
//TODO finish Object creation and Upsert DB
}
string name = "some node name";
var xDoc = XDocument.Load("yourFile");
var docRoot = xDoc.Element("your docs root name");
var aNode = docRoot.Elements().Where(x => x.Name == name).FirstOrDefault();
if (aNode == null)
{
return $"file has no {name}";
}
//I am finding childnode ERNO at 2nd but last place
If StrComp(xmlnode(i).ChildNodes.Item(xmlnode(i).ChildNodes.Count - 1).Name.ToString(), "ERNO", CompareMethod.Text) = 0 Then
xmlnode(i).ChildNodes.Item(xmlnode(i).ChildNodes.Count - 1).InnerText = c
Else
elem = xmldoc.CreateElement("ERNo")
elem.InnerText = c.ToString
root.ChildNodes(i).AppendChild(elem)
End If