问题反序列化经过验证的XML,无法转换为数组或从数组转换

Asm*_*mor 2 c# xml serialization xsd xsd.exe

我有点偏离我的元素.我已经使用xsd.exe从xml文件创建xsd架构,然后从该xsd创建一个C#类.这一切似乎都很好.

目前我只是想让XML反序列化.我正在反序列化文件,如果我最初用于构建类的文件相同.这是我的代码:

String xsdPath=@"C:\Users\tol56881\Documents\dnd4e.xsd";
String xmlPath=@"C:\Users\tol56881\Documents\dnd4e.xml";
String xsdNamespace="";

//Validation stuff
XmlParserContext context = new XmlParserContext(null, null, "", XmlSpace.None);
XmlValidatingReader vr = new XmlValidatingReader(xmlPath, XmlNodeType.Element, context);
vr.ValidationType = ValidationType.Schema;
vr.Schemas.Add(xsdNamespace, xsdPath);
while (vr.Read()) ;

//Actually reading the file
TextReader tr = new StreamReader(xmlPath);
D20Character character = (D20Character)(new XmlSerializer(typeof(D20Character))).Deserialize(tr);
Run Code Online (Sandbox Code Playgroud)

它编译得很好,但是当我尝试运行它时,我得到了一个错误,它重复了四个不同的对象.我在下面给出了一个例子,更改了对象的名称.

Unable to generate a temporary class (result=1).
error CS0030: Cannot convert type 'Namespace.ObjectName[]' to 'Namespace.ObjectName'
error CS0029: Cannot implicitly convert type 'Namespace.ObjectName' to 'Namespace.ObjectName[]'
Run Code Online (Sandbox Code Playgroud)

所以看起来程序试图从数组到对象再回到数组,但我不太确定.自动生成的类代码是一个巨大的混乱,很难通过.我希望也许这里有一些简单的我在这里缺席.

谢谢!

Asm*_*mor 10

我设法解决了这个问题.所讨论的四个对象中的每一个都生成为双索引数组,例如:

    private loot[][] lootTallyField;
Run Code Online (Sandbox Code Playgroud)

    public loot[][] LootTally
    {
        get
        {
            return this.lootTallyField;
        }
        set
        {
            this.lootTallyField = value;
        }
    }
Run Code Online (Sandbox Code Playgroud)

我所做的就是删除一组括号,这一切似乎都运行正常.反序列化和反序列化对象的快速检查没有问题,使得它看起来像数据已正确加载.

    private loot[] lootTallyField;
Run Code Online (Sandbox Code Playgroud)

    public loot[] LootTally
    {
        get
        {
            return this.lootTallyField;
        }
        set
        {
            this.lootTallyField = value;
        }
    }
Run Code Online (Sandbox Code Playgroud)

仍然不确定为什么xsd.exe如果它们不应该是这些双重索引.我觉得我还在遗漏一些东西,所以为什么这个问题仍然存在.

特别是,如果我需要重新生成这个代码,那么我需要重新应用修复,这种方式首先打破了使用部分类的目的......


小智 5

xsd.exe工具有问题,我会尽力解释.

如果你有一个带有序列的complexType,其中一个子complexType带有一个序列,而第一个没有任何其他元素/属性,那么生成的类只有1个生成的类型,而不是2,它将是一个double阵列.

如果将双数组放入单个数组中,则可以将xml反序列化.但是,这会产生以下意外结果.如果您的xml如下所示.

<root>
    <loot>
        <tally>value1</tally>
        <tally>value2</tally>
    </loot>
    <loot>
        <tally>value3</tally>
        <tally>value4</tally>
    </loot>
</root>
Run Code Online (Sandbox Code Playgroud)

然后你的反序列化对象,在lootTally数组中只包含value3和value4项而不是全部4.

所以你有2个选项来正确解决这个问题:

  1. 通过在第一个序列中添加一个哑元来改变xsd文件,然后再次运行xsd.exe,这样当它生成类时它不会创建一个double数组,然后你可以从类中删除dummy属性.
  2. 更改生成的类,添加一个名为loot的新类,它将包含您已有的计数对象数组(并且只需要更改名称).

请注意,在选项2中,如果XmlArrayIttribute属性为XmlElementAttribute,则可能需要更改一些声明.

希望这可以帮助