Reading XML to DataSet with multiple tables in file - c#

I'm working on building an XML editor for a personal project. Using WinForms DataGridView control and DataSet, I was able to set up Read/Edit/Save with little issue, using a separate XML file for each type.
However, as I started to try adding more "advanced" controls, it became cumbersome to work with several different files - requiring if statements depending on which file I was working with. So, I tried combining these files into one larger file, as below:
<?xml version="1.0" encoding="utf-8" ?>
<Items>
<Armor>
<Item>
<Name>Test Armor</Name>
<Value>1234567</Value>
<Rarity>Common</Rarity>
<Slot>Chest</Slot>
<Damage>1234567</Damage>
<Defense>1234567</Defense>
<Health>1234567</Health>
<Mana>1234567</Mana>
<Strength>1234567</Strength>
<Dexterity>1234567</Dexterity>
<FlavorText>Something about stuff</FlavorText>
<ImageSource>C:\Items\img.gif</ImageSource>
</Item>
</Armor>
<Consumables>
<Item>
<Name>Test Potion</Name>
<Value>1234567</Value>
<Damage>1234567</Damage>
<Defense>1234567</Defense>
<Health>0.1234567</Health>
<Mana>0.1234567</Mana>
<Strength>1234567</Strength>
<Dexterity>1234567</Dexterity>
<FlavorText>Something about stuff</FlavorText>
<ImageSource>C:\Items\img.gif</ImageSource>
</Item>
</Consumables>
<Junk>
<Item>
<Name>Test Junk</Name>
<Value>1234567</Value>
<Stackable>Yes</Stackable>
<FlavorText>Something about stuff</FlavorText>
<ImageSource>C:\Items\img.gif</ImageSource>
</Item>
</Junk>
<QuestItems>
<Item>
<Name>Test Quest Item</Name>
<Stackable>Yes</Stackable>
<FlavorText>Something about stuff</FlavorText>
<ImageSource>C:\Items\img.gif</ImageSource>
</Item>
</QuestItems>
<Weapons>
<Item>
<Name>Test Weapon</Name>
<Value>1234567</Value>
<Rarity>Common</Rarity>
<Slot>Primary</Slot>
<Damage>1234567</Damage>
<Defense>1234567</Defense>
<Health>1234567</Health>
<Mana>1234567</Mana>
<Strength>1234567</Strength>
<Dexterity>1234567</Dexterity>
<FlavorText>Something about stuff</FlavorText>
<ImageSource>C:\Items\img.gif</ImageSource>
</Item>
</Weapons>
</Items>
And the schema, generated from Visual Studio's Create Schema menu, and minimally modified - such as changing unsignedInt to int:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Items">
<xs:complexType>
<xs:sequence>
<xs:element name="Armor">
<xs:complexType>
<xs:sequence>
<xs:element name="Item" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Name" type="xs:string" />
<xs:element name="Value" type="xs:int" />
<xs:element name="Rarity" type="xs:string" />
<xs:element name="Slot" type="xs:string" />
<xs:element name="Damage" type="xs:int" />
<xs:element name="Defense" type="xs:int" />
<xs:element name="Health" type="xs:int" />
<xs:element name="Mana" type="xs:int" />
<xs:element name="Strength" type="xs:int" />
<xs:element name="Dexterity" type="xs:int" />
<xs:element name="FlavorText" type="xs:string" />
<xs:element name="ImageSource" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Consumables">
<xs:complexType>
<xs:sequence>
<xs:element name="Item" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Name" type="xs:string" />
<xs:element name="Value" type="xs:int" />
<xs:element name="Damage" type="xs:int" />
<xs:element name="Defense" type="xs:int" />
<xs:element name="Health" type="xs:decimal" />
<xs:element name="Mana" type="xs:decimal" />
<xs:element name="Strength" type="xs:int" />
<xs:element name="Dexterity" type="xs:int" />
<xs:element name="FlavorText" type="xs:string" />
<xs:element name="ImageSource" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Junk">
<xs:complexType>
<xs:sequence>
<xs:element name="Item" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Name" type="xs:string" />
<xs:element name="Value" type="xs:int" />
<xs:element name="Stackable" type="xs:string" />
<xs:element name="FlavorText" type="xs:string" />
<xs:element name="ImageSource" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="QuestItems">
<xs:complexType>
<xs:sequence>
<xs:element name="Item" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Name" type="xs:string" />
<xs:element name="Stackable" type="xs:string" />
<xs:element name="FlavorText" type="xs:string" />
<xs:element name="ImageSource" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Weapons">
<xs:complexType>
<xs:sequence>
<xs:element name="Item" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Name" type="xs:string" />
<xs:element name="Value" type="xs:int" />
<xs:element name="Rarity" type="xs:string" />
<xs:element name="Slot" type="xs:string" />
<xs:element name="Damage" type="xs:int" />
<xs:element name="Defense" type="xs:int" />
<xs:element name="Health" type="xs:int" />
<xs:element name="Mana" type="xs:int" />
<xs:element name="Strength" type="xs:int" />
<xs:element name="Dexterity" type="xs:int" />
<xs:element name="FlavorText" type="xs:string" />
<xs:element name="ImageSource" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Both of these files are wholly representative of their counterparts - I had separate files for Armor, Consumables, etc.
The expected outcome was to have one file representing the previously separate files, such that:
Items is the root node.
Within Items are the parent nodes - Armor, Consumables, etc.
Within each parent node are the child nodes Item and their properties.
As far as I can tell, the XML structure and schema looks correct, but when I try to read this file into my program, I receive the error: System.FormatException - "Input string was not in a correct format.".
The stack trace shows that System.Number.StringToNumber is throwing this exception. I've dug through the file and the schema a few times and can't seem to find where this is occuring, and the exception detail doesn't provide much further detail.
In my code, I'm reading the data simply using
DataSet data = new DataSet();
data.ReadXmlSchema(itemSchema);
data.ReadXml(itemData);
This exact method worked without issue when the files/schema were separate, which further leads me to believe I've simply overlooked something in the XML/Schema.
At this point, I'm stuck and not sure what it could be. I would greatly appreciate if anyone can help me solve this issue.

The problem is that you repeat the element Item on each item type.
When your code reads the schema, it finds the first appearance of the Item element and tries to apply the same schema to every other appearance; so, when it reads the Test Potion it tries to read it as string, int, string, string, int, int, int, int, int, int, string, string and fails when it finds the 0.1234567 Health value.
My suggestion would be to change your schema it to something like this:
<?xml version="1.0" encoding="utf-8" ?>
<Items>
<Armor>
<ArmorItem>
...Item elements
</ArmorItem>
</Armor>
<Consumables>
<ConsumableItem>
...Item elements
</ConsumableItem>
</Consumables>
<Junk>
<JunkItem>
...Item elements
</JunkItem>
</Junk>
<QuestItems>
<QuestItem>
...Item elements
</QuestItem>
</QuestItems>
<Weapons>
<WeaponItem>
...Item elements
</WeaponItem>
</Weapons>
</Items>

Related

create index on XML file

I have an XML file
perhaps i usually do more than 100 query every minute with C# and XMLDatareader, that's why i am thinking to add an Index on it, is it possible? or Indexes are allowed only on DB like sqlserver/mysql?
thanks
Here my XML file, with the first record:
<?xml version="1.0" standalone="yes"?>
<NewDataSet>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="Traduzioni">
<xs:complexType>
<xs:sequence>
<xs:element name="Path" type="xs:string" />
<xs:element name="IT" type="xs:string" minOccurs="0" />
<xs:element name="EN" type="xs:string" minOccurs="0" />
<xs:element name="FR" type="xs:string" minOccurs="0" />
<xs:element name="PT" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="extension_ref">
<xs:complexType>
<xs:sequence>
<xs:element name="idKey" type="xs:string" minOccurs="0" />
<xs:element name="Reference" type="xs:string" minOccurs="0" />
<xs:element name="Ordine" type="xs:string" minOccurs="0" />
<xs:element name="Dizione_EN" type="xs:string" minOccurs="0" />
<xs:element name="Dizione_IT" type="xs:string" minOccurs="0" />
<xs:element name="Dizione_PT" type="xs:string" minOccurs="0" />
<xs:element name="Dizione_FR" type="xs:string" minOccurs="0" />
<xs:element name="Dizione_SP" type="xs:string" minOccurs="0" />
<xs:element name="idKey_old" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
<xs:unique name="Constraint1" msdata:PrimaryKey="true">
<xs:selector xpath=".//Traduzioni" />
<xs:field xpath="Path" />
</xs:unique>
</xs:element>
</xs:schema>
<Traduzioni>
<Path>N.Ordine</Path>
<IT>N.Ordine</IT>
<EN>Order number</EN>
<FR>Numéro de commande</FR>
<PT>No de ordem:</PT>
</Traduzioni>
That looks like a translation file of some sort.
You'd be best off loading the XML into memory, e.g. a Dictionary<string, Dictionary<string, string>>, keyed by target language, then by original string. (This is rather trivial to do, so I won't post the code here.)
That way you can then access translations with
translations["EN"]["N.Ordine"]

How to create child node using named types in XML

I have the below xsd schema and I want to add the DG collection inside DGItems. So I want to know how can I achieve that.
When look at my xml at the 2nd section in that manner I want to achieve that. Just a little help needed to fix that.
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="InvoiceData" type="InvoiceData"/>
<xs:complexType name="InvoiceData">
<xs:sequence>
<xs:element name="HeaderFields" type="HeaderFields"/>
<xs:element name="DGItems" type="DGItems"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="HeaderFields">
<xs:sequence>
<xs:element name="CompanyId" type="xs:string" />
<xs:element name="ImageID" type="xs:string" />
<xs:element name="Incident" type="xs:string" />
<xs:element name="FacilityID" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="DGItems">
<xs:sequence>
<xs:element name="DG1" type="xs:string" />
<xs:element name="DG2" type="xs:string" />
<xs:element name="DG3" type="xs:string" />
<xs:element name="DG4" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:schema>
<InvoiceValues>
<HeaderFields>
<CompanyId>StringValue</CompanyId>
<ImageID>StringValue</ImageID>
<Incident>StringValue</Incident>
<FacilityID>StringValue</FacilityID>
</HeaderFields>
<DGItems>
<Dg>
<DG1>StringValue</DG1>
<DG1>StringValue</DG1>
<DG1>StringValue</DG1>
<DG1>StringValue</DG1>
</Dg>
<Dg>
<DG1>StringValue</DG1>
<DG1>StringValue</DG1>
<DG1>StringValue</DG1>
<DG1>StringValue</DG1>
</Dg>
</DGItems>
</InvoiceValues>
Need your help on this.
I have solved the issue on my own, the thing which i have done to fix my issue is are as follows : I have added the Element AI inside the Sequence node & in this way I was managed to fix my issue.
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="EmployeeData" type="EmployeeData"/>
<xs:complexType name="EmployeeData">
<xs:sequence>
<xs:element name="EmployeeHeaderData" type="EmployeeHeaderData"/>
<xs:element name="AddressItems" type="AddressItems"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="EmployeeHeaderData">
<xs:sequence>
<xs:element name="CompanyId" type="xs:string" />
<xs:element name="ImageID" type="xs:string" />
<xs:element name="Incident" type="xs:string" />
<xs:element name="FacilityID" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="AddressItems">
<xs:sequence>
<xs:element name="AI" minOccurs="0" maxOccurs="unbounded" >
<xs:complexType>
<xs:sequence>
<xs:element name="AI1" type="xs:string" />
<xs:element name="AI2" type="xs:string" />
<xs:element name="AI3" type="xs:string" />
<xs:element name="AI4" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:schema>

Why is a DataSet loaded in C# with ReadXml empty?

I am using C# 4.5/Visual Studio 2012 to try to load an XML file to a DataSet. I read the instructions here:
http://msdn.microsoft.com/en-us/library/fx29c3yd.aspx
I am loading an XML file that looks like this:
<?xml version="1.0" encoding="utf-8" ?>
<UnitTestDataSet xmlns="https://rebuildinghomes.codeplex.com/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://rebuildinghomes.codeplex.com/ UnitTestLoadData.xsd">
<Person>
<PersonId>1111</PersonId>
<FirstName>Unit</FirstName>
<LastName>Tester</LastName>
</Person>
</UnitTestDataSet>
With a schema like this:
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema id="RebuildingUnitTestData"
targetNamespace="https://rebuildinghomes.codeplex.com/"
xmlns:u="https://rebuildinghomes.codeplex.com/"
elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:complexType name="PersonType">
<xs:sequence>
<xs:element name="PersonId" type="xs:int"
minOccurs="1" maxOccurs="1" />
<xs:element name="FirstName" type="xs:string"
minOccurs="1" maxOccurs="1" />
<xs:element name="LastName" type="xs:string"
minOccurs="1" maxOccurs="1" />
</xs:sequence>
</xs:complexType>
</xs:schema>
Using the following C# code:
//Load init/expected
DataSet init = new DataSet();
init.ReadXmlSchema("RebuildingModel/Data/UnitTestLoadData.xsd");
init.ReadXml("RebuildingModel/Data/PersonUnitTest.xml", XmlReadMode.ReadSchema);
However, when I look at "init" in the debugger, the DataSet is empty. What am I doing wrong?
Sadly, your snippet of code seem to work on my machine. Are you sure you're checking init AFTER the init.ReadXml() statement executes?
See my output from my Visual Studio immediate window below:
ds.Tables[0]
{Person}
base {System.ComponentModel.MarshalByValueComponent}: {Person}
CaseSensitive: false
ChildRelations: {System.Data.DataRelationCollection.DataTableRelationCollection}
Columns: {System.Data.DataColumnCollection}
Constraints: {System.Data.ConstraintCollection}
DataSet: {System.Data.DataSet}
DefaultView: {System.Data.DataView}
DisplayExpression: ""
ExtendedProperties: Count = 0
HasErrors: false
IsInitialized: true
Locale: {en-US}
MinimumCapacity: 50
Namespace: "https://rebuildinghomes.codeplex.com/"
ParentRelations: {System.Data.DataRelationCollection.DataTableRelationCollection}
Prefix: ""
PrimaryKey: {System.Data.DataColumn[0]}
RemotingFormat: Xml
Rows: {System.Data.DataRowCollection}
Site: null
TableName: "Person"
ds.Tables[0].Rows
{System.Data.DataRowCollection}
base {System.Data.InternalDataCollectionBase}: {System.Data.DataRowCollection}
Count: 1
My DataSet is populated with a single table containing a single row as per your XML.
I finally figured this out.
The schema now looks like this:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="UnitTestDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:msprop="urn:schemas-microsoft-com:xml-msprop">
<xs:annotation>
<xs:appinfo source="urn:schemas-microsoft-com:xml-msdatasource">
<DataSource DefaultConnectionIndex="0" FunctionsComponentName="QueriesTableAdapter" Modifier="AutoLayout, AnsiClass, Class, Public" SchemaSerializationMode="IncludeSchema" xmlns="urn:schemas-microsoft-com:xml-msdatasource">
<Connections />
<Tables />
<Sources />
</DataSource>
</xs:appinfo>
</xs:annotation>
<xs:element name="UnitTestDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true" msprop:Generator_DataSetName="UnitTestDataSet" msprop:Generator_UserDSName="UnitTestDataSet">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="Person" msprop:Generator_TableClassName="PersonDataTable" msprop:Generator_TableVarName="tablePerson" msprop:Generator_TablePropName="Person" msprop:Generator_RowDeletingName="PersonRowDeleting" msprop:Generator_RowChangingName="PersonRowChanging" msprop:Generator_RowEvHandlerName="PersonRowChangeEventHandler" msprop:Generator_RowDeletedName="PersonRowDeleted" msprop:Generator_UserTableName="Person" msprop:Generator_RowChangedName="PersonRowChanged" msprop:Generator_RowEvArgName="PersonRowChangeEvent" msprop:Generator_RowClassName="PersonRow">
<xs:complexType>
<xs:sequence>
<xs:element name="PersonId" msprop:Generator_ColumnVarNameInTable="columnPersonId" msprop:Generator_ColumnPropNameInRow="PersonId" msprop:Generator_ColumnPropNameInTable="PersonIdColumn" msprop:Generator_UserColumnName="PersonId" type="xs:int" />
<xs:element name="FirstName" msprop:Generator_ColumnVarNameInTable="columnFirstName" msprop:Generator_ColumnPropNameInRow="FirstName" msprop:Generator_ColumnPropNameInTable="FirstNameColumn" msprop:Generator_UserColumnName="FirstName" type="xs:string" />
<xs:element name="LastName" msprop:Generator_ColumnVarNameInTable="columnLastName" msprop:Generator_ColumnPropNameInRow="LastName" msprop:Generator_ColumnPropNameInTable="LastNameColumn" msprop:Generator_UserColumnName="LastName" type="xs:string" />
<xs:element name="HomePhoneNbr" msprop:Generator_ColumnVarNameInTable="columnHomePhoneNbr" msprop:Generator_ColumnPropNameInRow="HomePhoneNbr" msprop:Generator_ColumnPropNameInTable="HomePhoneNbrColumn" msprop:Generator_UserColumnName="HomePhoneNbr" type="xs:string" minOccurs="0" />
<xs:element name="CellPhoneNbr" msprop:Generator_ColumnVarNameInTable="columnCellPhoneNbr" msprop:Generator_ColumnPropNameInRow="CellPhoneNbr" msprop:Generator_ColumnPropNameInTable="CellPhoneNbrColumn" msprop:Generator_UserColumnName="CellPhoneNbr" type="xs:string" minOccurs="0" />
<xs:element name="StreetAddress" msprop:Generator_ColumnVarNameInTable="columnStreetAddress" msprop:Generator_ColumnPropNameInRow="StreetAddress" msprop:Generator_ColumnPropNameInTable="StreetAddressColumn" msprop:Generator_UserColumnName="StreetAddress" type="xs:string" minOccurs="0" />
<xs:element name="AptNbr" msprop:Generator_ColumnVarNameInTable="columnAptNbr" msprop:Generator_ColumnPropNameInRow="AptNbr" msprop:Generator_ColumnPropNameInTable="AptNbrColumn" msprop:Generator_UserColumnName="AptNbr" type="xs:string" minOccurs="0" />
<xs:element name="City" msprop:Generator_ColumnVarNameInTable="columnCity" msprop:Generator_ColumnPropNameInRow="City" msprop:Generator_ColumnPropNameInTable="CityColumn" msprop:Generator_UserColumnName="City" type="xs:string" minOccurs="0" />
<xs:element name="County" msprop:Generator_ColumnVarNameInTable="columnCounty" msprop:Generator_ColumnPropNameInRow="County" msprop:Generator_ColumnPropNameInTable="CountyColumn" msprop:Generator_UserColumnName="County" type="xs:string" minOccurs="0" />
<xs:element name="StateProvCd" msprop:Generator_ColumnVarNameInTable="columnStateProvCd" msprop:Generator_ColumnPropNameInRow="StateProvCd" msprop:Generator_ColumnPropNameInTable="StateProvCdColumn" msprop:Generator_UserColumnName="StateProvCd" type="xs:string" minOccurs="0" />
<xs:element name="PostalCode" msprop:Generator_ColumnVarNameInTable="columnPostalCode" msprop:Generator_ColumnPropNameInRow="PostalCode" msprop:Generator_ColumnPropNameInTable="PostalCodeColumn" msprop:Generator_UserColumnName="PostalCode" type="xs:string" minOccurs="0" />
<xs:element name="CountryCode" msprop:Generator_ColumnVarNameInTable="columnCountryCode" msprop:Generator_ColumnPropNameInRow="CountryCode" msprop:Generator_ColumnPropNameInTable="CountryCodeColumn" msprop:Generator_UserColumnName="CountryCode" type="xs:string" minOccurs="0" />
<xs:element name="NumberOfYearsAtAddr" msprop:Generator_ColumnVarNameInTable="columnNumberOfYearsAtAddr" msprop:Generator_ColumnPropNameInRow="NumberOfYearsAtAddr" msprop:Generator_ColumnPropNameInTable="NumberOfYearsAtAddrColumn" msprop:Generator_UserColumnName="NumberOfYearsAtAddr" type="xs:int" minOccurs="0" />
<xs:element name="EmailAddress" msprop:Generator_ColumnVarNameInTable="columnEmailAddress" msprop:Generator_ColumnPropNameInRow="EmailAddress" msprop:Generator_ColumnPropNameInTable="EmailAddressColumn" msprop:Generator_UserColumnName="EmailAddress" type="xs:string" minOccurs="0" />
<xs:element name="GenderCode" msprop:Generator_ColumnVarNameInTable="columnGenderCode" msprop:Generator_ColumnPropNameInRow="GenderCode" msprop:Generator_ColumnPropNameInTable="GenderCodeColumn" msprop:Generator_UserColumnName="GenderCode" type="xs:string" minOccurs="0" />
<xs:element name="EthnicityCode" msprop:Generator_ColumnVarNameInTable="columnEthnicityCode" msprop:Generator_ColumnPropNameInRow="EthnicityCode" msprop:Generator_ColumnPropNameInTable="EthnicityCodeColumn" msprop:Generator_UserColumnName="EthnicityCode" type="xs:int" minOccurs="0" />
<xs:element name="BirthDate" msprop:Generator_ColumnVarNameInTable="columnBirthDate" msprop:Generator_ColumnPropNameInRow="BirthDate" msprop:Generator_ColumnPropNameInTable="BirthDateColumn" msprop:Generator_UserColumnName="BirthDate" type="xs:date" minOccurs="0" />
<xs:element name="ResidentStatus" msprop:Generator_ColumnVarNameInTable="columnResidentStatus" msprop:Generator_ColumnPropNameInRow="ResidentStatus" msprop:Generator_ColumnPropNameInTable="ResidentStatusColumn" msprop:Generator_UserColumnName="ResidentStatus" type="xs:int" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
<xs:unique name="Constraint1" msdata:PrimaryKey="true">
<xs:selector xpath=".//Person" />
<xs:field xpath="PersonId" />
</xs:unique>
</xs:element>
</xs:schema>
The big thing that changed, as you'll notice, is all of the extraneous junk that Visual Studio adds in. Apparently, .NET needs some of this to load the data properly, most notably the primary key annotation. So the moral of the story: if you're going to load a DataSet from XML, create a schema through Visual Studio or be prepared to run it through XSLT to add all this stuff, or the results will be unpredictable, at best.
Could it be the space in the following:
xsi:schemaLocation="https://rebuildinghomes.codeplex.com/ UnitTestLoadData.xsd">
from your xml file?

The same table 'name' cannot be the child table in two nested relations

Several time already asked here and there, some answers relate to old VS versions (this on is using V.S. 2012).
I present the problem again:
given an xsd:
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:complexType name="LocationType">
<xs:attribute name="X" type="xs:integer" />
<xs:attribute name="Y" type="xs:integer" />
</xs:complexType>
<xs:complexType name="AlphaNumericType">
<xs:sequence>
<xs:element name="AlphaNumericLocation" type="LocationType" />
</xs:sequence>
<xs:attribute name="id" type="xs:string" />
<xs:attribute name="key" type="xs:integer" />
</xs:complexType>
<xs:complexType name="BitmapType">
<xs:sequence>
<xs:element name="BitmapLocation" type="LocationType" />
<xs:element name="BitmapCaptions" type="AlphaNumericType" />
</xs:sequence>
<xs:attribute name="key" type="xs:string" />
<xs:attribute name="id" type="xs:string" />
</xs:complexType>
<xs:complexType name="ArcType">
<xs:sequence>
<xs:element name="ArcLocation" type="LocationType" />
<xs:element name="ArcCaptions" type="AlphaNumericType" />
</xs:sequence>
<xs:attribute name="key" type="xs:string" />
<xs:attribute name="id" type="xs:string" />
</xs:complexType>
<xs:element name="BitmapControls">
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="Bitmap" type="BitmapType" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="ArcControls">
<xs:complexType>
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<xs:element name="Arc" type="ArcType" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Notice - that AlphaNumeric has a location element, and both bitmap and arc has AlphaNumeric.
When I create a cs class (using XSD tool) and try to instantiate it I get this error:
The same table 'AlphaNumericLocation' cannot be the child table in two
nested relations.
How can I overcome this issue ?
(the real xsd is more complicated and has a lot more "related similar" children.....
I want to use the xml data in my app in a typed dataset (which easily read and parse the xml).
and I can easily bind tables and columns to other controls... (grid)
Microsoft's XML parser does not support this: I don't think it's changed since early versions of VS.
Check here for some hints on what to do instead: http://social.msdn.microsoft.com/Forums/en-US/22f98352-83b9-4638-a306-34a36a11e4d6/the-same-table-choice-cannot-be-the-child-table-in-two-nested-relations
I have posted a workaround for this problem.
Obviously it may not be a solution for every one,
but at least it explains the source of the problem an points a finger to the offending code.
Serialization Issue when using WriteXML method
Also, you should use 'nesting' in your schema, that will fix the problem.
I have problems adapting your schema, so you'll have to try yourself, but I have adapted one of my own. It's a DataSet with two tables, where MyRootTable has a nested relation with 'PremiumPerYear'.
The key player in this nested relation is the <xs:choice element.
It allows (I believe) the schema to reference another part of itself.
This reference is then created/used by the 'ref' keyword:
<xs:element ref="PremiumPerYear" />
Note: this example does not have an actual 'double nested' relation, but that's just because I cut 90kb of text out.
<DataSet>
<xs:schema id="NewDataSet" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:msprop="urn:schemas-microsoft-com:xml-msprop">
<xs:element name="PremiumPerYear">
<xs:complexType>
<xs:sequence>
<xs:element name="BeforeTaxes" type="xs:decimal" minOccurs="0" />
<xs:element name="AfterTaxes" type="xs:decimal" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="PremiumPerYear" />
<xs:element name="MyRootTable">
<xs:complexType>
<xs:sequence>
<xs:element name="RequestType" msprop:KeyValueCategory="KindOfRequest" type="xs:string" minOccurs="0" />
<xs:element name="RequestDateTime" type="xs:dateTime" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
</DataSet>

Problem deserializing xml file

I auto generated an xsd file from the below xml and used xsd2code to get a c# class. The problem is the entire xml doesn't deserialize.
Here is how I'm attempting to deserialize:
static void Main(string[] args)
{
using (TextReader textReader = new StreamReader("config.xml"))
{
// string temp = textReader.ReadToEnd();
XmlSerializer deserializer = new XmlSerializer(typeof(project));
project p = (project)deserializer.Deserialize(textReader);
}
}
here is the actual XML:
<?xml version='1.0' encoding='UTF-8'?>
<project>
<scm class="hudson.scm.SubversionSCM">
<locations>
<hudson.scm.SubversionSCM_-ModuleLocation>
<remote>https://svn.xxx.com/test/Validation/CPS DRTest DLL/trunk</remote>
</hudson.scm.SubversionSCM_-ModuleLocation>
</locations>
<useUpdate>false</useUpdate>
<browser class="hudson.scm.browsers.FishEyeSVN">
<url>http://fisheye.xxxx.net/browse/Test/</url>
<rootModule>Test</rootModule>
</browser>
<excludedCommitMessages></excludedCommitMessages>
</scm>
<openf>Hello there</openf>
<buildWrappers/>
</project>
When I run the above, the locations node remains null.
Here is the xsd that I'm using:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="project">
<xs:complexType>
<xs:all>
<xs:element name="openf" type="xs:string" minOccurs="0" />
<xs:element name="buildWrappers" type="xs:string" minOccurs="0" />
<xs:element name="scm" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="useUpdate" type="xs:string" minOccurs="0" msdata:Ordinal="1" />
<xs:element name="excludedCommitMessages" type="xs:string" minOccurs="0" msdata:Ordinal="2" />
<xs:element name="locations" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="hudson.scm.SubversionSCM_-ModuleLocation" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="remote" type="xs:string" minOccurs="0" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="browser" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="url" type="xs:string" minOccurs="0" msdata:Ordinal="0" />
<xs:element name="rootModule" type="xs:string" minOccurs="0" msdata:Ordinal="1" />
</xs:sequence>
<xs:attribute name="class" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="class" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:all>
</xs:complexType>
</xs:element>
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element ref="project" />
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
Figured it out. When using xsd2code I had select options to target the 3.5 framework and include the xml attributes. It now deserializes as expected. Not sure which one did it, but works now.
According to this page '.' is not a valid XML tag name character, so you need to rename <hudson.scm.SubversionSCM_-ModuleLocation> to something without the dots.

Categories

Resources