I've been messing around with the following code to add each node in an xml fileto a dropdown list but with incorrect results so far.
XmlDocument XmlDoc = new XmlDocument();
XmlDoc.Load(Server.MapPath("~/Upload/" + FileUpload1.FileName));
XmlNodeList question = XmlDoc.GetElementsByTagName("row");
foreach(XmlNode Node in question)
{
string answer = Node["var"].Attributes["name"].InnerText;
string ques = Node["var"].InnerText;
DropDownList1.Items.Add(new ListItem(answer, ques));
}
Here is my xml file
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<root>
<row>
<var name="Name" value="Garcia" />
<var name=" Surname" value=" Jose" />
<var name=" Country" value=" Cuba" />
<var name=" Job" value="Software Developer" />
<var name=" Cabin" value="345A" />
</row>
<row>
<var name="Name" value="Lenon" />
<var name=" Surname" value="Tim" />
<var name=" Country" value="USA" />
<var name=" Job" value="SoftwareDeveloper" />
<var name=" Cabin" value="444" />
</row>
<row>
<var name="Name" value="Rusell" />
<var name=" Surname" value=" Anthony" />
<var name=" Country" value=" UK" />
<var name=" Job" value="Web Designer" />
<var name=" Cabin" value="345" />
</row>
<row>
<var name="Name" value="Wolf" />
<var name=" Surname" value=" Werner" />
<var name=" Country" value=" Germany" />
<var name=" Job" value="Linux IT" />
<var name=" Cabin" value="234 " />
</row>
</root>
What I need to do is just populate a drop down list with the values Name,Surname,Country,Job and Cabin,so the user can select these values to manipulate the data. I realise with the answer tag im accessing the values also I was trying different things from code ive saw.
The results im getting in my dropdown list from this code is
Name
Name
Name
Name
Im adding the first attribute of each node, but what I need to do is add every value from just one node. NOTE: The xml files il be working with will have different values and names etc so hardcoding is not an option.
If anyone could help Id appreciate it, thank you.
XDocument xml = XDocument.Load(Server.MapPath("~/Upload/" + FileUpload1.FileName));
foreach (var el in xml.Document.Descendants().First().Descendants().First().Descendants())
{
DropDownList1.Items.Add(new ListItem(el.Attribute(XName.Get("name")).Value, Value = el.Value));
}
This is something that you should use DataBinding to accomplish. This blog post has a good example of how you would do this for ASP.NET, which would also apply to WinForms. The key function is:
//populates the dropdownlist from xml file
public void PopulateDDLsFromXMLFile()
{
DataSet ds = new DataSet();
ds.ReadXml(MapPath("~/Resources/XMLFile.xml"));
//now define datatext field and datavalue field of dropdownlist
ddlName.DataTextField = "Name";
ddlName.DataValueField = "Name";
...
//now bind the dropdownlist to the dataview
ddlName.DataSource = ds;
ddlName.DataBind();
}
For some more information on databinding, you could read the following: ASP.NET, WinForms, WPF.
I'm not exactly sure what you're doing with the drop down list, but you can use the following code to get to the individual values you want:
XmlDocument XmlDoc = new XmlDocument();
XmlDoc.Load(Server.MapPath("~/Upload/" + FileUpload1.FileName));
string searchpath = "//root//row";
XmlNodeList xmlnodes = XmlDoc.SelectNodes(searchpath);
foreach (XmlNode node in xmlnodes)
{
string name = node.SelectSingleNode("//var[#name='Name']").Attributes["value"].InnerXml;
string surname = node.SelectSingleNode("//var[#name=' Surname']").Attributes["value"].InnerXml;
string Country = node.SelectSingleNode("//var[#name=' Country']").Attributes["value"].InnerXml;
string Job = node.SelectSingleNode("//var[#name=' Job']").Attributes["value"].InnerXml;
string Cabin = node.SelectSingleNode("//var[#name=' Cabin']").Attributes["value"].InnerXml;
}
Are you saying that you want to show Garcia, Lenon,Rusell and Wolf in the ddl? if so, just change your :
Node["var"].Attributes["name"].InnerText;
to
Node["var"].Attributes["value"].Value;
Related
I got a xml File like this and I want to add a /row/var to this file. For example, I want to add name="Test1" value="192.178.123.1" and the xml file will add a /var like <var name="Test1" value="192.178.123.1"/>. How could I do?
<DNS>
<row>
<var name="Viettel" value="192.168.1.1"/>
<var name="Google" value="192.182.11.2" />
<var name="Singapore" value="165.21.83.88" />
<var name="Verizon" value="4.2.2.1" />
<var name="VNPT" value="203.162.4.191" />
<var name="FPT" value="203.113.131.1" />
<var name="OpenDNS" value="210.245.31.130" />
<var name="Cloudflare" value="208.67.222.222" />
<var name="Norton" value="1.1.1.1" />
<var name="Viettel" value="198.153.192.1" />
<var name="Dnsadvantage" value="192.168.1.1" />
<var name="Hi-Teck" value="1156.154.70.1" />
<var name="Viettel" value="209.126.152.184" />
</row>
</DNS>
This is my code currently. But it doesn't work.
XmlDocument xdoc = new XmlDocument();
xdoc.Load(#"E:\Applications\Visual\C#\Forms\Test\XMLFile1.xml");
XmlNode rootNode = xdoc.DocumentElement;
XmlNode serverPathNode = xdoc.CreateElement("Test1");
serverPathNode.InnerText = "192.178.123.1";
rootNode.AppendChild(serverPathNode);
xdoc.Save(#"E:\Applications\Visual\C#\Forms\Test\XMLFile1.xml");
this is what you need to do (comments inside):
XmlDocument xdoc = new XmlDocument();
xdoc.Load(#"E:\Applications\Visual\C#\Forms\Test\XMLFile1.xml");
//find the row node to be able to add to him more "var" nodes
XmlNode rowNode = xdoc.SelectSingleNode("/DNS/row");
//create new "var" node
XmlNode serverPathNode = xdoc.CreateElement("var");
//the details are attributes and not nodes so we add them as attributes to the var node
XmlAttribute xmlAttribute = xdoc.CreateAttribute("name");
xmlAttribute.Value = "Test1";
serverPathNode.Attributes.Append(xmlAttribute);
xmlAttribute = xdoc.CreateAttribute("value");
xmlAttribute.Value = "192.178.123.1";
serverPathNode.Attributes.Append(xmlAttribute);
//add the var node to the row node
rowNode.AppendChild(serverPathNode);
xdoc.Save(#"E:\Applications\Visual\C#\Forms\Test\XMLFile1.xml");
Hi I need to insert some lines into an xml file and save it how I should do it?
the xml file is
<?xml version="1.0" encoding="utf-8"?>
<Dashboard CurrencyCulture="en-US">
<Title Text="Dashboard" />
<DataConnections>
<DataConnection Name="Database1Connection" ProviderKey="Access2007" ConnectionString="XpoProvider=MSAccess;Provider=Microsoft.ACE.OLEDB.12.0;Mode=Share Deny None;data source=D:\Sina\Desktop\Omid\Database1.accdb;Jet OLEDB:Database Password=;">
<Parameters>
<Parameter Name="database" Value="D:\Sina\Desktop\Omid\Database1.accdb" />
<Parameter Name="read only" Value="1" />
<Parameter Name="generateConnectionHelper" Value="false" />
</Parameters>
</DataConnection>
</DataConnections>
<DataSources>
<DataSource Name="Data Source 1">
<DataProvider DataConnection="Database1Connection" SupportSql="true" />
</DataSource>
<DataSource Name="Query 2" />
</DataSources>
and I need to insert these lines
<Selection>
<Table Name="Query2">
<Columns>
<Column Name="PName" />
<Column Name="Prog" />
<Column Name="RDate" />
</Columns>
</Table>
</Selection>
between
<DataProvider DataConnection="Database1Connection" SupportSql="true">
.
.(here)
</DataProvider>
Here is a complete console application that will take the file you provided as input and build a new file with the nodes added.
NOTE: you will clearly have to make the code more dynamic as this is very static. For example, you would build the Column elements with another list and a loop likely.
class Program
{
static void Main(string[] args)
{
var doc = XDocument.Load("XMLFile1.xml");
var selection = new XElement("Selection");
var table = new XElement("Table");
table.Add(new XAttribute("Name", "Query2"));
var columns = new XElement("Columns");
var column = new XElement("Column");
column.Add(new XAttribute("Name", "PName"));
columns.Add(column);
column = new XElement("Column");
column.Add(new XAttribute("Name", "Prog"));
columns.Add(column);
column = new XElement("Column");
column.Add(new XAttribute("Name", "RDate"));
columns.Add(column);
table.Add(columns);
selection.Add(table);
var dataProvider = doc.Root.Descendants("DataProvider").First();
dataProvider.Add(selection);
doc.Save("XMLFile2.xml");
}
}
The output of the new file looks like this:
<DataSources>
<DataSource Name="Data Source 1">
<DataProvider DataConnection="Database1Connection" SupportSql="true">
<Selection>
<Table Name="Query2">
<Columns>
<Column Name="PName" />
<Column Name="Prog" />
<Column Name="RDate" />
</Columns>
</Table>
</Selection>
</DataProvider>
</DataSource>
<DataSource Name="Query 2" />
</DataSources>
Try this,
XmlDocument document = new XmlDocument();
document.Load(filename);
XmlElement childElement = document.CreateElement("child");
XmlNode parentNode = document.SelectSingleNode("root/firstLevel/parent");
parentNode.AppendChild(childElement);
A quick approach would be:
string file = "XMLFile1.xml";
string text = File.ReadAllText(file);
text = text.Replace("<DataProvider DataConnection=\"Database1Connection\" SupportSql=\"true\" />",
"<DataProvider DataConnection=\"Database1Connection\" SupportSql=\"true\">" +
"<Selection>" +
"<Table Name=\"Query2\">" +
"<Columns>" +
" <Column Name=\"PName\" />" +
"<Column Name=\"Prog\" />" +
"<Column Name=\"RDate\" />" +
"</Columns>" +
"</Table>" +
"</Selection>" +
"</DataProvider> ");
File.WriteAllText(file, text);
Assuming having the following xml
<test>
<step>
<var name="name1" />
<var name="name2" />
</step>
<step>
<var name="name3" />
<var name="name4" />
</step>
<step>
<var name="name5" />
<var name="name6" />
</step>
</test>
I m using XmlNodeList, seperated by "step". Is there a way to swap or replace a step directly in the xmlnodelist?
Need to make it like this:
<test>
<step>
<var name="name3" />
<var name="name4" />
</step>
<step>
<var name="name1" />
<var name="name2" />
</step>
<step>
<var name="name5" />
<var name="name6" />
</step>
</test>
You can use XDocument class instead of XMLDocument. This will swap the var nodes name3 with name6.
using System.Linq;
using System.Xml.Linq;
class Test
{
static void Main()
{
XDocument document = XDocument.Load("test.xml");
Swap("name3", "name6", document);
document.Save("test.xml");
}
static void Swap(string nameOne, string nameTwo, XDocument document)
{
var nameOneNode = document.Descendants("var").FirstOrDefault(p => p.Attribute("name").Value == nameOne);
var nameTwoNode = document.Descendants("var").FirstOrDefault(p => p.Attribute("name").Value == nameTwo);
nameOneNode.Attribute("name").Value = nameTwo;
nameTwoNode.Attribute("name").Value = nameOne;
}
}
The order of the nodes in an XML file does not necessarily have to be kept when the XML file is read. For example, if your file looks like this:
<xmlcontent>
<node value="Hello" />
<node value="World" />
</xmlcontent>
The XML read may return the nodes like this:
<xmlcontent>
<node value="World" />
<node value="Hello" />
</xmlcontent>
To apply something like an "order" to XML nodes, you need to add an attribute you can sort by, like
<xmlcontent>
<node index="1" value="Hello" />
<node index="2" value="World" />
</xmlcontent>
In that case, "swapping" two elements would come down to swapping the index values.
Finally managed to do it, here is the code:
XmlDocument xml;
XmlNodeList xmlList;
xml = new XmlDocument();
xml.Load(path);
xmlList = xml.GetElementsByTagName("step");
XmlNode refNode = xmlList[1];
XmlNode newNode = xmlList[0];
xml.DocumentElement.InsertAfter(newNode, refNode);
I try to get some specific values from an xml config. See example below.
<?xml version="1.0" encoding="utf-8"?>
<ExcelConfig>
<ExcelDocument name="Customer" type="flat">
<IdentityColumn>
<Column name="Id" />
</IdentityColumn>
<Validate>
<Column name="Name" mandatory="true" />
<Column name="FirstName" mandatory="true" />
<OrColumns mandatory="true">
<Column name="PostalCode" mandatory="false" />
<Column name="PostalCode2" mandatory="false" />
</OrColumns>
</Validate>
</ExcelDocument>
<ExcelDocument name="Company" type="flat">
<IdentityColumn>
<Column name="Id" />
</IdentityColumn>
<Validate>
<Column name="Name" mandatory="true" />
<Column name="FirstName" mandatory="true" />
<OrColumns mandatory="true">
<Column name="PostalCode" mandatory="false" />
<Column name="PostalCode2" mandatory="false" />
</OrColumns>
</Validate>
</ExcelDocument>
<ExcelDocument name="SomeOtherType" type="block">
<IdentityBlock>
<Column name="Period" col="A" />
<Column name="Period2" col="B" />
</IdentityBlock>
<Validate>
<Column name="Name" mandatory="true" />
<Column name="FirstName" mandatory="true" />
</Validate>
</ExcelDocument>
</ExcelConfig>
I use the following code to get some information from the excel file.
"ValidationConfiguration" is the string with the previous configuration.
//Get Different NodeTypes of Excel documents
List<XPathNavigator> types = XmlHelper.GetNodeTypes(validationConfiguration, "/ExcelConfig/ExcelDocument");
List<XPathNavigator> flatTypes = XmlHelper.GetNodeTypes(validationConfiguration,
"//ExcelConfig/ExcelDocument[#type='flat']");
List<XPathNavigator> blockTypes = XmlHelper.GetNodeTypes(validationConfiguration,
"//ExcelConfig/ExcelDocument[#type='block']");
//First we check if the file is from the flat type and get the IdentityColumns
List<XPathNavigator> identityColumnsNode = XmlHelper.GetNodeTypes(validationConfiguration, "//ExcelConfig/ExcelDocument[#type='flat']/IdentityColumn");
You can find the XmlHelper class below.
public static class XmlHelper
{
public static List<XPathNavigator> GetNodeTypes(string xmlConfiguration,string xPath)
{
XPathDocument doc = new XPathDocument(new StringReader(xmlConfiguration));
XPathNavigator nav = doc.CreateNavigator();
XPathExpression expr = nav.Compile(xPath);
List<XPathNavigator> elements = new List<XPathNavigator>();
foreach (XPathNavigator node in nav.Select(expr))
{
elements.Add(node);
}
return elements;
}
public static List<string> GetIdentityColumnNames(List<XPathNavigator> xPathNavigators)
{
List<string> identityColumns = new List<string>();
foreach (XPathNavigator xPathNavigator in xPathNavigators)
{
foreach (XPathNavigator test in xPathNavigator.Select("//Column"))
{
identityColumns.Add(test.GetAttribute("name", ""));
}
}
return identityColumns;
}
}
Now i want to do the following. I selected the identityColumnsNodes(they contains the IdentityColumn from the exceldocuments that have the flat type).
The i get for al that types the colums. But when i try that, i get all columns back from the whole file. He don't only the items from the node that i use.
foreach (XPathNavigator identityColumNode in identityColumnsNode)
{
List<string> identityColumns = XmlHelper.GetIdentityColumnNames(identityColumnsNode);
}
The second problem/thing i want to do --> the best way to select the right validate node from the specific file. With the identityColumns (that i get back and my list of HeaderRow Cells i know what file it is. But how can i select that validate node?
Or are their better methods to do this stuff?
Hey I was wondering if anyone could help to save the value of my xml doc to a c# variable. It is to help with a larger program feature. The XML layout is:
<row>
<var name="bud" value="45" />
<var name="acc" value="345" />
</row>
<row>
<var name="bud" value="45" />
<var name="acc" value="345" />
</row>
I would like to extract the value of bud and store it as a string in my c# code
thanks for any help guys I appreciate it.
XML has to be valid so added a root element.
XML:
<foo>
<row>
<var name="bud" value="45" />
<var name="acc" value="345" />
</row>
<row>
<var name="bud" value="45" />
<var name="acc" value="345" />
</row>
</foo>
Code:
This will return a List with the values of all variables "var" in your XML named "bud" and finally create a comma separated string with all the values.
string xml = "<foo><row><var name=\"bud\" value=\"45\" /><var name=\"acc\" value=\"345\" /></row><row><var name=\"bud\" value=\"45\" /><var name=\"acc\" value=\"345\" /></row></foo>";
XDocument doc = XDocument.Parse(xml);
var budValues =(from c in doc.Descendants("var")
where c.Attribute("name").Value == "bud"
select c.Attribute("value").Value).ToList();
string myBuddy = string.Join(",", budValues);
Your xml is not valid. It requires a single root node.
Here is simple solution using XPath:
XmlDocument xDoc = new XmlDocument();
xDoc.LoadXml(#"
<dataset><row>
<var name=""bud"" value=""45"" />
<var name=""acc"" value=""345"" />
</row>
<row>
<var name=""bud"" value=""45"" />
<var name=""acc"" value=""345"" />
</row></dataset>");
XmlNode node = xDoc.SelectSingleNode("/dataset/row/var[#name='bud']");
string value = node.Attributes["value"].Value;
This gets only the first of the matches where #name='bud'. Checkout XPath to adjust your result. (it's pretty powerful)