During C# deserialization, getting System.InvalidOperationException: < xmlns=''> was not expected - c#

I'm new to XMLdeserialization. I used xsd.exe to generate object classes for performing a deserialization on an existing XML file. When I run my solution below, I get the error
System.InvalidOperationException: < xmlns=''> was not expected
on the s = (NewDataSet)xs.Deserialize(sr) call. I looked this error up on Stack Overflow, and everyone says it's in the XMLRootAttribute line.
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
How can I correct this line? Or where can I find some documentation that explains how to correct it?
Also, why doesn't xsd.exe generate the correct XmlRootAttribute line in the first place? Am I invoking this utility wrong? Or are there some situations the xsd.exe utility can't handle?
public class Program
{
static void Main(string[] args)
{
SortedSet<string> symbolsEstablished = new SortedSet<string>();
GetXmlDataSet("Expt 2buy.xml", ref symbolsEstablished);
}
public static void GetXmlDataSet(string fileName, ref SortedSet<string> symbols)
{
XmlSerializer xs = new XmlSerializer(typeof(NewDataSet));
StreamReader sr = new StreamReader(#"C:\Users\mehl\AppData\Roaming\Fidelity Investments\WealthLabPro\1.0.0.0\Data\DataSets\" + fileName);
NewDataSet s = (NewDataSet)xs.Deserialize(sr);
Console.WriteLine(s.Items[0].DSString);
sr.Close();
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class DataSet
{
private string nameField;
private string scaleField;
private string barIntervalField;
private string dSStringField;
private string providerNameField;
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string Name
{
get { return this.nameField; }
set { this.nameField = value; }
}
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string Scale
{
get { return this.scaleField; }
set { this.scaleField = value; }
}
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string BarInterval
{
get { return this.barIntervalField; }
set { this.barIntervalField = value; }
}
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string DSString
{
get { return this.dSStringField; }
set { this.dSStringField = value; }
}
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string ProviderName
{
get { return this.providerNameField; }
set { this.providerNameField = value; }
}
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class NewDataSet
{
private DataSet[] itemsField;
[System.Xml.Serialization.XmlElementAttribute("DataSet")]
public DataSet[] Items
{
get { return this.itemsField; }
set { this.itemsField = value; }
}
}
}
The entire above code segment is wrapped in a screener2wl namespace.
And here's the XML file I'm trying to deserialize:
<?xml version="1.0"?>
<DataSet xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Name>Expt 2buy</Name>
<Scale>Daily</Scale>
<BarInterval>0</BarInterval>
<DSString>AAL,AFSI,BEN,BIG,BLKB,CDK,COHR,CRUS,EGP,EPE,ETH,FB,HUM,LSTR,MDP,MSI,NYT,TAST,TER,TSO,TXN,UTHR,VASC,VLO,WRI,</DSString>
<ProviderName>FidelityStaticProvider</ProviderName>
</DataSet>

Using xml linq :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
DataSet ds = doc.Descendants("DataSet").Select(x => new DataSet() {
nameField = (string)x.Element("Name"),
scaleField = (string)x.Element("Scale"),
barIntervalField = (string)x.Element("BarInterval"),
dSStringField = (string)x.Element("DSString"),
providerNameField = (string)x.Element("ProviderName")
}).FirstOrDefault();
}
}
public partial class DataSet
{
public string nameField { get; set; }
public string scaleField { get; set; }
public string barIntervalField { get; set; }
public string dSStringField { get; set; }
public string providerNameField { get; set; }
}
}

I got to thinking ... isn't it odd xsd.exe would provide a code generated solution that defines two independent XmlRootAttribute nodes? Can an XML file even have two Root Nodes? Maybe the solutions xsd.exe generates shouldn't be taken too literally. :-)
So after editing its solution, and removing one part with a second XmlRootAttribute defined, I got the solution below, which works.
namespace screener2wl
{
public class Program
{
static void Main(string[] args)
{
SortedSet<string> symbolsEstablished = new SortedSet<string>();
GetXmlDataSet("Expt 2buy.xml", ref symbolsEstablished);
}
public static void GetXmlDataSet(string fileName, ref SortedSet<string> symbols)
{
XmlSerializer xs = new XmlSerializer(typeof(DataSet));
StreamReader sr = new StreamReader(#"C:\Users\mehl\AppData\Roaming\Fidelity Investments\WealthLabPro\1.0.0.0\Data\DataSets\" + fileName);
DataSet s = (DataSet)xs.Deserialize(sr);
Console.WriteLine(s.DSString);
sr.Close();
}
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(IsNullable = false)]
public class DataSet
{
private string nameField;
private string scaleField;
private string barIntervalField;
private string dSStringField;
private string providerNameField;
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string Name
{
get { return this.nameField; }
set { this.nameField = value; }
}
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string Scale
{
get { return this.scaleField; }
set { this.scaleField = value; }
}
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string BarInterval
{
get { return this.barIntervalField; }
set { this.barIntervalField = value; }
}
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string DSString
{
get { return this.dSStringField; }
set { this.dSStringField = value; }
}
[System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string ProviderName
{
get { return this.providerNameField; }
set { this.providerNameField = value; }
}
}
}
}
Bottom line, use the code solutions xsd.exe generates from your XML data file as a guide, not a truth. It's a great tool, but needs to be used with a grain of salt. ... welcome your comments on my XMLdeserialization problem.

Related

How to desalinize an xml and pass it through wcf service in c#

I have an xml as shown below and want to pass it as a response from wcf service.What i did is, i used Visual studio to generate c# classes from xml and then deserilize the xml with the classes generated from VS.Data is coming in Soap UI from WCF service but when i click validate in soap ui, it is throwing error
EDIT on 250320
Finally i reached to single error like
line 17: Invalid xsi:type qname: 'c:string' in element SITE_NAME#http://schemas.datacontract.org/2004/07/ITSM_GIS_NRMIntegration.BusinessObjects
c# code
namespace ITSM_GIS_NRMIntegration
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "Service1" in code, svc and config file together.
// NOTE: In order to launch WCF Test Client for testing this service, please select Service1.svc or Service1.svc.cs at the Solution Explorer and start debugging.
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class GisItsmService : IGisItsmService
{
Datatable dtcustomerSiteDtls = dtcustomerSiteDtls.AsEnumerable()
.OrderBy(x => x.Field<string>("CBCM_PARTY_ID"))
.ThenBy(x => x.Field<string>("CBCM_PARTY_NAME"))
.ThenBy(x => x.Field<string>("SERVICE"))
.ThenBy(x => x.Field<string>("SITENAME"))
.ThenBy(x => x.Field<string>("NODENAME"))
.CopyToDataTable();
XElement allSites = doc.Root;
foreach (var idGroup in dtcustomerSiteDtls.AsEnumerable().GroupBy(x => x.Field<string>("CBCM_PARTY_ID")))
{
XElement siteNode = new XElement("PARTY_SITE_NODES");
allSites.Add(siteNode);
siteNode.Add(new XElement("CBCM_PARTY_ID", idGroup.Key));
siteNode.Add(new XElement("CBCM_PARTY_NAME", idGroup.First().Field<string>("CBCM_PARTY_NAME")));
DataTable dtfilter = dtcustomerSiteDtls.Select("CBCM_PARTY_ID = '" + idGroup.Key.ToString() + "'").CopyToDataTable();
foreach (var service in dtfilter.AsEnumerable().GroupBy(x => x.Field<string>("SERVICE")))
{
XElement partyServices = new XElement("PARTY_SERVICES");
siteNode.Add(partyServices);
partyServices.Add(new XElement("SERVICE_NAME", service.Key));
XElement serviceSites = new XElement("SERVICE_SITES");
partyServices.Add(serviceSites);
foreach (var serviceSite in service.GroupBy(x => x.Field<string>("SITENAME")))
{
serviceSites.Add(new XElement("SITE_NAME", serviceSite.Key));
XElement siteNodes = new XElement("SITE_NODES");
serviceSites.Add(siteNodes);
string[] nodeNames = serviceSite.Select(x => x.Field<string>("NODENAME")).Distinct().ToArray();
foreach (string nodeName in nodeNames)
{
siteNodes.Add(new XElement("NODE_NAME", nodeName));
}
}
}
}
}
}
catch (Exception ex)
{
log.Error(ex.Message);
}
XmlSerializer myItemSerializer = new XmlSerializer(typeof(getCustomerSites));
using (var reader = doc.CreateReader())
{
sitedetailsResObj = (getCustomerSites)myItemSerializer.Deserialize(reader);
}
C# classes used to serialize
namespace ITSM_GIS_NRMIntegration.BusinessObjects
{
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class getCustomerSites:ResponseBase
{
private getCustomerSitesPARTY_SITE_NODES[] pARTY_SITE_NODESField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("PARTY_SITE_NODES")]
public getCustomerSitesPARTY_SITE_NODES[] PARTY_SITE_NODES
{
get
{
return this.pARTY_SITE_NODESField;
}
set
{
this.pARTY_SITE_NODESField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class getCustomerSitesPARTY_SITE_NODES
{
private uint cBCM_PARTY_IDField;
private string cBCM_PARTY_NAMEField;
private getCustomerSitesPARTY_SITE_NODESPARTY_SERVICES[] pARTY_SERVICESField;
/// <remarks/>
public uint CBCM_PARTY_ID
{
get
{
return this.cBCM_PARTY_IDField;
}
set
{
this.cBCM_PARTY_IDField = value;
}
}
/// <remarks/>
public string CBCM_PARTY_NAME
{
get
{
return this.cBCM_PARTY_NAMEField;
}
set
{
this.cBCM_PARTY_NAMEField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("PARTY_SERVICES")]
public getCustomerSitesPARTY_SITE_NODESPARTY_SERVICES[] PARTY_SERVICES
{
get
{
return this.pARTY_SERVICESField;
}
set
{
this.pARTY_SERVICESField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class getCustomerSitesPARTY_SITE_NODESPARTY_SERVICES
{
private string sERVICE_NAMEField;
private getCustomerSitesPARTY_SITE_NODESPARTY_SERVICESSERVICE_SITES sERVICE_SITESField;
/// <remarks/>
public string SERVICE_NAME
{
get
{
return this.sERVICE_NAMEField;
}
set
{
this.sERVICE_NAMEField = value;
}
}
/// <remarks/>
public getCustomerSitesPARTY_SITE_NODESPARTY_SERVICESSERVICE_SITES SERVICE_SITES
{
get
{
return this.sERVICE_SITESField;
}
set
{
this.sERVICE_SITESField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[KnownType(typeof(getCustomerSitesPARTY_SITE_NODESPARTY_SERVICESSERVICE_SITESSITE_NODES))]
public partial class getCustomerSitesPARTY_SITE_NODESPARTY_SERVICESSERVICE_SITES
{
private object[] sITE_NAMEField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("SITE_NAME", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("SITE_NODES", typeof(getCustomerSitesPARTY_SITE_NODESPARTY_SERVICESSERVICE_SITESSITE_NODES))]
public object[] SITE_NAME
{
get
{
return this.sITE_NAMEField;
}
set
{
this.sITE_NAMEField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class getCustomerSitesPARTY_SITE_NODESPARTY_SERVICESSERVICE_SITESSITE_NODES
{
private string[] nODE_NAMEField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("NODE_NAME")]
public string[] NODE_NAME
{
get
{
return this.nODE_NAMEField;
}
set
{
this.nODE_NAMEField = value;
}
}
}
Error in SOAP UI is as shown below
An
Why aren't you using two properties instead of one?
public partial class getCustomerSitesPARTY_SITE_NODESPARTY_SERVICESSERVICE_SITES
{
private object[] itemNamesField;
private object[] itemNodessField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("SITE_NAME", typeof(string))]
public object[] ItemNames
{
get
{
return this.itemNamesField;
}
set
{
this.itemNamesField = value;
}
}
[System.Xml.Serialization.XmlElementAttribute("SITE_NODES", typeof(getCustomerSitesPARTY_SITE_NODESPARTY_SERVICESSERVICE_SITESSITE_NODES))]
public object[] ItemNodes
{
get
{
return this.itemNodesField;
}
set
{
this.itemNodesField = value;
}
}
}
Below is the code to deserialize the xml. Linq is much faster to deserialize than the code below. So you have to decide if it is better to use your code or the code below. Usually I recommend if you have a schema (and the classes) and trying to get all the data it is better to use serialization. You are putting results into a datatable which I then recommend xml linq. I just want to so why I suggested to remove the base class.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XmlReader reader = XmlReader.Create(FILENAME);
XmlSerializer serializer = new XmlSerializer(typeof(getCustomerSites));
getCustomerSites sites = (getCustomerSites)serializer.Deserialize(reader);
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class getCustomerSites //: ResponseBase
{
private getCustomerSitesPARTY_SITE_NODES[] pARTY_SITE_NODESField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("PARTY_SITE_NODES")]
public getCustomerSitesPARTY_SITE_NODES[] PARTY_SITE_NODES
{
get
{
return this.pARTY_SITE_NODESField;
}
set
{
this.pARTY_SITE_NODESField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class getCustomerSitesPARTY_SITE_NODES
{
private uint cBCM_PARTY_IDField;
private string cBCM_PARTY_NAMEField;
private getCustomerSitesPARTY_SITE_NODESPARTY_SERVICES[] pARTY_SERVICESField;
/// <remarks/>
public uint CBCM_PARTY_ID
{
get
{
return this.cBCM_PARTY_IDField;
}
set
{
this.cBCM_PARTY_IDField = value;
}
}
/// <remarks/>
public string CBCM_PARTY_NAME
{
get
{
return this.cBCM_PARTY_NAMEField;
}
set
{
this.cBCM_PARTY_NAMEField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("PARTY_SERVICES")]
public getCustomerSitesPARTY_SITE_NODESPARTY_SERVICES[] PARTY_SERVICES
{
get
{
return this.pARTY_SERVICESField;
}
set
{
this.pARTY_SERVICESField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class getCustomerSitesPARTY_SITE_NODESPARTY_SERVICES
{
private string sERVICE_NAMEField;
private getCustomerSitesPARTY_SITE_NODESPARTY_SERVICESSERVICE_SITES sERVICE_SITESField;
/// <remarks/>
public string SERVICE_NAME
{
get
{
return this.sERVICE_NAMEField;
}
set
{
this.sERVICE_NAMEField = value;
}
}
/// <remarks/>
public getCustomerSitesPARTY_SITE_NODESPARTY_SERVICESSERVICE_SITES SERVICE_SITES
{
get
{
return this.sERVICE_SITESField;
}
set
{
this.sERVICE_SITESField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
//[KnownType(typeof(getCustomerSitesPARTY_SITE_NODESPARTY_SERVICESSERVICE_SITESSITE_NODES))]
public partial class getCustomerSitesPARTY_SITE_NODESPARTY_SERVICESSERVICE_SITES
{
private object[] itemsField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("SITE_NAME", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("SITE_NODES", typeof(getCustomerSitesPARTY_SITE_NODESPARTY_SERVICESSERVICE_SITESSITE_NODES))]
public object[] Items
{
get
{
return this.itemsField;
}
set
{
this.itemsField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class getCustomerSitesPARTY_SITE_NODESPARTY_SERVICESSERVICE_SITESSITE_NODES
{
private string[] nODE_NAMEField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("NODE_NAME")]
public string[] NODE_NAME
{
get
{
return this.nODE_NAMEField;
}
set
{
this.nODE_NAMEField = value;
}
}
}
}

How to deserialize XML document with inner tags and inner elements?

This is my XML file.
<getMetadata>
<Project Name="Doors_Demo">
<Module FullPath="/Doors_Demo/Test_Module2">
<Attributes>
<Attribute name="TableType" type="TableType" />
<Attribute name="TableTopBorder" type="TableEdgeType" />
</Attributes>
</Module>
</Project>
</getMetadata>
I want to deserialize the above XML
Below is my code:
[XmlRoot("getMetadata")]
public class RootClass
{
public Project element_Project;
[XmlElement("Project")]
public Project Project
{
get { return element_Project; }
set { element_Project = value; }
}
}
public class Project
{
public string name;
[XmlAttribute("Name")]
public string Id
{
get { return name; }
set { name = value; }
}
}
public static void Main(string[] args)
{
RootClass obj = new RootClass();
XmlSerializer serializer = new XmlSerializer(typeof(RootClass));
using (FileStream stream = new FileStream(#"E:\getMetadata(4).xml", FileMode.Open))
{
RootClass myxml = (RootClass)serializer.Deserialize(stream);
Console.WriteLine(myxml.Project.name);
}
}
I want to deserialize my XML into a list, I am not able to access all inner elements and attributes inside the root element.
I want details of module element and its inner elements and tags into list which can be accessed.
Here is a little trick to generate classes from your XML automatically.
First, create a new empty class, name it for example TempXml.
Copy your XML to the clipboard and open the new empty class you just created.
Go to Visual Studio Edit menu then Paste Special and Paste XML as Classes:
This will generate the following code:
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class getMetadata
{
private getMetadataProject projectField;
/// <remarks/>
public getMetadataProject Project
{
get
{
return this.projectField;
}
set
{
this.projectField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class getMetadataProject
{
private getMetadataProjectModule moduleField;
private string nameField;
/// <remarks/>
public getMetadataProjectModule Module
{
get
{
return this.moduleField;
}
set
{
this.moduleField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string Name
{
get
{
return this.nameField;
}
set
{
this.nameField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class getMetadataProjectModule
{
private getMetadataProjectModuleAttribute[] attributesField;
private string fullPathField;
/// <remarks/>
[System.Xml.Serialization.XmlArrayItemAttribute("Attribute", IsNullable = false)]
public getMetadataProjectModuleAttribute[] Attributes
{
get
{
return this.attributesField;
}
set
{
this.attributesField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string FullPath
{
get
{
return this.fullPathField;
}
set
{
this.fullPathField = value;
}
}
}
/// <remarks/>
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class getMetadataProjectModuleAttribute
{
private string nameField;
private string typeField;
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string name
{
get
{
return this.nameField;
}
set
{
this.nameField = value;
}
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string type
{
get
{
return this.typeField;
}
set
{
this.typeField = value;
}
}
}
Which should work fine with the XmlSerializer class.
You can clean up a little bit the generated output by removing the empty remarks, changing the name of the classes to use camel case (in this case you need to specify the real element name in the attribute as you were doing in your question) or move the classes to different files.
Hope it helps.

Xml Deserialize exception

I'm trying simply to deserialize a xml file into a class.
This is my xml file:
<DirectoryListener inputDirectory="C:\test\"
outputDirectory="C:\keyValueXml\"
fileExt=".xml"/>
And this is my class (generated by "Paste Special"):
public class DirectoryListenConfig
{
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class DirectoryListener
{
private string inputDirectoryField;
private string outputDirectoryField;
private string fileExtField;
[System.Xml.Serialization.XmlAttributeAttribute()]
public string inputDirectory
{
get
{
return this.inputDirectoryField;
}
set
{
this.inputDirectoryField = value;
}
}
[System.Xml.Serialization.XmlAttributeAttribute()]
public string outputDirectory
{
get
{
return this.outputDirectoryField;
}
set
{
this.outputDirectoryField = value;
}
}
[System.Xml.Serialization.XmlAttributeAttribute()]
public string fileExt
{
get
{
return this.fileExtField;
}
set
{
this.fileExtField = value;
}
}
}
}
And I tried to deserialize the xml file:
string path = "DirectoryConfig.xml";
XmlSerializer serializer = new XmlSerializer(typeof(DirectoryListener));
StreamReader reader = new StreamReader(path);
directoryConfig = (DirectoryListener)serializer.Deserialize(reader);//Throw an exception
And got an exception
An unhandled exception of type 'System.InvalidOperationException' occurred in System.Xml.dll Additional information: There is an error in XML document (2, 2).).
What is the problem? :\
Thanks!
Try this
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Serialization;
using System.IO;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string path = #"c:\temp\test.xml";
XmlSerializer serializer = new XmlSerializer(typeof(DirectoryListener));
StreamReader reader = new StreamReader(path);
DirectoryListener directoryListener = (DirectoryListener)serializer.Deserialize(reader);//Throw an exception
}
}
[XmlRoot("DirectoryListener")]
public partial class DirectoryListener
{
private string inputDirectoryField;
private string outputDirectoryField;
private string fileExtField;
[XmlAttribute("inputDirectory")]
public string inputDirectory {get; set; }
[XmlAttribute("outputDirectory")]
public string outputDirectory { get; set; }
[XmlAttribute("fileExt")]
public string fileExt { get; set; }
}
}

XmlSerializer doesn't fill in values

I created classes from a DTD (over XSD and xsd.exe) for my C# project, so I could easily deserialize them into a model class in my code.
This is roughly how I do it:
XmlReaderSettings readerSettings = new XmlReaderSettings();
readerSettings.DtdProcessing = DtdProcessing.Parse;
XmlReader reader = XmlReader.Create(tipsfile.FullName, readerSettings);
XmlRootAttribute xRoot = new XmlRootAttribute();
xRoot.ElementName = "Tips";
xRoot.IsNullable = true;
XmlSerializer serializer = new XmlSerializer(typeof(Tips), xRoot);
Tips tips = (Tips)serializer.Deserialize(reader);
reader.Close();
But, upon inspection of tips, I see that it holds no values at all from the original XML file. Also, I tried setting a breakpoint on the set-Body of a property of Tips, and it is never reached, although I know for sure that it has a value in the original XML file.
Why is the file not correctly deserialized into the class? Is something missing in my code?
Edit: Here is the Tips.cs file, which was auto-generated from the XSD
using System.Xml.Serialization;
namespace MyNs.Model
{
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://tempuri.org/caravan_1")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://tempuri.org/caravan_1", IsNullable = false)]
public partial class Tips
{
private Chapter[] chapterField;
[System.Xml.Serialization.XmlElementAttribute("Chapter")]
public Chapter[] Chapter
{
get
{
return this.chapterField;
}
set
{
this.chapterField = value;
}
}
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://tempuri.org/caravan_1")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://tempuri.org/caravan_1", IsNullable = false)]
public partial class Chapter
{
private string headingField;
private CarType[] carTypesField;
private Section[] sectionField;
private string countryField;
private string languageField;
public string Heading
{
get
{
return this.headingField;
}
set
{
this.headingField = value;
}
}
[System.Xml.Serialization.XmlArrayItemAttribute("CarType", IsNullable = false)]
public CarType[] CarTypes
{
get
{
return this.carTypesField;
}
set
{
this.carTypesField = value;
}
}
[System.Xml.Serialization.XmlElementAttribute("Section")]
public Section[] Section
{
get
{
return this.sectionField;
}
set
{
this.sectionField = value;
}
}
[System.Xml.Serialization.XmlAttributeAttribute()]
public string Country
{
get
{
return this.countryField;
}
set
{
this.countryField = value;
}
}
[System.Xml.Serialization.XmlAttributeAttribute()]
public string Language
{
get
{
return this.languageField;
}
set
{
this.languageField = value;
}
}
}
[... and so on ...]
And a sample XML file:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Tips SYSTEM "caravan_1.dtd">
<Tips>
<Chapter Country="dafghagt" Language="de">
<Heading>fgagasgargaergarg</Heading>
<Section id="1">
<Heading>afdhwr6u5taehtaqh5</Heading>
<SubSection id="1">
<Heading>46k46kw6jhadfgadfha</Heading>
<Table>
<Row id="1">
<Heading>sgjsfgjsgfh443q572q356</Heading>
<Items>
<Item car="motor1" id="1">
<BodyText color="red">130*</BodyText>
<Subscript>3</Subscript>
</Item>
</Items>
</Row>
</Table>
</SubSection>
</Section>
</Chapter>
</Tips>
StreamReader sw = new StreamReader(fileName, false);
XmlTextReader xmlw = new XmlTextReader(sw);
XmlSerializer writer = new XmlSerializer(
type,
GetOverrides(),
extraTypes,
null,
null);
object o = writer.Deserialize(xmlw);
As per my comment, get overrides is just a method that contains something similar to your xml root attribute, I can show you this too if necessary
EDIT:
an example of extra types
public Type[] GetTypes()
{
return new Type[] { typeof(Class1), typeof(Class2)};
}
EDIT2: get overrides returns (Note this is untested)
XmlAttributes attribs = new XmlAttributes();
//attribs.XmlRoot - can edit root here (instead of xmlrootattribute)
attribs.XmlElements.Add(myAttribute);
XmlAttributeOverrides myOverride = new XmlAttributeOverrides();
myOverride.Add(typeof(Tips), "Tips", attribs);
return myOverride
Your object may not be identical to the xml model. In that case, you need map the properties of your class to the xml fields. I am giving you a quick example I had in one of my projects which may give you bit more information.
namespace DatabaseModel
{
[Description("Represents the selected nodes in the Coverage pane")]
[Serializable()]
[XmlRootAttribute("XmlCoverage", Namespace = "GISManager", IsNullable = false)]
public class TXmlCoverage : IXmlPolygon
{
[XmlArray(ElementName = "sbets"), XmlArrayItem(ElementName = "sbet")]
public List SbetsSelected { get; set; }
[XmlArray(ElementName = "sdcs"), XmlArrayItem(ElementName = "sdc")]
public List SdcsSelected { get; set; }
[XmlElementAttribute(ElementName = "area")]
public Boolean IsAreaSelected { get; set; }
[XmlElementAttribute(ElementName = "fpath")]
public Boolean IsFlightPathSelected { get; set; }
[XmlElementAttribute(ElementName = "fpoly")]
public Boolean IsFlightPolySelected { get; set; }
[XmlElementAttribute(ElementName = "mpoly")]
public Boolean IsMinePolySelected { get; set; }
[XmlElementAttribute(ElementName = "bldg")]
public Boolean IsBuildingsSelected { get; set; }
[XmlElementAttribute(ElementName = "hgt")]
public Boolean IsHeightSelected { get; set; }
[XmlIgnore()]
public Boolean ArePolygonsSelected { get { return IsMinePolySelected && IsBuildingsSelected && IsHeightSelected; } }
public TXmlCoverage()
{
SbetsSelected = new List<String>();
SdcsSelected = new List<String>();
IsAreaSelected = false;
IsFlightPathSelected = false;
IsFlightPolySelected = false;
}
}
}
So it turns out the problem is namespaces. Because my XML has no root namespace:
<Tips>
but the definition of my Model contained one:
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://tempuri.org/caravan_1", IsNullable = false)]
the Serializer didn't match any elements together. When removing the namespace attribute, it worked fine.
So now, I reworked the complete model and excluded any attributes that were not absolutely necessary (as it turns out, all but one were), so now every Property has just one Attribute: XmlElement and consorts.
using System.Xml.Serialization;
namespace MyNs.Model
{
[XmlRoot("Tips")]
public partial class Tips
{
[XmlElement("Chapter")]
public Chapter[] Chapter { get; set; }
}
[XmlRoot("Chapter")]
public partial class Chapter
{
[XmlElement("Heading")]
public string Heading { get; set; }
[XmlElement("CarType")]
public CarType[] CarTypes { get; set; }
[XmlElement("Section")]
public Section[] Section { get; set; }
[XmlAttribute("Country")]
public string Country { get; set; }
[XmlAttribute("Language")]
public string Language { get; set; }
}
[... and so on ...]
With a simple deserialization it works just fine now:
XmlReaderSettings readerSettings = new XmlReaderSettings { DtdProcessing = DtdProcessing.Parse };
XmlSerializer serializer = new XmlSerializer(typeof(Tips));
using (XmlReader reader = XmlReader.Create(fromXmlFile.FullName, readerSettings))
{
Tips tips = (Tips)serializer.Deserialize(reader);
return tips;
}

DataMember property "Type" cannot be found on the DataSource

I have create the following class for XML deserialization:
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public class ProgrammingConfiguration
{
private uint versionField;
private byte[] eLFImageField;
private PreferenceType[] preferencesField;
private ProgrammingConfigurationProtectFlashAfterProgramming protectFlashAfterProgrammingField;
//XML version
public uint Version
{
get { return this.versionField; }
set { this.versionField = value; }
}
//ELF image
[System.Xml.Serialization.XmlElementAttribute(DataType = "base64Binary")]
public byte[] ELFImage
{
get { return this.eLFImageField; }
set { this.eLFImageField = value; }
}
//Preference
[System.Xml.Serialization.XmlArrayItemAttribute("Preference", IsNullable = false)]
public PreferenceType[] Preferences
{
get { return this.preferencesField; }
set { this.preferencesField = value; }
}
//Protect flash after programming
public ProgrammingConfigurationProtectFlashAfterProgramming ProtectFlashAfterProgramming
{
get { return this.protectFlashAfterProgrammingField; }
set { this.protectFlashAfterProgrammingField = value; }
}
}
//Preference Type
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
public partial class PreferenceType
{
private string tagField;
private PreferenceTypePrecedence precedenceField;
private ValueType valueField;
public string Tag
{
get { return this.tagField; }
set { this.tagField = value; }
}
public PreferenceTypePrecedence Precedence
{
get { return this.precedenceField; }
set { this.precedenceField = value; }
}
public ValueType Value
{
get { return this.valueField; }
set { this.valueField = value; }
}
}
//Precedence Type
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public enum PreferenceTypePrecedence
{
XML,
[System.Xml.Serialization.XmlEnumAttribute("Target,XML")]
TargetXML,
Target,
}
//Value Type
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
public partial class ValueType
{
private string lengthField;
private object itemField;
private ItemChoiceType itemElementNameField;
[System.Xml.Serialization.XmlElementAttribute(DataType = "integer")]
public string Length
{
get { return this.lengthField; }
set { this.lengthField = value; }
}
[System.Xml.Serialization.XmlElementAttribute("AutoIncrement", typeof(ValueTypeAutoIncrement))]
[System.Xml.Serialization.XmlElementAttribute("HexBinary", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("Integer", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("String", typeof(string))]
[System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemElementName")]
public object Item
{
get { return this.itemField; }
set { this.itemField = value; }
}
[System.Xml.Serialization.XmlIgnoreAttribute()]
public ItemChoiceType ItemElementName
{
get { return this.itemElementNameField; }
set { this.itemElementNameField = value; }
}
}
//Autoincrement data
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class ValueTypeAutoIncrement
{
private string minimumField;
private string maximumField;
private ValueTypeAutoIncrementOverflowBehaviour overflowBehaviourField;
public string Minimum
{
get { return this.minimumField; }
set { this.minimumField = value; }
}
public string Maximum
{
get { return this.maximumField; }
set { this.maximumField = value; }
}
public ValueTypeAutoIncrementOverflowBehaviour OverflowBehaviour
{
get { return this.overflowBehaviourField; }
set { this.overflowBehaviourField = value; }
}
}
//Overflow behaviour
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public enum ValueTypeAutoIncrementOverflowBehaviour
{
Wrap,
Exception,
}
//Data type
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(IncludeInSchema = false)]
public enum ItemChoiceType
{
AutoIncrement,
HexBinary,
Integer,
String,
}
//ProtectFlashAfterProgramming
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public enum ProgrammingConfigurationProtectFlashAfterProgramming
{
True,
False,
}
I want to create 2 binding source, one for datagridview and one for textbox. I have tried the following:
ProgrammingConfiguration pc = new ProgrammingConfiguration();
XmlSerializer serializer = new XmlSerializer(typeof(ProgrammingConfiguration));
//Reading the XML document requires a FileStream.
Stream reader = new FileStream(filename, FileMode.Open);
//Call the Deserialize method to restore the object's state.
pc = (ProgrammingConfiguration)serializer.Deserialize(reader);
reader.Close();
bindingsource.DataSource = pc;
bindingsource.DataMember = "Preferences";
bsV.DataSource = bindingsource;
bsV.DataMember = "ItemElementName";
The program failed to run at the line bsV.DataMember = "ItemElementName". Any suggestion please
change:
bindingsource.DataSource = pc;
to:
bindingsource.DataSource = new List { pc };
i dont know why but PropertyManager doesnt like chaining properties, however CurrencyManager does. using an IEnumerable will fool and force the BindingContext create CurrencyManager instead of PropertyManager which is for binding single object. the issue isnt related to BindingSource you could set the DataSource property of the grid to the list and DataMember to the Preferences instead.
you dont have to use BindingSource to bind to the textbox either.
simply use:
textBox.DataBindings.Add(list, "Preferences.ItemElementName");
as for Value.Maximum use on of the:
textBoxMaximum.DataBindings.Add(list, Preferences.Value.Maximum);
textBoxMaximum.DataBindings.Add(bindingSource, Value.Maximum);

Categories