【问题标题】:Reading XML to DataSet with multiple tables in file使用文件中的多个表将 XML 读取到 DataSet
【发布时间】:2015-11-05 16:50:57
【问题描述】:

我正在为一个个人项目构建一个 XML 编辑器。使用 WinForms DataGridView 控件和 DataSet,我能够毫无问题地设置读取/编辑/保存,为每种类型使用单独的 XML 文件。

但是,当我开始尝试添加更多“高级”控件时,处理几个不同的文件变得很麻烦 - 需要 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);

当文件/模式是分开的时,这个确切的方法没有问题,这进一步让我相信我只是忽略了 XML/模式中的一些东西。

在这一点上,我被卡住了,不确定它会是什么。如果有人能帮我解决这个问题,我将不胜感激。

【问题讨论】:

    标签: c# xml winforms xsd


    【解决方案1】:

    问题是您在每个项目类型上重复元素Item。 当您的代码读取架构时,它会找到 Item 元素的第一次出现,并尝试将相同的架构应用于其他所有出现;因此,当它读取Test Potion 时,它会尝试将其读取为stringintstringstringintintintint、@987654 , 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>
    

    【讨论】:

    • 这真的很有意义!我没想到。
    • aa并且它运行良好。感谢您指出了这一点。学到了新东西!
    猜你喜欢
    • 2013-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-08
    • 1970-01-01
    • 2012-07-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多