2016-04-01 9 views
1

XSD.exeを使用して、XMLスキーマ(.xsdファイル)に基づいてC#オブジェクトを自動的に生成しました。 OpenCoverの出力をデシリアライズしていますが、部分クラスの1つが正しく生成されませんでした。xsi:type属性が上手くいかないC#XML deserialization

ここでは、例外を引き起こしている行です:

<MethodPoint xsi:type="SequencePoint" vc="0" uspid="1" ordinal="0" offset="0" sl="19" sc="9" el="19" ec="10" bec="0" bev="0" fileid="1" /> 

ここMethodPointクラスの短縮バージョンです:

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")] 
[System.SerializableAttribute()] 
[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)] 
public partial class CoverageSessionModulesModuleClassesClassMethodsMethodMethodPoint { 
    private string vcField; 
    private string uspidField; 
    private string ordinalField; 
    private string offsetField; 
    private string slField; 
    private string scField; 
    private string elField; 
    private string ecField; 
    private string becField; 
    private string bevField; 
    private string fileidField; 
} 

は、今私は.xmlファイルの多くを通過してきたが、しかし、 OpenCoverの出力ファイルは属性内にコロンを含む唯一のファイルです。 MethodPointオブジェクトは、属性にコロンを含む唯一のオブジェクトでもあります。ご覧のとおり、クラスにはxsi:type属性は含まれていません。コロンのためにクラスを追加するだけでは機能しません。プレフィックスxsiはどうやって対処していますか?ここで

OpenCover XMLファイルの1

<?xml version="1.0" encoding="utf-8"?> 
<xs:schema id="CoverageSession" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> 
    <xs:element name="Summary"> 
    <xs:complexType> 
     <xs:attribute name="numSequencePoints" type="xs:string" /> 
     <xs:attribute name="visitedSequencePoints" type="xs:string" /> 
     <xs:attribute name="numBranchPoints" type="xs:string" /> 
     <xs:attribute name="visitedBranchPoints" type="xs:string" /> 
     <xs:attribute name="sequenceCoverage" type="xs:string" /> 
     <xs:attribute name="branchCoverage" type="xs:string" /> 
     <xs:attribute name="maxCyclomaticComplexity" type="xs:string" /> 
     <xs:attribute name="minCyclomaticComplexity" type="xs:string" /> 
     <xs:attribute name="visitedClasses" type="xs:string" /> 
     <xs:attribute name="numClasses" type="xs:string" /> 
     <xs:attribute name="visitedMethods" type="xs:string" /> 
     <xs:attribute name="numMethods" type="xs:string" /> 
    </xs:complexType> 
    </xs:element> 
    <xs:element name="CoverageSession" msdata:IsDataSet="true" msdata:UseCurrentLocale="true"> 
    <xs:complexType> 
     <xs:choice minOccurs="0" maxOccurs="unbounded"> 
     <xs:element ref="Summary" /> 
     <xs:element name="Modules"> 
      <xs:complexType> 
      <xs:sequence> 
       <xs:element name="Module" minOccurs="0" maxOccurs="unbounded"> 
       <xs:complexType> 
        <xs:sequence> 
        <xs:element name="FullName" type="xs:string" minOccurs="0" msdata:Ordinal="1" /> 
        <xs:element name="ModuleName" type="xs:string" minOccurs="0" msdata:Ordinal="2" /> 
        <xs:element ref="Summary" minOccurs="0" maxOccurs="unbounded" /> 
        <xs:element name="Files" minOccurs="0" maxOccurs="unbounded"> 
         <xs:complexType> 
         <xs:sequence> 
          <xs:element name="File" minOccurs="0" maxOccurs="unbounded"> 
          <xs:complexType> 
           <xs:attribute name="uid" type="xs:string" /> 
           <xs:attribute name="fullPath" type="xs:string" /> 
          </xs:complexType> 
          </xs:element> 
         </xs:sequence> 
         </xs:complexType> 
        </xs:element> 
        <xs:element name="Classes" minOccurs="0" maxOccurs="unbounded"> 
         <xs:complexType> 
         <xs:sequence> 
          <xs:element name="Class" minOccurs="0" maxOccurs="unbounded"> 
          <xs:complexType> 
           <xs:sequence> 
           <xs:element name="FullName" type="xs:string" minOccurs="0" /> 
           <xs:element ref="Summary" minOccurs="0" maxOccurs="unbounded" /> 
           <xs:element name="Methods" minOccurs="0" maxOccurs="unbounded"> 
            <xs:complexType> 
            <xs:sequence> 
             <xs:element name="Method" minOccurs="0" maxOccurs="unbounded"> 
             <xs:complexType> 
              <xs:sequence> 
              <xs:element name="MetadataToken" type="xs:string" minOccurs="0" msdata:Ordinal="1" /> 
              <xs:element name="Name" type="xs:string" minOccurs="0" msdata:Ordinal="2" /> 
              <xs:element ref="Summary" minOccurs="0" maxOccurs="unbounded" /> 
              <xs:element name="FileRef" minOccurs="0" maxOccurs="unbounded"> 
               <xs:complexType> 
               <xs:attribute name="uid" type="xs:string" /> 
               </xs:complexType> 
              </xs:element> 
              <xs:element name="SequencePoints" minOccurs="0" maxOccurs="unbounded"> 
               <xs:complexType> 
               <xs:sequence> 
                <xs:element name="SequencePoint" minOccurs="0" maxOccurs="unbounded"> 
                <xs:complexType> 
                 <xs:attribute name="vc" type="xs:string" /> 
                 <xs:attribute name="uspid" type="xs:string" /> 
                 <xs:attribute name="ordinal" type="xs:string" /> 
                 <xs:attribute name="offset" type="xs:string" /> 
                 <xs:attribute name="sl" type="xs:string" /> 
                 <xs:attribute name="sc" type="xs:string" /> 
                 <xs:attribute name="el" type="xs:string" /> 
                 <xs:attribute name="ec" type="xs:string" /> 
                 <xs:attribute name="bec" type="xs:string" /> 
                 <xs:attribute name="bev" type="xs:string" /> 
                 <xs:attribute name="fileid" type="xs:string" /> 
                </xs:complexType> 
                </xs:element> 
               </xs:sequence> 
               </xs:complexType> 
              </xs:element> 
              <xs:element name="BranchPoints" minOccurs="0" maxOccurs="unbounded"> 
               <xs:complexType> 
               <xs:sequence> 
                <xs:element name="BranchPoint" minOccurs="0" maxOccurs="unbounded"> 
                <xs:complexType> 
                 <xs:attribute name="vc" type="xs:string" /> 
                 <xs:attribute name="uspid" type="xs:string" /> 
                 <xs:attribute name="ordinal" type="xs:string" /> 
                 <xs:attribute name="offset" type="xs:string" /> 
                 <xs:attribute name="sl" type="xs:string" /> 
                 <xs:attribute name="path" type="xs:string" /> 
                 <xs:attribute name="offsetend" type="xs:string" /> 
                 <xs:attribute name="fileid" type="xs:string" /> 
                 <xs:attribute name="offsetchain" type="xs:string" /> 
                </xs:complexType> 
                </xs:element> 
               </xs:sequence> 
               </xs:complexType> 
              </xs:element> 
              <xs:element name="MethodPoint" minOccurs="0" maxOccurs="unbounded"> 
               <xs:complexType> 
               <xs:attribute name="vc" type="xs:string" /> 
               <xs:attribute name="uspid" type="xs:string" /> 
               <xs:attribute name="ordinal" type="xs:string" /> 
               <xs:attribute name="offset" type="xs:string" /> 
               <xs:attribute name="sl" type="xs:string" /> 
               <xs:attribute name="sc" type="xs:string" /> 
               <xs:attribute name="el" type="xs:string" /> 
               <xs:attribute name="ec" type="xs:string" /> 
               <xs:attribute name="bec" type="xs:string" /> 
               <xs:attribute name="bev" type="xs:string" /> 
               <xs:attribute name="fileid" type="xs:string" /> 
               </xs:complexType> 
              </xs:element> 
              </xs:sequence> 
              <xs:attribute name="visited" type="xs:string" /> 
              <xs:attribute name="cyclomaticComplexity" type="xs:string" /> 
              <xs:attribute name="sequenceCoverage" type="xs:string" /> 
              <xs:attribute name="branchCoverage" type="xs:string" /> 
              <xs:attribute name="isConstructor" type="xs:string" /> 
              <xs:attribute name="isStatic" type="xs:string" /> 
              <xs:attribute name="isGetter" type="xs:string" /> 
              <xs:attribute name="isSetter" type="xs:string" /> 
              <xs:attribute name="skippedDueTo" type="xs:string" /> 
             </xs:complexType> 
             </xs:element> 
            </xs:sequence> 
            </xs:complexType> 
           </xs:element> 
           </xs:sequence> 
          </xs:complexType> 
          </xs:element> 
         </xs:sequence> 
         </xs:complexType> 
        </xs:element> 
        </xs:sequence> 
        <xs:attribute name="skippedDueTo" type="xs:string" /> 
        <xs:attribute name="hash" type="xs:string" /> 
       </xs:complexType> 
       </xs:element> 
      </xs:sequence> 
      </xs:complexType> 
     </xs:element> 
     </xs:choice> 
    </xs:complexType> 
    </xs:element> 
</xs:schema> 
+1

'xsi:type =" SequencePoint "は、この要素の実際の型が' MethodPoint'の派生型、すなわち 'SequencePoint'であることを意味します。 [Xsi:type属性バインディングのサポート](https://msdn.microsoft.com/en-us/library/ca1ks327.aspx)と[2.6.1 xsi:type](https://www.w3.org/)を参照してください。 TR/xmlschema-1 /#xsi_type)。対応する 'SequencePoint'クラスと[' [XmlInclude(typeof(SequencePoint)]]]]が必要です(https://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlincludeattribute.aspx )を 'MethodPoint'に追加します。質問を編集してXSDを含めることはできますか? XMLから作成しましたか? – dbc

+0

@dbcしかし、 'MethodPoint'クラスと同じフィールドを持つ' SequencePoint'クラスがあります。 XMLから自動的に生成されたXSDもXSD.exeに含めました。 –

+0

私はxsdを追加しても構いません。いつでも出力を拡張してコードが破損する可能性があります。 .NETを使用しているので、なぜOpenCover.Frameworkアセンブリをロードしてそこからタイプを使用するだけではないのですか? –

答えて

4

から生成された生の.xsdある短い答えは、あなたが手動MethodPointクラスに[XmlInclude(typeof(SequencePoint))]を追加する必要があるということです。

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.33440")] 
[System.SerializableAttribute()] 
[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)] 
[XmlInclude(typeof(SequencePoint))] 
public partial class CoverageSessionModulesModuleClassesClassMethodsMethodMethodPoint { 
    private string vcField; 
    private string uspidField; 
    private string ordinalField; 
    private string offsetField; 
    private string slField; 
    private string scField; 
    private string elField; 
    private string ecField; 
    private string becField; 
    private string bevField; 
    private string fileidField; 
} 

また、から継承しない場合は、SequencePointを継承する必要があります。 あなたがXMLサンプルからXSDを生成し、その後、順番に#クラスC、それは明らかに多型サブタイプを追加しませんXsd.exeではを使用したときに自動的にタイプをベースにする属性を、ので、あなたがこれを行う必要があり

属性xsi:type="SomePolymoirphicSubType"がXMLに表示されます。

の説明は以下の通りです。 {http://www.w3.org/2001/XMLSchema-instance}typeの略であるxsi:typeアトリビュートは、エレメントが明示的にタイプをアサートできるようにするw3c standard attributeです。それが期待される要素型の多型サブタイプであるとき。 XmlSerializersupports this attributeであり、それを使用して、このような多形型に対して逆シリアル化するオブジェクトの実際の型を決定します。ただし、XmlIncludeAttributeを使用して、可能なすべてのタイプのを事前に通知する必要があります。

[XmlInclude(typeof(SequencePoint))] 
public class MethodPoint 
{ 
} 

public class SequencePoint : MethodPoint 
{ 
} 

そして、次のようにそれをシリアル化:私は次の型階層作成した場合このように、

var test = new SequencePoint(); 

var serializer = new XmlSerializer(typeof(MethodPoint)); 
var sb = new StringBuilder(); 
using (var stream = new StringWriter(sb)) 
    serializer.Serialize(stream, test); 

Console.WriteLine(sb); 

を私は、次のXMLを取得:

<MethodPoint 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
xsi:type="SequencePoint" /> 

その後、私はvar serializer = new XmlSerializer(typeof(MethodPoint))を使用して、それをデシリアライズ場合、私はSequencePoint、その基本クラスではなく戻ってきます。私はこれらのクラスのスキーマを生成するために、Xsd.exeではを使用している場合と、私が手:

<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
    <xs:element name="MethodPoint" nillable="true" type="MethodPoint" /> 
    <xs:complexType name="MethodPoint" /> 
    <xs:complexType name="SequencePoint"> 
    <xs:complexContent mixed="false"> 
     <xs:extension base="MethodPoint" /> 
    </xs:complexContent> 
    </xs:complexType> 
    <xs:element name="SequencePoint" nillable="true" type="SequencePoint" /> 
</xs:schema> 

お知らせxs:extension? XSDが多型サブタイプを示す方法です。そして、私はxsdを実行する場合。後方私のクラスを再生成するためのexeファイルは、私が手:

[System.Xml.Serialization.XmlIncludeAttribute(typeof(SequencePoint))] 
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")] 
[System.SerializableAttribute()] 
[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=true)] 
public partial class MethodPoint { 
} 

/// <remarks/> 
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")] 
[System.SerializableAttribute()] 
[System.Diagnostics.DebuggerStepThroughAttribute()] 
[System.ComponentModel.DesignerCategoryAttribute("code")] 
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=true)] 
public partial class SequencePoint : MethodPoint { 
} 

あなたが見ることができるように、XmlIncludeAttributeがあり、得られるクラスはオリジナルと同等です。これまでのところすべてが完璧に動作しています。

しかし、xsd.exeはサンプルのXMLファイルからXSDを推測すると、xsi:type属性の存在でピックアップしないようです。私は上記の些細なXMLからXSDを作成する場合たとえば、結果は次のとおりです。

<xs:schema id="MethodPoint" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"> 
    <xs:element name="MethodPoint" msdata:IsDataSet="true" msdata:UseCurrentLocale="true"> 
    <xs:complexType> 
     <xs:choice minOccurs="0" maxOccurs="unbounded" /> 
    </xs:complexType> 
    </xs:element> 
</xs:schema> 

多型のサブタイプが完全に欠落しています。このXSDから生成されたクラスは、そのXMLを逆シリアル化できません。

xsd.exeを使用したXMLサンプルからのC#クラスの生成は、適切なXSDから生成するほど信頼性が低いと思われます。具体的には、xsi:typeがXMLファイルに含まれる場合は、生成されたクラスまたは生成されたXSDのいずれかを手動で修正して、必要な階層を実装する必要があります。これは、ツールの制限またはバグの可能性があります。

+0

+1非常に役に立ちます。もう一度upvoteしてください。あなたがxsd.exeを使用した場合にのみあなたの答えが当てはまることに注意してください。Visual Studioの "Paste XML as classes"を使って、かなり長い間同じロジックを試してみました。これはxsi:typeマークアップを理解するのと同じ無能さを持ち、いくつかのマークアップも同様です。 – Sidney

+0

過去10年間、XMLシリアライズで苦労してきた人として、これまでに見た中で最も包括的な答えの1つです。 10月10日、再びシリアル化されます。 – Squiggle

+0

ちょっと@dbc、助けてください!私は同じ状況に直面していますが、私のシーケンスポイントは内側のオブジェクトにあります。私は、親クラスを継承するクラスを作成しましたが、それでもオブジェクトを取得していません。メソッドポイントにプロパティを追加する必要がありますか?私もXMlInclude属性を追加しました –

関連する問題