C# 使用System.xml.Serialization.XmlSerializer反序列化有效xml文件时存在差异

C# 使用System.xml.Serialization.XmlSerializer反序列化有效xml文件时存在差异,c#,xml,xml-serialization,xmlserializer,C#,Xml,Xml Serialization,Xmlserializer,这是一个相当复杂的问题,请提前感谢。以下两个xml文件都根据给定的架构进行验证,但在尝试使用.Net的XmlSerializer进行反序列化时,只有第一个文件正确执行此操作: <ex:iso_10303_28 xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.iai-tech.org/ifcXML/IFC2x3/

这是一个相当复杂的问题,请提前感谢。以下两个xml文件都根据给定的架构进行验证,但在尝试使用.Net的XmlSerializer进行反序列化时,只有第一个文件正确执行此操作:

<ex:iso_10303_28 xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.iai-tech.org/ifcXML/IFC2x3/FINAL" version="2.0" xmlns:ex="urn:iso.org:standard:10303:part(28):version(2):xmlschema:common">
  <ex:iso_10303_28_header>
    <ex:name>An Example</ex:name>
    <ex:time_stamp>2010-11-12T13:04:00</ex:time_stamp>
    <ex:author>John Hancock</ex:author>
    <ex:organization>MegaCorp</ex:organization>
    <ex:preprocessor_version>a preprocessor</ex:preprocessor_version>
    <ex:originating_system>IfcXml dotNet Library</ex:originating_system>
    <ex:authorization>none</ex:authorization>
    <ex:documentation>documentation</ex:documentation>
  </ex:iso_10303_28_header>
  <ex:uos xsi:type="uos" id="uos_1" configuration="i-ifc2x3">
    <ex:Entity xsi:type="IfcOrganization" id="i1101">
      <Id xsi:nil="true" />
      <Name>MegaCorp</Name>
      <Description xsi:nil="true" />
      <Roles xsi:nil="true" />
      <Addresses xsi:nil="true" />
    </ex:Entity>
    <ex:Entity xsi:type="IfcCartesianPoint" id="i101">
      <Coordinates ex:itemType="ifc:IfcLengthMeasure" ex:cType="list">
        <IfcLengthMeasure>2500</IfcLengthMeasure>
        <IfcLengthMeasure>0</IfcLengthMeasure>
        <IfcLengthMeasure>0</IfcLengthMeasure>
      </Coordinates>
    </ex:Entity>
    <ex:Entity xsi:type="IfcDirection" id="i102">
      <DirectionRatios ex:itemType="ex:double-wrapper" ex:cType="list">
        <ex:double-wrapper>0</ex:double-wrapper>
        <ex:double-wrapper>1</ex:double-wrapper>
        <ex:double-wrapper>0</ex:double-wrapper>
      </DirectionRatios>
    </ex:Entity>
  </ex:uos>
</ex:iso_10303_28>
我的反序列化程序本质上是:

iso_10303_28 deserialized = (iso_10303_28)serializer.Deserialize( reader );

//using NUnit
Assert.IsNotNull(deserialized);
Assert.IsNotNull(deserialized.uos);
uos1 uos1 = deserialized.uos as uos1;
Assert.IsNotNull(uos1);
Assert.IsNotNull(uos1.Items); //<---FAILS HERE
Assert.AreEqual(3, uos1.Items.length);
以前有人遇到过这个问题吗?这有什么原因吗?我错过什么了吗?是否有修复或解决方法


由于模式和代码的其余部分相当大,并且试图将它们简化到最小失败部分会导致更多问题(请参阅),因此我没有将它们粘贴到这里。但是,如果需要,这个问题的模式、单元测试和源代码可以在

中找到。在文件1中,两个XML文件不相同,uso在ex下是合格的,所以它在“urn:iso.org:standard:10303:part(28):version(2):xmlschema:common”命名空间下,而在第二个命名空间中它不是,并且在默认命名空间下

在类“iso_10303_28”中,uos类型的属性uos,这意味着XmlSerializer将在与类“uos”描述的iso_10303_28和“xsi:type”uos相同的命名空间下使用名为“uos”的元素(默认情况下),并在相同的“urn:iso.org:standard:10303:part(28):version(2):xmlschema:common”命名空间下使用。这就解释了为什么在第二个xml中会出现null。 如果您无法控制xml,并且应该能够对其中任何一个进行反序列化,请尝试以下操作

  • 除非XmlInclude属性指定,否则类型uos不知道类型uos1。我认为您在uos类上额外添加了一个XmlInclude属性,以将uos1作为已知类型包含在内。如果不是-序列化程序将不会反序列化第一个文件。 如果不是,你应该按照下面的方法来做

    [System.Xml.Serialization.xmlclude(typeof(uos1))] [System.Xml.Serialization.XmlTypeAttribute(Namespace=“urn:iso.org:standard:10303:part(28):version(2):xmlschema:common”)] 公共部分类uos {

  • 您可以为属性iso_10303_28.uos添加XmlElement属性,以接受命名空间下的名称-并使用选项标识符,或使用“uos[]”作为类型而不是“uos”。使用选项标识符-可以按以下方式执行:

  • [System.Xml.Serialization.XmlRootAttribute(Namespace=“urn:iso.org:standard:10303:part(28):version(2):xmlschema:common”,IsNullable=false)] 公共部分类iso_10303_28 { 私人uos uosField

        public enum uosChoice
        {
            [XmlEnum("http://www.iai-tech.org/ifcXML/IFC2x3/FINAL:uos")]
            uos,
            [XmlEnum("urn:iso.org:standard:10303:part(28):version(2):xmlschema:common:uos")]
            uos1
        }
    
        [XmlIgnore]
        public uosChoice uosChoiceField;
    
        [XmlChoiceIdentifier("uosChoiceField")]
        [XmlElement(ElementName = "uos", Namespace = "http://www.iai-tech.org/ifcXML/IFC2x3/FINAL", Type = typeof(uos1))]
        [XmlElement(ElementName = "uos", Namespace = "urn:iso.org:standard:10303:part(28):version(2):xmlschema:common")]
        public uos uos
        {
            get
            {
                return this.uosField;
            }
            set
            {
                this.uosField = value;
            }
        }
    
    
    }
    
    编辑:要正确分析项目,请按如下方式修改uos1

     [System.Xml.Serialization.XmlTypeAttribute(TypeName = "uos", Namespace = "http://www.iai-tech.org/ifcXML/IFC2x3/FINAL")]
        [System.Xml.Serialization.XmlRootAttribute("uos", Namespace = "http://www.iai-tech.org/ifcXML/IFC2x3/FINAL", IsNullable = false)]
        public partial class uos1 : uos
        {
            private Entity[] itemsField;
    
            /// <remarks/>
            [XmlElement(ElementName = "Entity", Namespace = "urn:iso.org:standard:10303:part(28):version(2):xmlschema:common", Type = typeof(Entity))]
            [XmlElement(ElementName = "IfcOrganization", Namespace = "http://www.iai-tech.org/ifcXML/IFC2x3/FINAL", Type = typeof(IfcOrganization))]
            [XmlElement(ElementName = "IfcCartesianPoint", Namespace = "http://www.iai-tech.org/ifcXML/IFC2x3/FINAL", Type = typeof(IfcCartesianPoint))]
            [XmlElement(ElementName = "IfcDirection", Namespace = "http://www.iai-tech.org/ifcXML/IFC2x3/FINAL", Type = typeof(IfcDirection))]
            public Entity[] Items
            {
                get
                {
                    return this.itemsField;
                }
                set
                {
                    this.itemsField = value;
                }
            }
    
        }
    
     [System.Xml.Serialization.XmlTypeAttribute(TypeName = "IfcOrganization", Namespace = "http://www.iai-tech.org/ifcXML/IFC2x3/FINAL")]
        public class IfcOrganization : Entity
        {
    
        }
    
        [System.Xml.Serialization.XmlTypeAttribute(TypeName = "IfcCartesianPoint", Namespace = "http://www.iai-tech.org/ifcXML/IFC2x3/FINAL")]
        public class IfcCartesianPoint : Entity
        {
    
        }
    
        [System.Xml.Serialization.XmlTypeAttribute(TypeName = "IfcDirection", Namespace = "http://www.iai-tech.org/ifcXML/IFC2x3/FINAL")]
        public class IfcDirection : Entity
        {
    
        }
    
        [XmlInclude(typeof(IfcOrganization))]
        [XmlInclude(typeof(IfcCartesianPoint))]
        [XmlInclude(typeof(IfcDirection))]
        [System.Xml.Serialization.XmlTypeAttribute(TypeName = "Entity", Namespace = "urn:iso.org:standard:10303:part(28):version(2):xmlschema:common")]
        public class Entity
        {
    
        }
    
    [System.Xml.Serialization.XmlTypeAttribute(TypeName=“uos”,命名空间=”http://www.iai-tech.org/ifcXML/IFC2x3/FINAL")]
    [System.Xml.Serialization.XmlRootAttribute(“uos”,命名空间=”http://www.iai-tech.org/ifcXML/IFC2x3/FINAL“,IsNullable=false)]
    公共部分类uos1:uos
    {
    私人实体[]项字段;
    /// 
    [xmlement(ElementName=“Entity”,Namespace=“urn:iso.org:standard:10303:part(28):version(2):xmlschema:common”,Type=typeof(Entity))]
    [XmlElement(ElementName=“IfcOrganization”,命名空间=”http://www.iai-tech.org/ifcXML/IFC2x3/FINAL“,Type=typeof(IfcOrganization))]
    [xmlement(ElementName=“IfcCartesianPoint”,命名空间=”http://www.iai-tech.org/ifcXML/IFC2x3/FINAL“,Type=typeof(IfcCartesianPoint))]
    [XmlElement(ElementName=“IfcDirection”,命名空间=”http://www.iai-tech.org/ifcXML/IFC2x3/FINAL“,Type=typeof(ifcd方向))]
    公共实体[]项
    {
    得到
    {
    返回此.itemsField;
    }
    设置
    {
    this.itemsField=值;
    }
    }
    }
    [System.Xml.Serialization.XmlTypeAttribute(TypeName=“IfcOrganization”,命名空间=”http://www.iai-tech.org/ifcXML/IFC2x3/FINAL")]
    公共类IfcOrganization:实体
    {
    }
    [System.Xml.Serialization.XmlTypeAttribute(TypeName=“IfcCartesianPoint”,命名空间=”http://www.iai-tech.org/ifcXML/IFC2x3/FINAL")]
    公共类IfcCartesianPoint:实体
    {
    }
    [System.Xml.Serialization.XmlTypeAttribute(TypeName=“IfcDirection”,命名空间=”http://www.iai-tech.org/ifcXML/IFC2x3/FINAL")]
    公共类IfcDirection:实体
    {
    }
    [xmlclude(typeof(ifcororganization))]
    [xmlclude(typeof(IfcCartesianPoint))]
    [xmlclude(typeof(ifcd方向))]
    [System.Xml.Serialization.XmlTypeAttribute(TypeName=“Entity”,Namespace=“urn:iso.org:standard:10303:part(28):version(2):xmlschema:common”)]
    公共类实体
    {
    }
    
    在应用#2时,我遇到了几个错误。
    [xmlcoiceIdentifier(“忽略”)]
    应该是
    [xmlcoiceIdentifier(“uosChoice”)]
    公共uosChoice uosChoiceField
    应该有
    [xmlcoliner()]
    属性。按照上面的注释进行这些更改(作为第7版提交到code.google.com/p/ifc-dotnet/source/checkout),反序列化测试现在反序列化uos,因此它不是空的。不幸的是,它无法将uos强制转换为uos1,这意味着所有重要的uos1。项目仍然无法访问。:(抱歉,[xmlcoiceIdentifier(“忽略”)]应更改为[xmlcoiceIdentifier(“uosChoice”))]正如前面指出的那样,像这样更改XmlElement属性将正确解析为uos1[XmlElement(ElementName=“uos”,Namespace=”“,Type=typeof(uos1))],我已经编辑了这篇文章以反映-在XmlElement中添加类型-这对您有用
    [System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:iso.org:standard:10303:part(28):version(2):xmlschema:common")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace="urn:iso.org:standard:10303:part(28):version(2):xmlschema:common", IsNullable=false)]
    public partial class iso_10303_28 {
    
        private iso_10303_28_header iso_10303_28_headerField;
    
        private uos uosField;
    
        private string versionField;
    
        /// <remarks/>
        public iso_10303_28_header iso_10303_28_header {
            get {
                return this.iso_10303_28_headerField;
            }
            set {
                this.iso_10303_28_headerField = value;
            }
        }
    
        public enum uosChoice
        {
            [XmlEnum("http://www.iai-tech.org/ifcXML/IFC2x3/FINAL:uos")]
            uos1,
            [XmlEnum("urn:iso.org:standard:10303:part(28):version(2):xmlschema:common:uos")]
            uos
        }
    
        [XmlIgnore()]
        public uosChoice uosChoiceField;
    
        [XmlChoiceIdentifier("uosChoiceField")]
        [XmlElement(ElementName = "uos", Namespace = "http://www.iai-tech.org/ifcXML/IFC2x3/FINAL", Type = typeof(uos1))]
        [XmlElement(ElementName = "uos", Namespace = "urn:iso.org:standard:10303:part(28):version(2):xmlschema:common")]
        public uos uos {
            get {
                return this.uosField;
            }
            set {
                this.uosField = value;
            }
        }
    
        /// <remarks/>
        [System.Xml.Serialization.XmlAttributeAttribute()]
        public string version {
            get {
                return this.versionField;
            }
            set {
                this.versionField = value;
            }
        }
    }
    
    }
    
        public enum uosChoice
        {
            [XmlEnum("http://www.iai-tech.org/ifcXML/IFC2x3/FINAL:uos")]
            uos,
            [XmlEnum("urn:iso.org:standard:10303:part(28):version(2):xmlschema:common:uos")]
            uos1
        }
    
        [XmlIgnore]
        public uosChoice uosChoiceField;
    
        [XmlChoiceIdentifier("uosChoiceField")]
        [XmlElement(ElementName = "uos", Namespace = "http://www.iai-tech.org/ifcXML/IFC2x3/FINAL", Type = typeof(uos1))]
        [XmlElement(ElementName = "uos", Namespace = "urn:iso.org:standard:10303:part(28):version(2):xmlschema:common")]
        public uos uos
        {
            get
            {
                return this.uosField;
            }
            set
            {
                this.uosField = value;
            }
        }
    
    
    }
    
     [System.Xml.Serialization.XmlTypeAttribute(TypeName = "uos", Namespace = "http://www.iai-tech.org/ifcXML/IFC2x3/FINAL")]
        [System.Xml.Serialization.XmlRootAttribute("uos", Namespace = "http://www.iai-tech.org/ifcXML/IFC2x3/FINAL", IsNullable = false)]
        public partial class uos1 : uos
        {
            private Entity[] itemsField;
    
            /// <remarks/>
            [XmlElement(ElementName = "Entity", Namespace = "urn:iso.org:standard:10303:part(28):version(2):xmlschema:common", Type = typeof(Entity))]
            [XmlElement(ElementName = "IfcOrganization", Namespace = "http://www.iai-tech.org/ifcXML/IFC2x3/FINAL", Type = typeof(IfcOrganization))]
            [XmlElement(ElementName = "IfcCartesianPoint", Namespace = "http://www.iai-tech.org/ifcXML/IFC2x3/FINAL", Type = typeof(IfcCartesianPoint))]
            [XmlElement(ElementName = "IfcDirection", Namespace = "http://www.iai-tech.org/ifcXML/IFC2x3/FINAL", Type = typeof(IfcDirection))]
            public Entity[] Items
            {
                get
                {
                    return this.itemsField;
                }
                set
                {
                    this.itemsField = value;
                }
            }
    
        }
    
     [System.Xml.Serialization.XmlTypeAttribute(TypeName = "IfcOrganization", Namespace = "http://www.iai-tech.org/ifcXML/IFC2x3/FINAL")]
        public class IfcOrganization : Entity
        {
    
        }
    
        [System.Xml.Serialization.XmlTypeAttribute(TypeName = "IfcCartesianPoint", Namespace = "http://www.iai-tech.org/ifcXML/IFC2x3/FINAL")]
        public class IfcCartesianPoint : Entity
        {
    
        }
    
        [System.Xml.Serialization.XmlTypeAttribute(TypeName = "IfcDirection", Namespace = "http://www.iai-tech.org/ifcXML/IFC2x3/FINAL")]
        public class IfcDirection : Entity
        {
    
        }
    
        [XmlInclude(typeof(IfcOrganization))]
        [XmlInclude(typeof(IfcCartesianPoint))]
        [XmlInclude(typeof(IfcDirection))]
        [System.Xml.Serialization.XmlTypeAttribute(TypeName = "Entity", Namespace = "urn:iso.org:standard:10303:part(28):version(2):xmlschema:common")]
        public class Entity
        {
    
        }