读取 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>

这两个文件完全代表了它们的对应文件 - 我有 ArmorConsumables 等的单独文件

预期的结果是用一个文件代表以前单独的文件,这样:

Itemsroot 节点。
Items 内是父节点 - ArmorConsumables
每个父节点中都有子节点 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 时,它会尝试将其读取为 stringintstringstringintintintintintintstringstring 并在找到 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>