How to Read XML in .NET?
Load the XML into an XmlDocument
and then use xpath queries to extract the data you need.
For example
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlstring);
XmlNode errorNode = doc.DocumentElement.SelectSingleNode("/DataChunk/ResponseChunk/Errors/error");
string errorCode = errorNode.Attributes["code"].Value;
string errorMessage = errorNode.InnerText;
If there is potential for the XML having multiple error elements you can use SelectNodes
to get an XmlNodeList
that contains all elements at that xpath. For example:
XmlDocument doc = new XmlDocument();
doc.LoadXml(xmlstring);
XmlNodeList errorNodes = doc.DocumentElement.SelectNodes("/DataChunk/ResponseChunk/Errors/error");
foreach(XmlNode errorNode in errorNodes)
{
string errorCode = errorNode.Attributes["code"].Value;
string errorMessage = errorNode.InnerText;
}
Option 2
If you have a XML schema for the XML you could bind the schema to a class (using the .NET xsd.exe tool). Once you have that you can deserialise the XML into an object and work with it from that object rather than the raw XML. This is an entire subject in itself so if you do have the schema it is worth looking into.
Reading the XML file in c#
nodeList
is a list of <InvoiceHeader>
nodes. One method to solve this problem would be to iterate through the ChildNodes
of nodeList
and use the property Name
to create the Details
class in each iteration.
Your code was almost there... I've just updated it slightly so it correctly adds the <Number>
elements to the list:
List<Details> detailsList = new List<Details>();
XmlDocument doc = new XmlDocument();
doc.Load(path);
XmlNodeList nodeList = doc.SelectNodes("/Invoice/InvoiceHeader");
foreach (XmlNode node in nodeList)
{
// create details class for each InvoiceHeader
Details detail = new Details();
detail.Number = new List<string>();
// loop over child nodes to get Name and all Number elements
foreach (XmlNode child in node.ChildNodes)
{
// check node name to decide how to handle the values
if (child.Name == "Name")
{
detail.Name = child.InnerText;
}
else if (child.Name == "Number")
{
detail.Number.Add(child.InnerText);
}
}
detailsList.Add(detail);
}
Then you can display the results like this:
foreach (var details in detailsList)
{
Console.WriteLine($"{details.Name}: {string.Join(",", details.Number)}");
}
// output
cust1: 5689
cust1: 5689,5459
cust1: 5689,5645,5879
Another method you could consider is Linq-to-Xml. The below code produces the same output as that above:
XDocument doc = XDocument.Load(path);
var details = doc.Descendants("Invoice")
.Elements()
.Select(node => new Details()
{
Name = node.Element("Name").Value,
Number = node.Elements("Number").Select(child => child.Value).ToList()
})
.ToList();
Read XML from c#
XmlSerializer
is your friend:
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;
public class ExportJobs
{
public List<Job> JobList { get; } = new List<Job>();
}
public class Job
{
[XmlAttribute]
public int Id { get; set; }
public string Comments { get; set; }
public DateTime DueDate { get; set; }
public string FormattedDueDate { get; set; }
public DateTime TargetDueDate{ get; set; }
public int ServiceTypeId { get; set; }
public string ServiceType { get; set; }
public string TenantName { get; set; }
public string Uprn { get; set; }
public string HouseName { get; set; }
}
static class P
{
static void Main()
{
var ser = new XmlSerializer(typeof(ExportJobs));
ExportJobs jobs;
using (var sr = new StringReader(xml))
{
jobs = (ExportJobs) ser.Deserialize(sr);
}
foreach(var job in jobs.JobList)
{
Console.WriteLine($"{job.Id} / {job.Uprn}: {job.DueDate}");
}
}
const string xml = @"<?xml version=""1.0"" encoding=""utf-8""?>
<ExportJobs xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
<JobList>
<Job Id=""555555"">
<Comments></Comments>
<DueDate>2017-11-17</DueDate>
<FormattedDueDate>17-Nov-2017 12:00</FormattedDueDate>
<TargetDueDate>2017-11-17</TargetDueDate>
<ServiceTypeId>3</ServiceTypeId>
<ServiceType>Service</ServiceType>
<TenantName>Miss Ash</TenantName>
<Uprn>testUpr</Uprn>
<HouseName></HouseName>
</Job>
<Job Id=""666666"">
<Comments></Comments>
<DueDate>2018-03-15</DueDate>
<FormattedDueDate>15-Mar-2018 12:00</FormattedDueDate>
<TargetDueDate>2018-03-15</TargetDueDate>
<ServiceTypeId>3</ServiceTypeId>
<ServiceType>Service</ServiceType>
<TenantName>Mr Howard</TenantName>
<Uprn>testUpr2</Uprn>
</Job>
</JobList>
</ExportJobs>";
}
How to read raw xml from request body in aspnet
First, ASP.NET Core does not support XML serialization/deserialization by default. You must explicitly enable that:
services.AddControllersWithViews().AddXmlSerializerFormatters();
Then, to send raw XML format data to API method, the request's content-Type
should be application/xml
, and we will receive the xml content from the request body, so we should use the [FromBody]
attribute, and we should use the XElement
to receive the xml content. Please refer to the following sample:
Create a Values API with the following code:
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
// POST api/<ValuesController>
[HttpPost]
[Route("/xml")]
public string Post([FromBody]XElement xml)
{
return "Hello" + xml.ToString();
}
Then using Postman to call this API:
Besides, you could also according to the XML elements to create model, then using model class to receive the xml content. Check the following sample:
The XML content as below:
<?xml version="1.0" encoding="UTF-8"?>
<UserViewModel>
<Id>1</Id>
<Name>aa</Name>
</UserViewModel>
Create a UserViewModel
public class UserViewModel
{
public int Id { get; set; }
public string Name { get; set; }
}
Then, in the API controller, using the following method to receive data:
[HttpPost]
public string Post([FromBody]UserViewModel user)
{
return "Hello" + user.Name.ToString();
}
Using Postman to check it:
The [FromForm]
attribute will receive the Form data in the request body. Form data as the name suggests is used to send the data that you are wrapping inside the form like the details you enter when you fill a form. These details are sent by writing them as KEY-VALUE pairs where the key is the "name" of the entry you are sending and value is it’s value. More detail information, you could refer this thread.
Since you are using curl to send request, try to use -H
or --header
to set the request header, like this:
$ curl -k -X POST https://localhost:5001/xml -d '<foo>bar</foo>' -i -H "Content-Type: text/xml"
$ curl -k -X POST https://localhost:5001/xml -d '<foo>bar</foo>' -i -H "Content-Type:application/xml"
or
$ curl -k -X POST https://localhost:5001/xml -d '<foo>bar</foo>' -i --header "Content-Type: text/xml"
$ curl -k -X POST https://localhost:5001/xml -d '<foo>bar</foo>' -i --header "Content-Type:application/xml"
How to read XML data dynamically in C#/.net?
Use LINQ to XML.
Example: to retrieve host with (id = 1):
string id = "1"
XDocument doc = XDocument.Load("data.xml");
var accounts = from elements in doc.Elements("HOSTS").Elements("Host")
where elements.Attribute("id").Value = id
select elements.FirstOrDefault();
How to read xml file having different hierarchy in .net
You have a very large file so it is best to use XmlReader. Try this code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication16
{
class Program
{
const string FILENAME = @"c:\temp\test.xml";
enum State
{
GET_SUBNETWORK,
GET_MECONTEXT,
GET_CONTAINERS,
GET_SUBNETWORK_OR_MECONTEXT
}
static void Main(string[] args)
{
XmlReaderSettings settings = new XmlReaderSettings() { IgnoreWhitespace = true };
XmlReader reader = XmlReader.Create(FILENAME, settings);
reader.ReadToFollowing("SubNetwork", "generic.xsd");
Network.network.name = reader.GetAttribute("id");
Network.network.subnetworks = new List<SubNetwork>();
string xnNameSpace = reader.LookupNamespace("xn");
reader.ReadToFollowing("SubNetwork", xnNameSpace);
Sites newSite = null;
SubNetwork subNetWork = null;
Boolean endElement = false;
State state = State.GET_SUBNETWORK;
while (!reader.EOF)
{
switch (state)
{
case State.GET_SUBNETWORK:
if (reader.Name != "xn:SubNetwork")
{
reader.ReadToFollowing("SubNetwork", xnNameSpace);
}
if (!reader.EOF)
{
subNetWork = new SubNetwork();
Network.network.subnetworks.Add(subNetWork);
subNetWork.name = reader.GetAttribute("id");
subNetWork.sites = new List<Sites>();
state = State.GET_MECONTEXT;
}
break;
case State.GET_MECONTEXT :
if (reader.Name != "xn:MeContext")
{
if (reader.NodeType == XmlNodeType.EndElement)
{
endElement = true;
state = State.GET_SUBNETWORK;
}
else
{
endElement = false;
reader.ReadToFollowing("MeContext", xnNameSpace);
}
}
if (!reader.EOF && !endElement)
{
state = State.GET_CONTAINERS;
newSite = new Sites();
subNetWork.sites.Add(newSite);
newSite.sitename = reader.GetAttribute("id");
reader.ReadToFollowing("ManagedElement", xnNameSpace);
reader.ReadToFollowing("VsDataContainer", xnNameSpace);
}
break;
case State.GET_CONTAINERS:
if (!reader.EOF)
{
switch (reader.NodeType)
{
case XmlNodeType.EndElement:
state = State.GET_SUBNETWORK_OR_MECONTEXT;
break;
case XmlNodeType.Text:
string text = reader.ReadContentAsString();
break;
case XmlNodeType.Element:
string elementName = reader.Name;
XElement element = (XElement)XElement.ReadFrom(reader);
if (elementName == "xn:VsDataContainer")
{
XElement vsDataENodeBFunction = element.Descendants().Where(a => a.Name.LocalName == "vsDataENodeBFunction").FirstOrDefault();
if (vsDataENodeBFunction != null)
{
XElement eNBId = element.Descendants().Where(a => a.Name.LocalName == "eNBId").FirstOrDefault();
if (eNBId != null)
{
newSite.eNBId = (int)eNBId;
}
}
List<XElement> vsDataContainers = element.Descendants().Where(a => a.Name.LocalName == "VsDataContainer").ToList();
List<XElement> vsDataEUtranCellFDD = vsDataContainers.Where(x => x.Descendants().Where(a => (a.Name.LocalName == "vsDataType") && ((string)a == "vsDataEUtranCellFDD")).Any()).ToList();
if (vsDataEUtranCellFDD.Any())
{
List<CellName> cells = vsDataEUtranCellFDD.Select(x => new CellName()
{
id = (string)x.Attribute("id"),
earfcndl = (int)x.Descendants().Where(a => a.Name.LocalName == "earfcndl").FirstOrDefault(),
earfcnul = (int)x.Descendants().Where(a => a.Name.LocalName == "earfcnul").FirstOrDefault()
}).ToList();
if (newSite.cellName == null)
{
newSite.cellName = new List<CellName>();
}
newSite.cellName.AddRange(cells);
}
}
break;
default:
Console.WriteLine("Unexpected Results");
string elementText = reader.ReadContentAsString();
Console.ReadLine();
break;
}
}
break;
case State.GET_SUBNETWORK_OR_MECONTEXT :
switch(reader.NodeType)
{
case XmlNodeType.Element :
switch(reader.Name)
{
case "xn:MeContext" :
state = State.GET_MECONTEXT;
break;
case "xn:SubNetwork" :
state = State.GET_SUBNETWORK;
break;
default :
reader.ReadStartElement();
break;
}
break;
case XmlNodeType.Text:
string text = reader.ReadContentAsString();
break;
case XmlNodeType.EndElement:
reader.ReadEndElement();
break;
default:
Console.WriteLine("Unexpected Results");
string elementText = reader.ReadContentAsString();
Console.ReadLine();
break;
}
break;
}
}
}
}
public class Network
{
public static Network network = new Network();
public string name { get; set; }
public List<SubNetwork> subnetworks { get; set; }
}
public class SubNetwork
{
public string name { get; set; }
public List<Sites> sites { get; set; }
}
public class Sites
{
public string sitename { get; set; }
public int eNBId { get; set; }
public List<CellName> cellName { get; set; }
}
public class CellName
{
public string id { get; set; }
public int earfcndl { get; set; }
public int earfcnul { get; set; }
}
}
Related Topics
Oledbparameters and Parameter Names
How to Get Current User, and How to Use User Class in MVC5
"Open/Close" SQLconnection or Keep Open
Parallel.Foreach Slower Than Foreach
How to Stop Backgroundworker Correctly
How to Check If a String Exists in Another String
List<T> VS Bindinglist<T> Advantages/Disadvantages
Add Items to Columns in a Wpf Listview
Access a Remote Directory from C#
How to Convert List of Arrays into a Multidimensional Array
How to Set Properties on Struct Instances Using Reflection
What's the Difference Between Ienumerable and Array, Ilist and List
Does Parallel.Foreach Limit the Number of Active Threads
Enabling C# 7 in a ASP.NET Application
Format Timespan Greater Than 24 Hour