Reputation: 1505
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.
Upvotes: 0
Views: 1676
Reputation: 2164
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>
Upvotes: 1