code below:
protected void generate_Click(object sender, EventArgs e)
{
XmlDocument doc = new XmlDocument();
doc.PreserveWhitespace = true;
doc.Load("XmlFileName");
XmlNode node = doc.SelectSingleNode("ChartData/XaxisFields/XaxisField");
if (node != null)
{
node.ChildNodes.Item(0).InnerXml = "hi";
doc.Save("XmlFileName");
}
}
Showing null refernce here,
node.ChildNodes.Item(0).InnerXml = "hi";
Is the code is correct,the code behind running not showing any error
but the Xaxisfield is not added.
<?xml version="1.0" encoding="utf-8" ?>
<ChartData>
<XaxisFields>
<XaxisField></XaxisField>
</XaxisFields>
</ChartData>
List item
I want to add the childnode Xaxisfield in the xml file by selcting the particular parent node
You can use Linq to Xml to select your node and update its value:
var xdoc = XDocument.Load("XmlFileName");
xdoc.Root.Element("XaxisFields").Element("XaxisField").Value = "hi";
// OR
// xdoc.XPathSelectElement("//XaxisField").Value = "hi";
xdoc.Save("XmlFileName");
Also your code is not working because there is no child nodes of XaxisField node. This will work:
XmlDocument doc = new XmlDocument();
doc.PreserveWhitespace = true;
doc.Load("XmlFileName");
XmlNode node = doc.SelectSingleNode("ChartData/XaxisFields/XaxisField");
if (node != null)
{
node.InnerXml = "hi";
doc.Save("XmlFileName");
}
Related
I'm trying to populate a Combobox in C# using a field from my XML file, but with no luck... I don't know what is wrong here (it doesn't show anything):
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
XmlDocument doc = new XmlDocument();
doc.Load("Baza_de_cunostinte.xml");
var dataSource = new List<Persoane>();
string PersoanaPlacuta;
foreach (XmlNode node in doc.DocumentElement)
{
string persoanaPlacuta = node["PersoanaPlacuta"].InnerText.Replace("\"", "");
comboBox1.Items.Add(persoanaPlacuta);
}
}
This is the XML file:
<root>
<Persoane>
<Nume>"Bob"</Nume>
<IsMale>true</IsMale>
<Varsta>30</Varsta>
<PersoanaPlacuta>"Iulia"</PersoanaPlacuta>
</Persoane>
<Persoane>
<Nume>"Bogdan"</Nume>
<IsMale>true</IsMale>
<Varsta>28</Varsta>
<PersoanaPlacuta>"Ana"</PersoanaPlacuta>
</Persoane>
</root>
I don't think your are searching in the right Xml node address. You should do it with the full address in order to find the targeted node.
Use XmlNodeList to get all the nodes with the full address and then loop through its items:
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
XmlDocument doc = new XmlDocument();
doc.Load("Baza_de_cunostinte.xml");
var dataSource = new List<Persoane>();
string PersoanaPlacuta;
XmlNodeList xmlNodeList = doc.SelectNodes("//root//Persoane");
foreach (XmlNode node in xmlNodeList)
{
string PersoanaPlacuta = node.ChildNodes[3].InnerText.Replace("\"", "");
comboBox1.Items.Add(PersoanaPlacuta);
}
}
Also you can change the foreach loop like this:
foreach (string PersoanaPlacuta in from XmlNode node in xmlNodeList
select node.ChildNodes[3].InnerText.Replace("\"", ""))
{
comboBox1.Items.Add(PersoanaPlacuta);
}
Note: You better add comboBox1.Items.Clear(); at the first line, otherwise you will get repetitive items in your ComboBox
I've got a Web Service that uses an XML document and I'm trying to add a function that adds a new node to the XML document. It runs fine and doesn't break, but the save function doesn't seem to work? Here's the code;
[WebMethod]
public void AddNodeTEST()
{
XmlDocument xmlUpdateCfg = new XmlDocument();
try
{
xmlUpdateCfg.Load(Context.Request.MapPath("Updates.xml"));
}
catch (Exception ex)
{
}
XmlNode updateInfo = xmlUpdateCfg.SelectSingleNode("updateinfo");
/* Create the downloadmodule node */
XmlNode newDownloadModule = xmlUpdateCfg.CreateNode(XmlNodeType.Element, "downloadmodule", null);
newDownloadModule.InnerText = "download/test.CAB";
XmlAttribute downloadModuleName = xmlUpdateCfg.CreateAttribute("name");
downloadModuleName.Value = "Test";
newDownloadModule.Attributes.Append(downloadModuleName);
/* Create the version node */
XmlNode newVersion = xmlUpdateCfg.CreateNode(XmlNodeType.Element, "version", null);
XmlAttribute versionMaj = xmlUpdateCfg.CreateAttribute("maj");
versionMaj.Value = "1";
XmlAttribute versionMin = xmlUpdateCfg.CreateAttribute("min");
versionMin.Value = "2";
XmlAttribute versionBld = xmlUpdateCfg.CreateAttribute("bld");
versionBld.Value = "3";
XmlAttribute versionRev = xmlUpdateCfg.CreateAttribute("rev");
versionRev.Value = "4";
newVersion.Attributes.Append(versionMaj);
newVersion.Attributes.Append(versionMin);
newVersion.Attributes.Append(versionBld);
newVersion.Attributes.Append(versionRev);
/* Add the newVersion node to the newDownloadModule node */
newDownloadModule.AppendChild(newVersion);
/* Add the newDownloadModule to the updateinfo Node*/
updateInfo.AppendChild(newDownloadModule);
xmlUpdateCfg.Save("Updates.xml");
}
and here is the XML structure;
<?xml version="1.0" encoding="utf-8" ?>
<updateinfo>
<downloadmodule name="test">
<version maj="1" min="0" bld="4" rev="0"/>
Download/cabfile.CAB
</downloadmodule>
</updateinfo>
Any help is appreciated, thanks!.
Shouldn't you be calling xmlUpdateCfg.Save(Context.Request.MapPath("Updates.xml")) so that it saves it to the same location it read it from?
<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 currently have the following code:
XPathNodeIterator theNodes = theNav.Select(theXPath.ToString());
while (theNodes.MoveNext())
{
//some attempts i though were close
//theNodes.RemoveChild(theNodes.Current.OuterXml);
//theNodes.Current.DeleteSelf();
}
I have set xpath to what I want to return in xml and I want to delete everything that is looped. I have tried a few ways of deleting the information but it does't like my syntax. I found an example on Microsoft support: http://support.microsoft.com/kb/317666 but I would like to use this while instead of a for each.
Any comments or questions are appreciated.
Why not to use XDocument?
var xmlText = "<Elements><Element1 /><Element2 /></Elements>";
var document = XDocument.Parse(xmlText);
var element = document.XPathSelectElement("Elements/Element1");
element.Remove();
var result = document.ToString();
result will be <Elements><Element2 /></Elements>.
Or:
var document = XDocument.Load(fileName);
var element = document.XPathSelectElement("Elements/Element1");
element.Remove();
document.Savel(fileName);
[Edit] For .NET 2, you can use XmlDocument:
XmlDocument document = new XmlDocument();
document.Load(fileName);
XmlNode node = document.SelectSingleNode("Elements/Element1");
node.ParentNode.RemoveChild(node);
document.Save(fileName);
[EDIT]
If you need to remove all child elements and attributes:
XmlNode node = document.SelectSingleNode("Elements");
node.RemoveAll();
If you need to keep attributes, but delete elements:
XmlNode node = document.SelectSingleNode("Elements");
foreach (XmlNode childNode in node.ChildNodes)
node.RemoveChild(childNode);
string nodeXPath = "your x path";
XmlDocument document = new XmlDocument();
document.Load(/*your file path*/);
XmlNode node = document.SelectSingleNode(nodeXPath);
node.RemoveAll();
XmlNode parentnode = node.ParentNode;
parentnode.RemoveChild(node);
document.Save("File Path");
You can use XmlDocument:
string nodeXPath = "your x path";
XmlDocument document = new XmlDocument();
document.Load(/*your file path*/);//or document.LoadXml(...
XmlNode node = document.SelectSingleNode(nodeXPath);
if (node.HasChildNodes)
{
//note that you can use node.RemoveAll(); it will remove all child nodes, but it will also remove all node' attributes.
for (int childNodeIndex = 0; childNodeIndex < node.ChildNodes.Count; childNodeIndex++)
{
node.RemoveChild(node.ChildNodes[childNodeIndex]);
}
}
document.Save("your file path"));
I have a bit of xml file named Sample.xml which is shown below
<?xml version="1.0" encoding="ISO-8859-1"?>
<countries>
<country>
<text>Norway</text>
<value>N</value>
</country>
<country>
<text>Sweden</text>
<value>S</value>
</country>
<country>
<text>France</text>
<value>F</value>
</country>
<country>
<text>Italy</text>
<value>I</value>
</country>
</countries>
i have button named submit(button1).If i click that button i need to display the count(PartitionName="AIX") in a text box named textBox1, means How many PartitionName="AIX" is belonging to Type="NIC"
Can any one give me the c# code
I did like this,,but not able to get the answaer
private void button1_Click(object sender, EventArgs e)
{
XmlDocument doc1 = new XmlDocument();
doc1.Load(#"D:\New Folder\WindowsFormsApplication3\WindowsFormsApplication3\Sample.xml");
XmlNodeList a = doc1.GetElementsByTagName("AIX");
textBox1.Text = a.Count.ToString();
}
here is a quick soln I arrived at using linq. hope you find it useful.
static void Main(string[] args)
{
XElement xElement = XElement.Load(#"C:\Labs\test.xml");
// PartitionName="AIX" is belonging to Type="NIC"
var count = xElement.Descendants().Where(x => x.Name.ToString().Contains("Port")) // namespaces might be used here for faster traversal..
.Where(x => x.HasAttributes && x.Attribute("Type").Value == "NIC")
.Descendants().Where(x => x.Name.ToString().Contains("Client"))
.Where(x => x.Attribute("PartitionName").Value == "AIX").Count();
string str = count.ToString();
Console.WriteLine("Count = {0}", str);
Console.ReadLine();
}
Using xpath something like this:
count(vendor/Slot/Port[#Type='NIC']/Client[#PartitionName='AIX'])
But you have to modify it to support your namespaces.
Also easier and shorter code than going the Linq route for this particular case.
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
XmlNamespaceManager nsMgr = new XmlNamespaceManager(doc.NameTable);
nsMgr.AddNamespace("inv", "http://secon.com/Ultravendor");
int count = doc.SelectNodes("inv:vendor/inv:Slot/inv:Port[#Type='NIC']/inv:Client[#PartitionName='AIX']", nsMgr).Count;
XmlDocument doc1 = new XmlDocument();
doc1.Load(#"C:\Labs\test.xml");
XmlNodeList nodes = doc1.GetElementsByTagName("inv:Port");
int count = 0;
foreach (XmlNode childNode in nodes)
{
XmlNodeReader nodeReader = new XmlNodeReader(childNode);
while (nodeReader.Read())
{
if (nodeReader.GetAttribute("PartitionName") == "AIX")
{
count++;
}
}
}
Console.WriteLine("Count = {0}", count);
Console.ReadLine();