2010-11-26 52 views
2

我已经从一些3GPP XSD(多个XSD文件/命名空间)生成了一些C#类,它非常适合除了一个用于替代组中的抽象类型的具体实例的问题。XML从xsd.exe生成的代码使用替换组序列化是无效的(无效的xsi:类型错误)

首先,模式的相关部分:

(genericNrm.xsd)

<element name="ManagedElement"> 
    <complexType> 
     <complexContent> 
     <extension base="xn:NrmClass"> 
      <sequence> 
      ... 
      <choice minOccurs="0" maxOccurs="unbounded"> 
       <element ref="xn:IRPAgent"/> 
       <element ref="xn:ManagedElementOptionallyContainedNrmClass"/> 
       <element ref="xn:VsDataContainer"/> 
      </choice> 
      </sequence> 
     </extension> 
     </complexContent> 
    </complexType> 
</element> 

<element 
    name="ManagedElementOptionallyContainedNrmClass" 
    type="xn:NrmClass" 
    abstract="true" 
/> 

(eutran.xsd)

<element name="ENBFunction" substitutionGroup="xn:ManagedElementOptionallyContainedNrmClass"> 
    <complexType> 
     <complexContent> 
     <extension base="xn:NrmClass"> 
      <sequence> 
      <element name="attributes" minOccurs="0"> 
       <complexType> 
       <all> 
        <element name="userLabel" type="string" minOccurs="0"/> 
... etc 

与包含从一个简单的ManagedElement序列化处理的XML ENB功能是:

<ManagedElement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" id="1234" xmlns="http://www.3gpp.org/ftp/specs/archive/32_series/32.625#genericNrm"> 
    <ManagedElementOptionallyContainedNrmClass xmlns:q1="http://www.3gpp.org/ftp/specs/archive/32_series/32.765#eutranNrm" xsi:type="q1:ENBFunction" id="1234"> 
     <q1:attributes> 
     <q1:userLabel>label</q1:userLabel> 
     </q1:attributes> 
    </ManagedElementOptionallyContainedNrmClass> 
    </ManagedElement> 

内置的visual studio XML验证抱怨该元素,指出“这是一个无效的xsi:type'http://www.3gpp.org/ftp/specs/archive/32_series/32.765#eutranNrm:ENBFunction'。

那么是序列化的XML错误还是验证?这与单独的命名空间有关吗?

我可以反序列化XML就好了,但我需要生成的XML符合模式(不更改模式)。我发现,如果我手动更改的XML以下,错误消失(我觉得它更容易也看过):

<ManagedElement xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" id="1234" xmlns="http://www.3gpp.org/ftp/specs/archive/32_series/32.625#genericNrm"> 
    <q1:ENBFunction xmlns:q1="http://www.3gpp.org/ftp/specs/archive/32_series/32.765#eutranNrm" id="1234"> 
     <q1:attributes> 
     <q1:userLabel>label</q1:userLabel> 
     </q1:attributes> 
    </q1:ENBFunction> 
</ManagedElement> 

我可以强制串行输出这种方式?

感谢您的期待...

+1

好运让XML序列化器来处理这个复杂的事情。使用LINQ to XML可能会更好,但最好还是让一些麻烦的类实现IXmlSerializable并手工处理。 – 2010-11-26 21:55:18

回答

2

我通过手动编辑从XSD生成的代码解决了这个问题。一个XmlElementAttribute需要在ManagedElement类物品的收集,以保证序列化工作正常:从ManagedElement继承的类以确保正确的一个是在序列化时使用

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")] 
[System.SerializableAttribute()] 
[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://www.3gpp.org/ftp/specs/archive/32_series/32.625#genericNrm")] 
[System.Xml.Serialization.XmlRootAttribute(Namespace="http://www.3gpp.org/ftp/specs/archive/32_series/32.625#genericNrm", IsNullable=false)] 
public partial class ManagedElement : NrmClass { 

... 

[System.Xml.Serialization.XmlElementAttribute("ENBFunction", typeof(ENBFunction), Namespace = "http://www.3gpp.org/ftp/specs/archive/32_series/32.765#eutranNrm")] 
public NrmClass[] Items { 
... 

此属性是必需的。

相关问题