5

开始使用 XML 和 C# 练习,我收到一条错误消息“XML 文档 (3,2) 中存在错误”。查看文件后,我看不出有什么问题(请注意,我可能错过了一些东西,因为我是菜鸟)。我现在正在使用 C# 的控制台应用程序。我试图返回一个冒险者列表,只是一个旁注,GEAR 元素是可选的。这是我到目前为止所拥有的:

XML 文件 - 测试 1

<?xml version="1.0" encoding="utf-8"?>
<Catalog>
    <Adventurer>
        <ID>001</ID>
        <Name>John Smith</Name>
        <Address>123 Fake Street</Address>
        <Phone>123-456-7890</Phone>
        <Gear>
            <Attack>
                <Item>
                    <IName>Sword</IName>
                    <IPrice>15.00</IPrice>
                </Item> 
                <Item>
                    <IName>Wand</IName>
                    <IPrice>20.00</IPrice>
                </Item>         
            </Attack>
            <Defense>
                <Item>
                    <IName>Shield</IName>
                    <IPrice>5.00</IPrice>
                </Item>
        </Defense>  
        </Gear>
    </Adventurer>
    <Adventurer>
        <ID>002</ID>
        <Name>Guy noone likes</Name>
        <Address>Some Big House</Address>
        <Phone>666-666-6666</Phone>
        <Gear></Gear>
    </Adventurer>
</Catalog>

C# 类

public class Catalog
{
    List<Adventurer> Adventurers { get; set; }
}

public class Adventurer
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
    public string Phone { get; set; }
    public Gear Gear { get; set; }
}

public class Gear
{
    public List<Item> Attack { get; set; }
    public List<Item> Defense { get; set; }
}

public class Item
{
    public string IName { get; set; }
    public decimal IPrice { get; set; }
}

序列化函数- 问题出现在第 5 行

Catalog obj = null;
string path = @"C:\Users\Blah\Desktop\test1.xml";
XmlSerializer serializer = new XmlSerializer(typeof(Catalog));
StreamReader reader = new StreamReader(path);
obj = (Catalog)serializer.Deserialize(reader);
reader.Close();

Console.ReadLine();
4

4 回答 4

3

问题是目录中的冒险者列表:

<?xml version="1.0" encoding="utf-8"?>
<Catalog>
    <Adventurers> <!-- you're missing this -->
        <Adventurer>
        </Adventurer>
        ...
        <Adventurer>
        </Adventurer>
    </Adventurers> <!-- and missing this -->
</Catalog>

您没有Adventurers集合的包装元素。

编辑:顺便说一句,我发现构建 XML 结构并确保其兼容的最简单方法是在 C# 中创建对象,然后运行内置XmlSerializer并使用其 XML 输出作为任何 XML 的基础我创造而不是手工形成它。

于 2012-06-28T17:08:37.090 回答
2

首先,“Adventurers”属性不是公开的,无法访问,我认为找到错误的最佳方法是序列化您的对象,然后将结果与您的 xml 文件进行比较。

于 2012-06-28T17:17:29.203 回答
1

我能够通过一些小的更改(即 Adventurer 上的公共限定符)使您的 xml 反序列化。

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml.Serialization;

namespace TempSandbox
{
    [XmlRoot]
    public class Catalog
    {
        [XmlElement("Adventurer")]
        public List<Adventurer> Adventurers;

        private readonly static Type[] myTypes = new Type[] { typeof(Adventurer), typeof(Gear), typeof(Item) };
        private readonly static XmlSerializer mySerializer = new XmlSerializer(typeof(Catalog), myTypes);

        public static Catalog Deserialize(string xml)
        {
            return (Catalog)Utils.Deserialize(mySerializer, xml, Encoding.UTF8);
        }
    }

    [XmlRoot]
    public class Adventurer
    {
        public int ID;

        public string Name;

        public string Address;

        public string Phone;

        [XmlElement(IsNullable = true)]
        public Gear Gear;
    }

    [XmlRoot]
    public class Gear
    {
        public List<Item> Attack;

        public List<Item> Defense;
    }

    [XmlRoot]
    public class Item
    {
        public string IName;

        public decimal IPrice;
    }
}

我正在使用 [XmlElement("Adventurer")] 因为 xml 元素名称与类属性名称不完全匹配。

注意:我正在使用手头已有的通用反序列化实用程序。

于 2012-06-28T17:56:08.803 回答
1

您的 XML 与您的对象不太一致......即这两个......

public string City { get; set; }

<Address>123 Fake Street</Address>

将城市更改为地址,反之亦然,它应该可以解决问题。

编辑:让它在一个测试项目中工作,结合我们所有的答案......

在之后(和之前)添加<Adventurers>标签并更改<Catalog></Adventurers></Catalog>

List<Adventurer> Adventurers { get; set; }

public List<Adventurer> Adventurers { get; set; }

它适用于我。

于 2012-06-28T17:04:02.600 回答