Total C# beginner here working on my first simple task list app from a windows form.
I am trying to import data from an XML file into a listbox, however I keep encountering the problem that instead of the actual data (e.g. "Pick up groceries", "Fix car", "Get better at this!") I keep getting lots of other data such as "
DocumentProperties xmlns="um.schemas-microsoft-come:office:office"
.... etc
I start off by loading the dialog box to select the file (saving as string 'file').
My code is then;
XDocument doc = XDocument.Load(file);
foreach (XElement el in doc.Root.Elements())
{
el.ToString();
var task = el;
listBox1.Items.Add(task);
}
I have tried a few different approaches and no luck reading from my test xml file. Is there something simple I am missing?
Thanks in advance for your help.
Your mistake is that you don't specify the TagName, for your root xml document.
This is an example how to read a XML file :
My XML File :
<?xml version="1.0" encoding="utf-8"?>
<head>
<Config>
<port>80</port>
<thread>5</thread>
<gSave>0</gSave>
<bSave>0</bSave>
</Config>
</head>
And the example how to read that XML:
protected string[] Config()
{
var retStrings = new[] {"","","",""};
var xd = new XmlDocument();
var fs = new FileStream("data/config.xml", FileMode.Open);
xd.Load(fs);
var list = xd.GetElementsByTagName("Config");
for (var i = 0; i < list.Count; i++)
{
retStrings[0] = xd.GetElementsByTagName("port")[i].InnerText;
retStrings[1] = xd.GetElementsByTagName("thread")[i].InnerText;
retStrings[2] = xd.GetElementsByTagName("gSave")[i].InnerText;
retStrings[3] = xd.GetElementsByTagName("bSave")[i].InnerText;
}
fs.Close();
return retStrings;
}
If you could show me your XML file, I would give you a specific example.
Try the below snippet..
DataSet ds = new DataSet();
ds.ReadXml(#"C:\demo.xml");
if (ds.Tables.Count > 0)
{
for (int i = 0; i < ds.Tables[0].Rows.Count; i++)
{
for (int j = 0; j < ds.Tables[0].Columns.Count; j++)
{
listBox1.Items.Add(ds.Tables[0].Rows[i][j].ToString());
}
}
}
Related
I have an XML like this I want to get Return/ReturnHeader not EliminationsConsolidatedReturn/ReturnHeader. I want to traverse the XML by a path like Return/ReturnHeader. I got this function in c#. The issue is when I set the path Return/ReturnHeader is also getting the ReturnHeader of all inside EliminationsConsolidatedReturn,ParentReturn and SubsidiaryReturn. Please help me fix this.
c#
private List<XElement> GetNode(XNamespace nameSpace, string path)
{
var names = path.Split("\\".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
var element = new List<XElement>() { XDocument.Descendants(NameSpace + names[0]).FirstOrDefault() };
for (int i = 1; i < names.Length; i++)
{
var name = names[i];
element = element.Descendants(XName.Get(name, nameSpace.ToString())).ToList();
}
return element;
}
XML
<?xml version="1.0" encoding="utf-8"?>
<Return returnVersion="2014v4.0" xmlns="http://www.irs.gov/efile" xmlns:efile="http://www.irs.gov/efile" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ReturnHeader binaryAttachmentCnt="45" subsidiaryReturnCount="18">
</ReturnHeader>
<EliminationsConsolidatedReturn>
<ReturnHeader>
</ReturnHeader>
</EliminationsConsolidatedReturn>
<ParentReturn>
<ReturnHeader>
</ReturnHeader>
</ParentReturn>
<SubsidiaryReturn>
<ReturnHeader>
</ReturnHeader>
</SubsidiaryReturn>
</Return>
private List<XElement> GetNode(XNamespace nameSpace, string path)
{
var names = path.Split("\\".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
var element = new List<XElement>() { XDocument.Descendants(NameSpace + names[0]).FirstOrDefault() };
for (int i = 1; i < names.Length; i++)
{
var name = names[i];
element = element.Elements().Where(q => q.Name.LocalName == name).ToList();
}
return element;
}
I have to fill a datagridview with 3 specifics XML nodes data from several XML files.
Here it´s an example:
<?xml version='1.0' encoding='iso-8859-1'?>
<retorno>
<mensagem>
<codigo>00001 - Sucesso</codigo>
</mensagem>
<alerta>
</alerta>
<numero_nfse>641</numero_nfse>
<serie_nfse>1</serie_nfse>
<data_nfse>08/09/2020</data_nfse>
<hora_nfse>12:16:10</hora_nfse>
<arquivo_gerador_nfse>688569.xml</arquivo_gerador_nfse>
<cod_verificador_autenticidade>03379569</cod_verificador_autenticidade>
</retorno>
I need these get 3 tags - <numero_nfse>, <data_nfse>, <cod_verificador_autenticidade> - and load them into a datagridview.
However, there are more XML files, with the same tags and I would to load all of them at the same time into a datagridview.
I wrote the code bellow and as you can see, it´s not working.
string[] arquivos = Directory.GetFiles(#"D:\Documentos\retorno");
DataSet retorno = new DataSet();
for (int j = 0; j < arquivos.Length; j++)
{
FileInfo Xmls = new FileInfo(arquivos[j]);
string caminhoXmls = Convert.ToString(Xmls);
XmlDocument retornoXml = new XmlDocument();
retornoXml.Load(caminhoXmls);
XmlNodeList retornoTags = retornoXml.GetElementsByTagName("retorno");
foreach (XmlNode xn in retornoTags)
{
string XmlNumeroNfse = xn["numero_nfse"].InnerText;
string XmlDataNfse = xn["data_nfse"].InnerText;
string XmlHoraNfse = xn["hora_nfse"].InnerText;
string XmlCodigo = xn["cod_verificador_autenticidade"].InnerText;
}
retorno.ReadXml(caminhoXmls);
dgvDadosNota.DataSource = retorno.Tables[j];
}
To clarify: I want one column for each tag. So my datagridview would be with 3 columns and as many rows as there are files in the directory. There´s only one <retorno> in each XML file.
Can anyone help me?
You are loading your multiple XML files into a DataSet with one DataTable for each file, but as explained in How to bind Dataset to DataGridView in windows application you can only bind a single DataTable to a DataGridView.
Since you have only one <retorno> node in each file, it would make sense to load the files into a DataTable with 3 columns - one each for <numero_nfse>, <data_nfse>, and <cod_verificador_autenticidade> - and one row for each file.
The following code does this:
static DataTable CreateDataTableFromRetornoXML(IEnumerable<string> fileNames)
{
var columnNames = new []
{
"numero_nfse",
"data_nfse",
"cod_verificador_autenticidade",
};
var rootName = "retorno";
var table = new DataTable();
foreach (var name in columnNames)
table.Columns.Add(name, typeof(string));
foreach (var fileName in fileNames)
{
var row = table.NewRow();
var root = XElement.Load(fileName);
var retorno = root.DescendantsAndSelf(rootName).Single(); // There should be only one.
foreach (DataColumn column in table.Columns)
{
row[column] = retorno.Element(column.ColumnName)?.Value;
}
table.Rows.Add(row);
}
return table;
}
Note I have switch to the LINQ to XML API which is generally easier to work with than the old XmlDocument API.
Demo fiddle here.
I have a Xamarin (C#) project, where I am trying to loop through some XML, but for some reason my code is not working.
This is what I have now:
DeviceList = new List<DeviceInfo>();
string ResultStatus = "";
string ResultDevice = "";
var result = Encoding.Default.GetString(e.Result);
result = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + result;
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(result);
string xPathStatus = "ed_listdevices";
var nodes = xmlDoc.SelectNodes(xPathStatus);
foreach (XmlNode xNode in nodes) {
ResultStatus = xNode.SelectSingleNode("//status").InnerText;
ResultDevice = xNode.SelectSingleNode("//device").InnerText;
}
if (ResultStatus.ToLower() == "ok") {
XmlDocument deviceDoc = new XmlDocument();
deviceDoc.LoadXml(result);
var deviceNodes = deviceDoc.SelectNodes(xPathStatus + "/device");
//foreach(XmlNode dNode in deviceNodes) {
for (int i = 0; i < deviceNodes.Count; i++) {
DeviceList.Add(new DeviceInfo() {
DeviceID = deviceNodes[i].SelectSingleNode("//id").InnerXml,
DeviceName = deviceNodes[i].SelectSingleNode("//name").InnerXml,
DeviceExtraName = "",
DeviceOnlineStatus = deviceNodes[i].SelectSingleNode("//status").InnerXml,
Location = deviceNodes[i].SelectSingleNode("//address").InnerXml,
Time = deviceNodes[i].SelectSingleNode("//time").InnerXml
});
}
}
When I step though the code I get the "ResultStatus" and "ResultDevice" correctly, and when I get to the
for (int i = 0; i < deviceNodes.Count; i++)
the "deviceNodes" variable have a count of 91, and I can see all the individual xml elements that I am suppose to get from the webservice I am calling.
However, when I loop through deviceNodes[i] I only get values from the very first XML element (yes, the value of "i" does change). In other words, my DeviceList is filled with 91 entries with the same values.
Am I missing something obvious?? What am I doing wrong since this isn't working??
PS: I have also tried using a foreach (XmlNode node in deviceNodes) but the result was the same.
"//" in the selector tells it to search from the root node of the document. If you want to search locally under the "current" node, remove the "//"
I have an xml file which contains an element .
i am storing the content of that xml file as string in csv in one of my projects.i am reading the content of that xml from csv and i want the data of the tag which exists in the content of xml file
I tried like this.
XmlDocument doc = new XmlDocument();
doc.LoadXml(Convert.ToString(dataRow["XML"]));
var temp = doc.GetElementsByTagName("Mail");
but I am not getting the value of Mail into temp.what should i do?
GetElementsByTagName returns XmlNodeList. MSDN Reference
// Display all the book titles.
XmlNodeList elemList = doc.GetElementsByTagName("title");
for (int i=0; i < elemList.Count; i++)
{
Console.WriteLine(elemList[i].InnerXml);
}
Linq solution:
var xDoc = XDocument.Load(dataRow["XML"].ToString());
var mailList = xDoc.Descendants("Mail")
.Select(x => new
{
MailID = x.Element("MailID").Value
})
.ToList();
UPDATE:
XmlDocument doc = new XmlDocument();
doc.LoadXml(Convert.ToString(dataRow["XML"]));
var temp = doc.GetElementsByTagName("Mail");
// loop through all retrieved "Mail" elements
foreach(XmlElement xElem in temp)
{
string sMailText = xElem.InnerText;
}
I want to load an XML file that I make by getting data from my database.
However, if I want to read that data, it says there"s an error on line 1.
Line 1 is strange indeed, because I never asked for "ArrayOfBand". But even when it's there I get all my Bands when i put a break point. It just crashes at the last step. Error HRESULT: 0xC00CE556
XAML on localhost
<ArrayOfBand xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://schemas.datacontract.org/2004/07/WindowsStoreApp.Models">
<Band>
<Description>Noorse DJ</Description>
<Facebook>Avicii</Facebook>
<ID>156</ID>
<Name>Avicii</Name>
<Picture>..\Images\Avicii.jpg</Picture>
<Twitter>#Avicii</Twitter>
</Band>
<Band>
<Description>Heavy Metal</Description>
<Facebook>A7X</Facebook>
<ID>157</ID>
<Name>Avenged Sevenfold</Name>
<Picture>..\Images\A7X.jpg</Picture>
<Twitter>#A7X</Twitter>
</Band>
</ArrayOfBand>
C# xml reader
string m_strFilePath = "http://localhost:17281/api/Band";
XmlDocument myXmlDocument = new XmlDocument();
myXmlDocument.Load(m_strFilePath); //Load NOT LoadXml
XmlNodeList elemList = myXmlDocument.GetElementsByTagName("Band");
for (int i = 0; i < elemList.Count; i++)
{
XAML station = new XAML() {
ID = elemList[i].Attributes["ID"].InnerText,
Name = elemList[i].Attributes["Name"].InnerText
};
list.Add(station);
}
return list;
}
c# for creating the xml file
you can see I'm not asking for an "ArrayOfBand". If i take the file and remove "ArrayOfBand" it works perfectly. Anyone has an idea why it's there?
public static List GetBands()
{
List list = new List();
DbDataReader reader = Database.GetData("SELECT * FROM Band");
while (reader.Read())
{
Band b = new Band();
b.ID = reader["ID"].ToString();
b.Name = reader["Name"].ToString();
b.Picture = reader["Picture"].ToString();
b.Description = reader["Description"].ToString();
b.Twitter = reader["Twitter"].ToString();
b.Facebook = reader["Facebook"].ToString();
list.Add(b);
}
return list;
}
Your xml is badly formed. You need to have a closing </ArrayOfBand> at the end.