Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 反序列化已验证的XML时出现问题,can';t转换为数组/从数组转换_C#_Xml_Xsd_Serialization_Xsd.exe - Fatal编程技术网

C# 反序列化已验证的XML时出现问题,can';t转换为数组/从数组转换

C# 反序列化已验证的XML时出现问题,can';t转换为数组/从数组转换,c#,xml,xsd,serialization,xsd.exe,C#,Xml,Xsd,Serialization,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="";

我有点不知所措。我使用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);
它可以很好地编译,但是当我尝试运行它时,我得到一个错误,该错误对四个不同的对象重复出现。我在下面给出了一个例子,更改对象的名称

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[]'
所以看起来程序试图从一个数组到另一个对象再回到另一个数组,但我不是很确定。自动生成的类代码非常混乱,很难处理。我希望这里可能有一些简单的东西我遗漏了


谢谢

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

    private loot[][] lootTallyField;

我所做的只是移除了一组支架,看起来一切都很好。反序列化没有问题,快速检查反序列化对象使其看起来数据加载正确

    private loot[] lootTallyField;

仍然不知道为什么xsd.exe会对这些不应该被索引的文件进行双重索引。我觉得我仍然缺少一些东西,因此为什么这个问题仍然悬而未决


特别是,如果我需要重新生成此代码,那么我需要重新应用修复程序,这会首先破坏使用分部类的目的…

xsd.exe工具上存在问题,我将尝试解释

如果您有一个包含序列的complexType,其中有一个子complexType和一个序列,并且第一个complexType没有任何其他元素/属性,那么生成的类将只有1个生成的类型,而不是2个,并且它将是一个双数组

如果将双数组转换为单数组,则可以很好地反序列化xml。 但是,这将产生以下意外结果。 如果您的xml如下所示

<root>
    <loot>
        <tally>value1</tally>
        <tally>value2</tally>
    </loot>
    <loot>
        <tally>value3</tally>
        <tally>value4</tally>
    </loot>
</root>

价值1
价值2
价值3
价值4
然后,RootTally数组中的反序列化对象将只包含value3和value4项,而不是全部包含4项

因此,您有两个选项可以正确修复此问题:

  • 通过在第一个序列中添加虚拟来更改xsd文件,并再次运行xsd.exe,以便在生成类时不会创建双数组,然后可以从类中删除虚拟属性
  • 更改生成的类,添加一个名为loot的新类,该类将包含一个您已经拥有的tally对象数组(并且只需要更改名称)
  • 请注意,在选项2中,如果将XmlArrayItemAttribute更改为XmlElementAttribute,则可能需要更改某些声明


    希望这对解析DDI字符生成器文件有所帮助?我稍后会看一看,看能不能提供一些想法。他们在上一次更新中非常友好,使XML文件对第三方更加友好,所以我想我会接受他们。我确实设法把它修好了。即将添加有关修复程序的详细信息,但我将保留问题,因为我不明白问题首先出现的原因。这是一个旧问题,但仍然有效,以下是更多信息,以防其他人遇到此问题:。这篇文章包含了一个稍微优雅一点的解决方案(在模式中添加一个属性)和一个示例。问题实际上是.NET的XmlSerializer中的一个bug:您还可以通过删除不应该是数组的元素的maxOccurs=“unbounded”属性(这就是这些2d数组的原因)来编辑生成的XSD文件,而不是更改生成的类。这是一个很好的答案。节省了我很多时间。我生成了一个SalesForce企业WSDL,并使用VS2017从该文件生成POCO,但我也得到了双索引数组。
        public loot[] LootTally
        {
            get
            {
                return this.lootTallyField;
            }
            set
            {
                this.lootTallyField = value;
            }
        }
    
    <root>
        <loot>
            <tally>value1</tally>
            <tally>value2</tally>
        </loot>
        <loot>
            <tally>value3</tally>
            <tally>value4</tally>
        </loot>
    </root>