Xml & C# Deserialize Exception Error - c#

I am working on a XNA gaming project and keep receiving the following error:
An unhandled exception of type 'System.InvalidOperationException' occurred in System.Xml.dll
Additional information: There is an error in XML document (2, 2).
This is my Xml code:
<?xml version="1.0" encoding="utf-8" ?>
<SplashScreen>
<Path>\SplashScreen\Game.png</Path>
</SplashScreen>
And this is my C# Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;
namespace WindowsGame3
{
public class Manager<T>
{
public Type Type;
public T Load(string Path)
{
T instance;
using (TextReader reader = new StreamReader(Path))
{
XmlSerializer xml = new XmlSerializer(Type);
instance = (T)xml.Deserialize(reader);
}
return instance;
}
public void save(string Path, object obj)
{
using (TextWriter writer = new StreamWriter(Path))
{
XmlSerializer xml = new XmlSerializer(Type);
xml.Serialize(writer, obj);
}
}
}
}
Here's the code that uses the above Manager class:
public void LoadContent(ContentManager Content)
{
this.Content = new ContentManager(Content.ServiceProvider, "Content");
GameScreenManager = new Manager<GameScreen>();
GameScreenManager.Type = currentScreen.Type;
currentScreen = GameScreenManager.Load("SplashScreen.xml");
currentScreen.LoadContent();
}

Did you check to see if the type T that you are calling the Load method on matches proper casing of the root element name SplashScreen ?

Related

Compiling two embedded XSDs: error "Cannot resolve 'schemaLocation' attribute [duplicate]

This question already has an answer here:
How can I resolve the schemaLocation attribute of an .XSD when all of my .XSD's are stored as resources?
(1 answer)
Closed 7 years ago.
I am trying to compile 2 embedded XSDs into a single XSD file but I am getting the error "cannot resolve 'schemaLocation' attribute". I am unsure how to fix this but am guessing its the namespaces some how.
Schema1.xsd does an xsd:include to Schema2.xsd
Schem1.xsd (embedded resource) (simplified)
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://www.somedomain.co.uk/application" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.somedomain.co.uk/application" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xsd:include schemaLocation="Schema2.xsd"/>
</xsd:schema>
Schema2.xsd (embedded resource) (simplified)
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.somedomain.co.uk/application" targetNamespace="http://www.somedomain.co.uk/application" elementFormDefault="qualified" attributeFormDefault="unqualified" id="someId">
</xsd:schema>
Code
using System;
using System.Reflection;
using System.Xml;
using System.Xml.Schema;
namespace Example
{
class Program
{
public static void Main()
{
XmlSchema schema1 = null;
using (XmlTextReader xtr = new XmlTextReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("Example.Schema1.xsd")))
{
schema1 = XmlSchema.Read(xtr, new ValidationEventHandler(XSDValidationEventHandler));
xtr.Close();
}
XmlSchema schema2 = null;
using (XmlTextReader xtr = new XmlTextReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("Example.Schema2.xsd")))
{
schema2 = XmlSchema.Read(xtr, new ValidationEventHandler(XSDValidationEventHandler));
xtr.Close();
}
XmlSchemaSet schemaSet = new XmlSchemaSet();
schemaSet.ValidationEventHandler += new ValidationEventHandler(XSDValidationEventHandler);
schemaSet.Add(schema1); //error writes out to console here
schemaSet.Add(schema2);
schemaSet.Compile();
XmlSchema compiledSchema = null;
foreach (XmlSchema schema in schemaSet.Schemas())
{
compiledSchema = schema;
}
Console.WriteLine("Finished");
Console.ReadKey();
}
public static void XSDValidationEventHandler(object sender, ValidationEventArgs args)
{
Console.WriteLine(args.Message);
}
}
}
NOTE: I am not allowed to change the XSDs content or change them to not being an embedded resource.
Any questions feel free to ask
Thanks
Kyle
When you're using embedded files, the default XmlTextReader is not able to find referenced files. After creating the XmlTextReader, you must supply it with a XmlResolver that is aware of handling embedded files.
using (XmlTextReader xtr = new XmlTextReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("Example.Schema1.xsd")))
{
xtr.XmlResolver = new EmbeddedResourceResolver();
schema1 = XmlSchema.Read(xtr, new ValidationEventHandler(XSDValidationEventHandler));
xtr.Close();
}
The 'EmbeddedResourceResolver' is not an existing Framework class, but can be created by yourself. You can find a reference implementation below.
using System;
using System.Xml;
using System.Reflection;
using System.IO;
namespace MyApp
{
public class EmbeddedResourceResolver : XmlUrlResolver
{
public override object GetEntity(Uri absoluteUri,
string role, Type ofObjectToReturn)
{
Assembly assembly = Assembly.GetExecutingAssembly();
return assembly.GetManifestResourceStream("the.path.to.your.resource");
}
}
}
Because you're not allowed to change the XML, your implementation depends on where the embedded resources are put in your project structure.
You can find more info on the XmlResolver here
My final code
NOTE: For reference both my embedded XSDs were located at the root of my project
using System;
using System.Reflection;
using System.Xml;
using System.Xml.Schema;
namespace Example
{
public class EmbeddedResourceResolver : XmlUrlResolver
{
public override object GetEntity(Uri absoluteUri, string role, Type ofObjectToReturn)
{
Assembly assembly = Assembly.GetExecutingAssembly();
return assembly.GetManifestResourceStream("Example.Schema2.xsd");
}
}
class Program
{
public static void Main()
{
XmlSchema schema1 = null;
using (XmlTextReader xtr = new XmlTextReader(Assembly.GetExecutingAssembly().GetManifestResourceStream("Example.Schema1.xsd")))
{
schema1 = XmlSchema.Read(xtr, new ValidationEventHandler(XSDValidationEventHandler));
xtr.Close();
}
XmlSchemaSet schemaSet = new XmlSchemaSet();
schemaSet.XmlResolver = new EmbeddedResourceResolver();
schemaSet.ValidationEventHandler += new ValidationEventHandler(XSDValidationEventHandler);
schemaSet.Add(schema1);
schemaSet.Compile();
XmlSchema compiledSchema = null;
foreach (XmlSchema schema in schemaSet.Schemas())
{
compiledSchema = schema;
}
Console.WriteLine("Finished");
Console.ReadKey();
}
public static void XSDValidationEventHandler(object sender, ValidationEventArgs args)
{
Console.WriteLine(args.Message);
}
}
}

De serialize an XML string from a Web API

I am using C# and have a question in relation to de serializing an XML string.
Here is my code to de serialize:
public object XmlDeserializeFromString(string objectData, Type type)
{
var serializer = new XmlSerializer(type);
object result;
using (TextReader reader = new StringReader(objectData))
{
result = serializer.Deserialize(reader);
}
return result;
}
The following XML works with the above function:
<House>
<address>21 My House</address>
<id>1</id>
<owner>Optimation</owner>
</House>
However, the XML from my Web API application does not:
<House xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/MVCwithWebAPIApplication.Models">
<address>21 My House</address>
<id>1</id>
<owner>Optimation</owner>
</House>
How can I get the XmlDeserializeFromString function to work with the XML from my Web API application?
The xml return from web api has a default namespace inside. To deserialize this xml into a memory object (defined by a c# class), XmlSerialize has to know whether the class belongs to that namespace or not. This is specified by the property 'Namespace' in RootAttribute attached to that class. If the namespace in xml matches to the declared namespace in c# class, then the xml is successfully deserialized. Otherwise deserialization fails.
More information about xml namespace please see http://www.w3schools.com/xml/xml_namespaces.asp
below is the demo solution for your reference.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml.Serialization;
namespace ConsoleApplication8 {
class Program {
static void Main(string[] args) {
var s1 = "<House><address>21 My House</address><id>1</id><owner>Optimation</owner></House>";
var s2 = "<House xmlns:i=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"http://schemas.datacontract.org/2004/07/MVCwithWebAPIApplication.Models\"><address>21 My House</address><id>1</id><owner>Optimation</owner></House>";
House house = (House)XmlDeserializeFromString(s2, typeof(House));
Console.WriteLine(house.ToString());
Console.Read();
}
public static Object XmlDeserializeFromString(string objectData, Type type) {
var serializer = new XmlSerializer(type);
object result;
using (TextReader reader = new StringReader(objectData)) {
result = serializer.Deserialize(reader);
}
return result;
}
}
//this is the only change
[XmlRoot(Namespace="http://schemas.datacontract.org/2004/07/MVCwithWebAPIApplication.Models")]
public class House {
public String address { get; set; }
public String id { get; set; }
public String owner { get; set; }
public override string ToString() {
return String.Format("address: {0} id: {1} owner: {2}", address, id, owner);
}
}
}

Getting deserialized values

I have deserialized an xml file which contains a list of programs, days, times and a true or false value against them. The file looks similar to below.
<AlarmSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ProgramSettings>
<ProgramSetting>
<ProgramPathText>Alarm.exe</ProgramPathText>
<ProgramPathValue>D:\Documents\Work\Visual Studio\WindowsFormsApplication1\bin\Debug\Alarm.exe</ProgramPathValue>
<Monday>
<Time>11:08</Time>
<Enabled>true</Enabled>
</Monday>
<Tuesday>
<Time>17:08</Time>
<Enabled>true</Enabled>
</Tuesday>
</ProgramSetting>
</ProgramSettings>
</AlarmSettings>
I am trying to access the values but i keep getting stuck at the end of program settings where i cant see any methods that will be useful. I am needing to get to return the programpathtext values, programpathvalue values etc.
public void load()
{
AlarmSettings alarmSettings;
alarmSettings = AlarmSettings.Load(#"C:\Users\jason\Desktop\Booya.txt");
alarmSettings.ProgramSettings.
}
Any help would be appreciated. Thanks
AlarmSettings Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
using System.IO;
namespace WindowsAlarm
{
public class AlarmSettings
{
public List<ProgramSetting> ProgramSettings = new List<ProgramSetting>();
public void Save(string filename)
{
XmlSerializer serializer = new XmlSerializer(typeof(AlarmSettings));
TextWriter writer = new StreamWriter(filename);
serializer.Serialize(writer, this);
writer.Close();
}
public static AlarmSettings Load(string filename)
{
try
{
XmlSerializer serializer = new XmlSerializer(typeof(AlarmSettings));
using (StreamReader reader = new StreamReader(filename))
{
AlarmSettings loadedSettings = (AlarmSettings)serializer.Deserialize(reader);
reader.Close();
return loadedSettings;
}
}
catch(Exception e)
{
throw e;
//return new AlarmSettings();
}
}
}
}
if you have proper object structure , make use of XmlSerializer
XmlSerializer serializer = new XmlSerializer(typeof(objecttype));
or make use of Linq to XML or create you own XML parser for that you can serach on google
you can also check post which talks about serialization : Object to XML using LINQ or XmlSerializer
I have solved the problem. the problem was that i was not going in and accessing the collection.
public void load()
{
AlarmSettings alarmSettings;
alarmSettings = AlarmSettings.Load(#"C:\Users\jason\Desktop\Booya.txt");
foreach (var setting in alarmSettings.ProgramSettings)
{
string pathtext = setting.ProgramPathText;
string pathvalue = setting.ProgramPathValue;
}
}

Write to Xml File using Asp-C#

I'm trying to store Some values to an xml file.I've already created an Xml file and trying to overwrite data. The code is given..
/*storepassword.cs *//
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
public class StorePassword
{
public StorePassword()
{
}
public void store(NewPassword nps)
{
XmlDocument XmlDoc = new XmlDocument();
//XmlDoc.Load(#"Password.xml");
XmlDoc.LoadXml("Password.xml");
XmlNode root = XmlDoc.DocumentElement;
XmlNode myNode1 = root.SelectSingleNode("UserName");
XmlNode myNode2 = root.SelectSingleNode("PassWord");
myNode1.Value = "sjn";
myNode2.Value = "sjn123";
XmlDoc.Save(#"Password.xml");
}
}
//NewPassword.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
public class NewPassword
{
public NewPassword()
{
}
public string username{ get; set; }
public string Password{ get; set; }
}
on button click..
NewPassword nps = new NewPassword();
nps.username = TxtUser.Text;
nps.Password = TxtNewPassword.Text;
StorePassword sp=new StorePassword();
sp.store(nps);
The existing Xml file contains the following..
<?xml version="1.0" encoding="utf-8"?>
<ROOT>
<UserName>abc</UserName>
<PassWord>123</PassWord>
</ROOT>
But it's not working..
Data at the root level is invalid. Line 1, position 1
this error occures..
Ichanged the code as XmlDoc.Load(#"Password.xml");
now error changed to
Root element is missing.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Xml.XmlException: Root element is missing.
why this happens?
Try using XML Serialization:
public static partial class ObjectXMLSerializer<T> where T : class
{
private static void SaveToDocumentFormat(T serializableObject, System.Type[] extraTypes, string path, IsolatedStorageFile isolatedStorageFolder)
{
using (TextWriter textWriter = CreateTextWriter(isolatedStorageFolder, path))
{
XmlSerializer xmlSerializer = CreateXmlSerializer(extraTypes);
//Cuong: set name space to null
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
xmlSerializer.Serialize(textWriter, serializableObject, ns);
}
}
public static void Save(T serializableObject, string path)
{
SaveToDocumentFormat(serializableObject, null, path, null);
}
}
When you load your Xml you need to use Server.MapPath . XmlDoc.LoadXml(Server.MapPath("Password.xml"));
delete
<?xml version="1.0" encoding="utf-8"?>
from
<?xml version="1.0" encoding="utf-8"?>
<ROOT>
<UserName>abc</UserName>
<PassWord>123</PassWord>
</ROOT>
I do not know why it works but we do that all the time in our code. And yes you should be using XmlDocument.Load not XmlDocument.LoadXml

C# Error with XML Serialization "There is an error in XML document (2, 2)"

All, I am trying to serialize and de-serialize a class and the de-serialization is failing. There are tons of similar threads, but I am unable to resolve this. I am getting the following error "There is an error in XML document (2, 2)" Inner expection "{" was not expected."}"
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
namespace XMLSerialization
{
[System.Xml.Serialization.XmlRootAttribute(Namespace = "",
IsNullable = false)]
public class Level
{
private String _name;
private String _background;
public Level()
{
_name = "LEVEL_NAME";
_background = "LEVEL_BACKGROUND_IMAGE";
}
[XmlAttribute("LevelName")]
public String LevelName
{
get { return _name; }
set { _name = value; }
}
[XmlAttribute("Background")]
public String Background
{
get { return _background; }
set { _background = value; }
}
}
}
This is the code I use for de-serialization. The serialization is happening fine but the de-serialization is not going through. I think that I am doing a trivial mistake but I am unable to solve this!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml.Serialization;
namespace XMLSerialization
{
class Program
{
static void Main(string[] args)
{
Level oLevel1 = new Level();
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", "");
XmlSerializer serializer = new XmlSerializer(typeof(Level));
TextWriter textWriter = new StreamWriter("Level1.xml");
serializer.Serialize(textWriter, oLevel1, ns);
textWriter.Close();
Level oLevel2 = new Level();
XmlSerializer deserializer = new XmlSerializer(typeof(List<Level>));
TextReader textReader = new StreamReader("Level1.xml");
oLevel2 = (Level)deserializer.Deserialize(textReader);
textReader.Close();
}
}
}
I think you need to change the line
XmlSerializer deserializer = new XmlSerializer(typeof(List<Level>));
To
XmlSerializer deserializer = new XmlSerializer(typeof(Level));
You a serializing a Level and are trying to deserizalize a List<Level>.

Categories

Resources