读取 XML 到文件中包含多个表的 DataSet
Reading XML to DataSet with multiple tables in file
我正在为个人项目构建 XML 编辑器。使用 WinForms DataGridView
控件和 DataSet
,我能够毫无问题地设置 Read/Edit/Save,为每种类型使用单独的 XML 文件。
但是,当我开始尝试添加更多 "advanced" 控件时,处理几个不同的文件变得很麻烦 - 需要 if
语句,具体取决于我正在处理的文件。所以,我尝试将这些文件合并成一个更大的文件,如下所示:
<?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>
和架构,从 Visual Studio 的 Create Schema
菜单生成,并进行了最少的修改 - 例如将 unsignedInt
更改为 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>
这两个文件完全代表了它们的对应文件 - 我有 Armor
、Consumables
等的单独文件
预期的结果是用一个文件代表以前单独的文件,这样:
Items
是 root
节点。
Items
内是父节点 - Armor
、Consumables
等
每个父节点中都有子节点 Item
及其属性。
据我所知,XML 结构和模式看起来是正确的,但是当我尝试将此文件读入我的程序时,我收到错误:System.FormatException - "Input string was not in a correct format."
。
堆栈跟踪显示 System.Number.StringToNumber
正在抛出此异常。我已经多次浏览文件和模式,但似乎无法找到发生这种情况的位置,异常详细信息也没有提供更多详细信息。
在我的代码中,我只是使用
读取数据
DataSet data = new DataSet();
data.ReadXmlSchema(itemSchema);
data.ReadXml(itemData);
当 files/schema 分开时,这种确切的方法没有问题,这进一步让我相信我只是忽略了 XML/Schema.
中的某些内容
在这一点上,我卡住了,不确定它会是什么。如果有人能帮我解决这个问题,我将不胜感激。
问题是您在每个项目类型上重复元素 Item
。
当您的代码读取模式时,它会找到 Item
元素的第一次出现,并尝试将相同的模式应用于其他所有出现;因此,当它读取 Test Potion
时,它会尝试将其读取为 string
、int
、string
、string
、int
、int
、int
、int
、int
、int
、string
、string
并在找到 0.1234567 Health
时失败值。
我的建议是将您的架构更改为如下所示:
<?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>
我正在为个人项目构建 XML 编辑器。使用 WinForms DataGridView
控件和 DataSet
,我能够毫无问题地设置 Read/Edit/Save,为每种类型使用单独的 XML 文件。
但是,当我开始尝试添加更多 "advanced" 控件时,处理几个不同的文件变得很麻烦 - 需要 if
语句,具体取决于我正在处理的文件。所以,我尝试将这些文件合并成一个更大的文件,如下所示:
<?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>
和架构,从 Visual Studio 的 Create Schema
菜单生成,并进行了最少的修改 - 例如将 unsignedInt
更改为 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>
这两个文件完全代表了它们的对应文件 - 我有 Armor
、Consumables
等的单独文件
预期的结果是用一个文件代表以前单独的文件,这样:
Items
是 root
节点。
Items
内是父节点 - Armor
、Consumables
等
每个父节点中都有子节点 Item
及其属性。
据我所知,XML 结构和模式看起来是正确的,但是当我尝试将此文件读入我的程序时,我收到错误:System.FormatException - "Input string was not in a correct format."
。
堆栈跟踪显示 System.Number.StringToNumber
正在抛出此异常。我已经多次浏览文件和模式,但似乎无法找到发生这种情况的位置,异常详细信息也没有提供更多详细信息。
在我的代码中,我只是使用
读取数据DataSet data = new DataSet();
data.ReadXmlSchema(itemSchema);
data.ReadXml(itemData);
当 files/schema 分开时,这种确切的方法没有问题,这进一步让我相信我只是忽略了 XML/Schema.
中的某些内容在这一点上,我卡住了,不确定它会是什么。如果有人能帮我解决这个问题,我将不胜感激。
问题是您在每个项目类型上重复元素 Item
。
当您的代码读取模式时,它会找到 Item
元素的第一次出现,并尝试将相同的模式应用于其他所有出现;因此,当它读取 Test Potion
时,它会尝试将其读取为 string
、int
、string
、string
、int
、int
、int
、int
、int
、int
、string
、string
并在找到 0.1234567 Health
时失败值。
我的建议是将您的架构更改为如下所示:
<?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>