Deserialize a string - c#

Currently I'm using this code to deserialize a file
StreamReader str = new StreamReader(reply);
System.Xml.Serialization.XmlSerializer xSerializer = new System.Xml.Serialization.XmlSerializer(typeof(imginfo));
imginfo res = (imginfo)xSerializer.Deserialize(str);
How should I modify the code if reply is a string and not a path to an xml file?

Basically, you use an XmlReader chained to a StringReader:
imginfo res;
using(var sr = new StringReader(xml)) // "xml" is our string containing xml
using(var xr = XmlReader.Create(sr)) {
res = (imginfo)xSerializer.Deserialize(xr);
}
//... use "res"
or as Anders notes:
imginfo res;
using(var sr = new StringReader(xml)) // "xml" is our string containing xml
res = (imginfo)xSerializer.Deserialize(sr);
}
//... use "res"

Use StringReader instead of StreamReader. No other change needed.

Related

System.ArgumentNullException for Xamarin.Forms using StreamReader

In public ScenarioPage() of ScenarioPage.cs I have the following code to read from a json file:
var assembly = typeof(ScenarioPage).GetTypeInfo().Assembly;
Stream stream = assembly.GetManifestResourceStream("firstSession.json");
using (StreamReader reader = new StreamReader(stream)) // System.ArgumentNullException
{
var json = reader.ReadToEnd();
List<SessionModel> data = JsonConvert.DeserializeObject<List<SessionModel>>(json);
foreach(SessionModel scenario in data)
{
label.Text = scenario.title;
break;
};
}
I am getting an ArgumentNullException for the stream input. firstSession.json is in the same folder as ScenarioPage.cs, and it is set as an embedded resource. It seems like Visual Studio is not recognizing that my json file is there. Is this is a bug? Or is there something wrong with my code?
Where did you put the Json File, I put it in the Json File in the root Of PCL like following screenshot.
Then use following code to read the Json File.
void GetJsonData()
{
string jsonFileName = "firstSession.json";
ContactList ObjContactList = new ContactList();
var assembly = typeof(MainPage).GetTypeInfo().Assembly;
Stream stream = assembly.GetManifestResourceStream($"{assembly.GetName().Name}.{jsonFileName}");
using (var reader = new System.IO.StreamReader(stream))
{
var jsonString = reader.ReadToEnd();
//Converting JSON Array Objects into generic list
ObjContactList = JsonConvert.DeserializeObject<ContactList>(jsonString);
}
EmployeeView.ItemsSource = ObjContactList.contacts;
}
And here is running GIF.
I update my demo to you. you can test it
https://github.com/851265601/Xamarin.Android_ListviewSelect/blob/master/PlayMusicInBack.zip

Serializing PrinterSettings to string or blob for inserting into a database

Using the below code, I can serialize / deserialize PrinterSettings to a file.
I would like to ask if there's a way to serialize it to a string or byte array or similar instead in order to save it directly into a database.
Thank you!
PrinterSettings prtSettings = new PrinterSettings();
prtSettings.PrintFileName = "does not matter, unused if PrintToFile == false";
//serialise
System.Xml.Serialization.XmlSerializer xmlSerializer = new System.Xml.Serialization.XmlSerializer(prtSettings.GetType());
using (System.IO.TextWriter txtWriter = new StreamWriter(#"c:\temp\printerSettings.xml"))
{
xmlSerializer.Serialize(txtWriter,prtSettings);
}
//deserialise
using (FileStream fileStream = new FileStream(#"c:\temp\printerSettings.xml", FileMode.Open))
{
object obj = xmlSerializer.Deserialize(fileStream);
prtSettings = (PrinterSettings)obj;
}
Instead of a StreamWriter use a StringWriter
string printerSettingText = "";
XmlSerializer xser = new XmlSerializer(typeof(PrinterSettings));
using (StringWriter sw = new StringWriter())
{
xser.Serialize(sw, prtSettings);
printerSettingText = sw.ToString();
}
Deserialization of the object is simple like this
string dataToDeserialize = GetYourDataFromDb();
xser = new XmlSerializer(typeof(PrinterSettings));
using (StringReader sr = new StringReader(dataToDeserialize))
{
PrinterSettings prn = (PrinterSettings)xser.Deserialize(sr);
Console.WriteLine(prn.PrintFileName);
}

Pass xml and xsl as string for processing in xslt 3

I am converting xml to html using xslt 3.0 saxon-HE 9.8 library. Using it in c# code.
I am passing xml and xslt file path in input to get it transformed and get output.
Can anyone please let me know how can I pass xml as string and xslt as string as input in c# code for processing it.
Below is my code.
public static string Transform_XML(string param, string inputfile, string xsltfilename)
{
var xslt = new FileInfo(xsltfilename);
var input = new FileInfo(inputfile);
// Compile stylesheet
var processor = new Processor();
var compiler = processor.NewXsltCompiler();
var executable = compiler.Compile(new Uri(xslt.FullName));
XPathDocument doc = new XPathDocument(new StringReader(param));
DocumentBuilder db = processor.NewDocumentBuilder();
XdmNode xml;
using (XmlReader xr = XmlReader.Create(new StringReader(param)))
{
xml = db.Build(xr);
}
// Do transformation to a destination
var destination = new DomDestination();
using (var inputStream = input.OpenRead())
{
var transformer = executable.Load();
transformer.SetParameter(new QName("", "", "user_entry"), xml);
transformer.SetInputStream(inputStream, new Uri(input.DirectoryName));
transformer.Run(destination);
}
return destination.XmlDocument.InnerXml.ToString();
}
Want to pass xml and xslt as string instead of file path.
UPDATE 1
Got the solution for passing xml and xsl as string in c#. Below is the updated code.
private string Transform_XML(string param, string param_name, string inputfile, string xsltfilename)
{
string xslt_input = System.IO.File.ReadAllText(xsltfilename + ".xslt");
string xml_input = System.IO.File.ReadAllText(inputfile + ".xml");
// Compile stylesheet
var processor = new Processor();
var compiler = processor.NewXsltCompiler();
compiler.BaseUri=new Uri(Server.MapPath("/"));
var executable = compiler.Compile(new XmlTextReader(new StringReader(xslt_input)));
XPathDocument doc = new XPathDocument(new StringReader(param));
DocumentBuilder db = processor.NewDocumentBuilder();
XdmNode xml;
using (XmlReader xr = XmlReader.Create(new StringReader(param)))
{
xml = db.Build(xr);
}
//xml input
DocumentBuilder builder = processor.NewDocumentBuilder();
builder.BaseUri= new Uri(Server.MapPath("/"));
MemoryStream ms = new MemoryStream();
StreamWriter tw = new StreamWriter(ms);
tw.Write(xml_input);
tw.Flush();
Stream instr = new MemoryStream(ms.GetBuffer(), 0, (int)ms.Length);
XdmNode input = builder.Build(instr);
// Do transformation to a destination
var destination = new DomDestination();
var transformer = executable.Load();
//Set the parameter with xml value
transformer.SetParameter(new QName("", "", param_name), xml);
// Set the root node of the source document to be the initial context node
transformer.InitialContextNode = input;
transformer.Run(destination);
// Get result
return destination.XmlDocument.InnerXml.ToString();
}
The XsltTransformer has a method SetInputStream() that allows you to supply the input as a stream (which indeed you appear to be using).
This post How do I generate a stream from a string? tells you how to create a stream from a string.

How to download and open XML file via SFTP?

I need to open XML file (create XmlDocument) without creating local copy. Using SSH.NET, I came up with this code:
var connectionInfo = new ConnectionInfo("host",
"username",
new PasswordAuthenticationMethod("username", "password"));
using (var client = new SftpClient(connectionInfo))
{
client.Connect();
System.IO.MemoryStream mem = new System.IO.MemoryStream();
client.DownloadFile("filename.xml", mem);
mem.Position=0;
using(XmlReader reader = XmlReader.Create(mem))
{
var docc = new XmlDocument();
docc.Load(mem);
}
client.Disconnect();
}
But is gets stuck on docc.Load(mem). What could be the problem?
mem object looks like this:
Note that here:
using(XmlReader reader = XmlReader.Create(mem))
{
var docc = new XmlDocument();
docc.Load(mem);
}
You are not using variable reader at all. Either change to
using(XmlReader reader = XmlReader.Create(mem))
{
var docc = new XmlDocument();
docc.Load(reader);
}
or remove reader at all:
docc.Load(mem);
While the answer by #Evk solves your immediate problem, your code is still inefficient.
Use SftpClient.OpenRead to directly stream the file to XmlReader:
using (XmlReader reader = XmlReader.Create(client.OpenRead("filename.xml"))
{
// process the XML
}
or to XmlDocument:
var docc = new XmlDocument();
docc.Load(client.OpenRead("filename.xml"));
This way, you do not waste a memory by creating another copy of the file in MemoryStream.
It looks like you wrote xml file to stream and now, stream is pointed at the end of xml file. Try setting stream.position to 0 before loading.
stream.Position = 0;
Try this:
using (var client = new SftpClient(connectionInfo))
{
client.Connect();
System.IO.MemoryStream mem = new System.IO.MemoryStream();
client.DownloadFile("filename.xml", mem);
// Set stream position
mem.Position = 0;
using(XmlReader reader = XmlReader.Create(mem))
{
var docc = new XmlDocument();
docc.Load(mem);
}
client.Disconnect();
}
I would also change the code to dispose the memory stream correctly...

Convert xml document to json

My code is as follows.
using (IsolatedStorageFileStream isoStream = new IsolatedStorageFileStream("TestStore1.xml", FileMode.Open, isoStore))
{
using (StreamReader reader = new StreamReader(isoStream))
{
str = reader.ReadToEnd();
XmlDocument doc = new XmlDocument();
doc.LoadXml(str);
string json = JsonConvert.SerializeXmlNode(doc);
}
}
It is giving the error at the line of string json = JsonConvert.SerializeXmlNode(doc);
Error - Newtonsoft.Json.JsonConvert' does not contain a definition for 'SerializeXmlNode'
If you are using dotnet core, install the Newtonsoft.Json package via nuget.

Categories

Resources