I want to save and load my xml data using XmlReader. But I don't know how to use this class. Can you give me a sample code for start?
MSDN has a simple example to get you started here.
If you're interested in reading and writing XML documents, and not just specifically using the XmlReader class, there's a nice article covering a few of your options here.
But if you just want to get started and play around, try this:
XmlReaderSettings settings = new XmlReaderSettings();
settings.IgnoreWhitespace = true;
settings.IgnoreComments = true;
XmlReader reader = XmlReader.Create("file.xml", settings);
Personally I have switched away from XMLReader to System.XML.Linq.XDocument to manage my XML data files. This way I can easily pull data from xml into objects and manage them like any other object in my program. When I am done manipulating them I can just save the changes back out the the xml file at any time.
//Load my xml document
XDocument myData = XDocument.Load(PhysicalApplicationPath + "/Data.xml");
//Create my new object
HelpItem newitem = new HelpItem();
newitem.Answer = answer;
newitem.Question = question;
newitem.Category = category;
//Find the Parent Node and then add the new item to it.
XElement helpItems = myData.Descendants("HelpItems").First();
helpItems.Add(newitem.XmlHelpItem());
//then save it back out to the file system
myData.Save(PhysicalApplicationPath + "/Data.xml");
If I want to use this data in an easily managed data set I can bind it to a list of my objects.
List<HelpItem> helpitems = (from helpitem in myData.Descendants("HelpItem")
select new HelpItem
{
Category = helpitem.Element("Category").Value,
Question = helpitem.Element("Question").Value,
Answer = helpitem.Element("Answer").Value,
}).ToList<HelpItem>();
Now it can be passed around and manipulated with any inherent functions of my object class.
For convenience my class has a function to create itself as an xml node.
public XElement XmlHelpItem()
{
XElement helpitem = new XElement("HelpItem");
XElement category = new XElement("Category", Category);
XElement question = new XElement("Question", Question);
XElement answer = new XElement("Answer", Answer);
helpitem.Add(category);
helpitem.Add(question);
helpitem.Add(answer);
return helpitem;
}
You should use the Create method instead of using new, since XmlReader is an abstract class using the Factory pattern.
var xmlReader = XmlReader.Create("xmlfile.xml");
From the excellent C# 3.0 in a Nutshell, consider looking at the sample code from chapter 11.
Related
I would like to Read and Deserialize more than one XML file into my XML class structure given a list of strings consisting of file names.
Obviously when reading ONE xml file, you can go like this:
XmlRoot file = null;
XmlSerializer ser = new XmlSerializer(typeof(XmlRoot));
using (XmlReader read = XmlReader.Create(FileName))
{
file = (XmlRoot)ser.Deserialize(read);
{
Which will deserialize the XML file into the class structure?
It is not possible to have a list with file names and use a foreach loop to iterate over them, reading and deserializing one by one as it would theoretically result into multiple root elements being read, deserialized and replicated in the class structure.
So in general I would like to deserialize each file and append the required master elements to a root object.
Does anyone know how to accomplish this? It would be of great help.
Thanks in advance!
PS: Excuse me for my English, as I am not a native speaker. If you need further information, just tell me!
I managed to solve the problem for myself.
First i created a XDocument for the first file i read, afterwards i iterate through the other documents creating a new XDocument for every xml file and try to get the elements after the root (Language in my case) and add it to the root of the XDocument created outside the loop.
XDocument lDoc = new XDocument();
int counter = 0;
foreach (var fileName in multipleFileNames)
{
try
{
counter++;
if (lCounter <= 1)
{
doc = XDocument.Load(fileName);
}
else
{
XDocument doc2 = XDocument.Load(fileName);
IEnumerable<XElement> elements = doc2.Element("Language")
.Elements();
doc.Root.Add(elements);
}
}
return Deserialize(lDoc);
Afterwards i call the Deserialize method, deserializing my created XDocument like this:
public static XmlLanguage Deserialize(XDocument doc)
{
XmlSerializer ser = new XmlSerializer(typeof(XmlLanguage));
return (XmlLanguage)ser.Deserialize(doc.CreateReader());
}
Having trouble dealing with xml and to properly use it for my purpose. So i am creating a test method and one of the parameters is xml data and i am not sure how to pass it in.
Service
public IEnumerable<Submissions> CheckingOutForUserReview(string data)
{
var _submissions = DataContextManager.StoredProcs.CheckingOutForUserReview<SSubmissions>(data, s => new Submissions
{
QRCodeGUID = SubmissionsColumnMap.QRCodeGUID(s),
StoragePath = SubmissionsColumnMap.StoragePath(s),
UploadedByUsersID = SubmissionsColumnMap.UploadedByUsersID(s)
});
return _submissions;
}
Stored Proc:
public virtual IEnumerable<T> CheckingOutForUserReview<T>(string data, Func<IDataRecord, T> modelBinder)
{
SqlCommand _command = new SqlCommand("dbo.CheckingOutForUserReview");
_command.CommandType = CommandType.StoredProcedure;
_command.Parameters.Add(new SqlParameter { ParameterName = "Data", SqlDbType = SqlDbType.Xml, Value = data });
return DbInstance.ExecuteAs<T>(_command, modelBinder);
}
This is my TestMethod:
public void CheckingOutForUserReview()
{
string _data = #"<CheckingOutForUserReview xmlns:i=""www.w3.org/2001/XMLSchema-instance"" xmlns=""schemas.name.com/2013/03/Malt.Models"">
<Record>
<QRCodeID>2FAC636E-F96C-4465-9272-760BAF73C0DF</QRCodeID>
<SubmissionID>10B5236C-47FD-468D-B88D-D789CA0C663A</SubmissionID>
<UserID>1</UserID>
<Page>1</Page>
</Record>
</CheckingOutForUserReview>";
XmlDocument doc = new XmlDocument();
doc.LoadXml(_data);
var _Svc = new SubmissionsService();
var _checkins = _Svc.CheckingOutForUserReview(doc.InnerXml);
}
UPDATE:
my CheckingOutForUserReview() method accepts a XmlDocument as i changed it to that in my stored procedure and with what i currently have it is giving an error that i have invalid arguments(System.Xml.XmlDocument) not sure if i messed up somewhere.
If this is a different way i am also open in trying new ways. Thanks for the help.
As I see there are two ways:
You should save your xml into an xml file by adding xml file in your
project then use it with XmlDocument using Load method like:
XmlDocument doc = new XmlDocument.Load(FileName);
...
...
var _checkins = _Svc.CheckingOutForUserReview(doc.innerXml);
Save your xml as a string literal and use it with XmlDocument using
LoadXml method like:
XmlDocument doc = new XmlDocument.LoadXml(stringThatContainsXml);
...
...
var _checkins = _Svc.CheckingOutForUserReview(doc.innerXml);
You can use XDocument and XElement classes as well but my focus on XmlDocument is that it will work for framework less than 3.5 too since XDocument and XElement is introduced in framework 3.5.
Also loading xml into a parser will help to filter out the invalid xml. (if mistakenly tried to use)
Another thing i have noticed in your snippet:
Assert.IsNotNull(_data);
It should come before the initialization of _Svc, because if there is no data in _data initialization doesn't make sense.
So your code looks like:
public void CheckingOutForUserReview()
{
string _data = "I want to pass in xml here";
Assert.IsNotNull(_data); <--------------- See the re-ordering
var _Svc = new SubmissionsService();
var _checkins = _Svc.CheckingOutForUserReview(_data);
}
Like I said in a comment, I think the best way to do this is to save the XML into a separate file.
If you don't want to do that, you can use verbatim string literal (note the double quotes):
string data = #"<CheckingOutForUserReview xmlns:i=""www.w3.org/2001/XMLSchema-instance"" xmlns=""schemas.name.com/2013/03/Malt.Models"">
<Record>
<QRCodeID>2FAC636E-F96C-4465-9272-760BAF73C0DF</QRCodeID>
<SubmissionID>10B5236C-47FD-468D-B88D-D789CA0C663A</SubmissionID>
<UserID>1</UserID>
<Page>1</Page>
</Record>
</CheckingOutForUserReview>";
I don't see what is the problem in passing any kind of strings as a parameter into a method
If your XML is generated from your code, you better have used a StringBuilder to build it to reduce creating new references while concatenating your string.
If your XML is originally from a file, pass the file path into your method, and open the document there. there are a lot of different ways to open and read XML documents, or loading a string to an XML document and deal with it as XML rather than a string.
Examples:
http://www.codeproject.com/Articles/24375/Working-with-XML
http://forum.codecall.net/topic/58239-c-tutorial-reading-and-writing-xml-files/
and finally from MSDN:
http://msdn.microsoft.com/en-us/library/aa288481%28v=vs.71%29.aspx
enjoy
I have a very simple application. MainUI has the List of CustomClass. I pass this list to WCF service. WCF Service further needs to save these objects in database.
I am using Open XML in our sql stored procedure to get better performnace. But i don't know how to convert my List of Objects to XML.
If i have a datatable, it'll be easy as datatables have methods to get the XML out of them. But how to use for List of objects.
I completly understand that if my List is coming over the WCF, it is getting serialized properly. But what should i exactly need to do.
IMO, look into Controlling XML Serialization with Attributes and the XmlSerializer class and possibly create container classes parallel to your CustomClass. While List<> can't be automatically serialized by the default XML serializer, an array can be.
Thera are two ways: use XmlSerializer or DataContractSerializer.
Code for convert list to xml : List name GridDetails
void ConvertToXml()
{
string xmlString = ConvertObjectToXMLString(GridDetails);
// Save C# class object into Xml file
XElement xElement = XElement.Parse(xmlString);
xElement.Save(#"C:\Users\user\Downloads\userDetail.xml");
}
static string ConvertObjectToXMLString(object classObject)
{
string xmlString = null;
XmlSerializer xmlSerializer = new XmlSerializer(classObject.GetType());
using (MemoryStream memoryStream = new MemoryStream())
{
xmlSerializer.Serialize(memoryStream, classObject);
memoryStream.Position = 0;
xmlString = new StreamReader(memoryStream).ReadToEnd();
}
return xmlString;
}
I have a StringBuilder with the contents of an XML file. Inside the XML file is a root tag called <root> and contains multiple <node> tags.
I'd like to parse through the XML to read values of tags within in s, but not sure how to do it.
Will I have to use some C# XML data type for this?
Thanks in advance
StringBuilder sb = new StringBuilder (xml);
TextReader textReader = new StringReader (sb.ToString ());
XDocument xmlDocument = XDocument.Load (textReader);
var nodeValueList = from node in xmlDocument.Descendants ("node")
select node.Value;
You should use classes available in either System.Xml or System.Xml.Linq to parse XML.
XDocument is part of the LINQ extensions for XML and is particularly easy to use if you need to parse through an arbitrary structure. I would suggest using it rather than XmlDocument (unless you have legacy code or are not on .NET 3.5).
Creating an XDocument from a StringBuilder is straightforward:
var doc = XDocument.Parse( stringBuilder.ToString() );
From here, you can use FirstNode, Descendents(), and the many other properties and methods available to walk and examine the XML structure. And since XDocument is designed to work well with LINQ, you can also write queries like:
var someData = from node in doc.Descendants ("yourNodeType")
select node.Value; // etc..
If you are just looking the specifically named nodes then you don't need to load the document into memory, you can process it yourself with an XmlReader.
using(var sr = new StringReader(stringBuilder.ToString)) {
using(var xr = XmlReader.Create(sr)) {
while(xr.Read()) {
if(xr.IsStartElement() && xr.LocalName == "node")
xr.ReadElementString(); //Do something here
}
}
}
use XDocument.Parse(...)
There are several objects at your disposal for working with XML. Look at the System.Xml namespace for objects such as XmlDocument as well as the XmlReader and XmlWriter families of objects. If using C# 3.0+, look at the System.Xml.Linq namespace and the XDocument class.
If you're looking to read all the values in the XML file , you could look into deserializing the XML into a C# data Object.
Deserializing XML into class obj in C#
Yes, I suggest you use an XmlDocument object to parse the content of your string.
Here is an example who print all inner text contained in your tags:
var doc=new XmlDocument();
doc.LoadXml(stringBuilder.TosTring());
XmlNodeList elemList = doc.GetElementsByTagName("node");
for (int i=0; i < elemList.Count; i++)
{
XmlNode node=elemList[i];
Console.WriteLine(node.InnerText);
}
using Node object members, you can also easily extract all you attributes .
I want to create a XML file in csharp like the below format pls help me with the code
<MasterEntries>
<fruit>Apple</fruit>
<animal>Fox</animal>
<color>Violet</color>
</MasterEntries>
Well, if you have .NET 3.5 available to you, I'd recommend you use LINQ to XML. For example:
XElement master = new XElement("MasterEntries",
new XElement("fruit", "Apple"),
new XElement("animal", "Fox"),
new XElement("color", "Violet"));
That's about as simple as it gets :)
EDIT: Okay, in .NET 2.0 it's a bit more cumbersome. Something like this:
XmlDocument doc = new XmlDocument();
XmlElement root = doc.CreateElement("MasterEntries");
doc.AppendChild(root);
XmlElement fruit = doc.CreateElement("fruit");
fruit.InnerText = "Apple";
root.AppendChild(fruit);
XmlElement animal = doc.CreateElement("animal");
animal.InnerText = "Fox";
root.AppendChild(animal);
XmlElement color = doc.CreateElement("color");
color.InnerText = "Violet";
root.AppendChild(color);
There may well be simpler ways of doing this, but I don't know them...
Once you've got an XElement/XDocument/XmlDocument, you can call Save to save it to a file.