6

.NET XSD.EXEインポーターを使用して、XSDファイルのコレクションからC#クラスを生成しています。クラスの1つをXMLにシリアル化しようとすると失敗し(InvalidOperationException)、それを掘り下げたときに、作成されたクラスの1つが間違っているように見えることがわかりました。

関連するXSDコードは次のとおりです。

<xsd:complexType name="SuccessType">
    <xsd:annotation>
        <xsd:documentation>Indicates in a response message that a request was successfully processed.</xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
        <xsd:element ref="Warnings" minOccurs="0" maxOccurs="unbounded"/>
    </xsd:sequence>
</xsd:complexType>
<!-- .. snip .. -->
<xsd:element name="Warnings" type="WarningsType">
    <xsd:annotation>
        <xsd:documentation>The processing status of a business message and any related warnings or informational messages.</xsd:documentation>
    </xsd:annotation>
</xsd:element>
<!-- .. snip .. -->
<xsd:complexType name="WarningsType">
    <xsd:annotation>
        <xsd:documentation>A collection of warnings generated by the successful processing of a business message.</xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
        <xsd:element ref="Warning" maxOccurs="unbounded"/>
    </xsd:sequence>
</xsd:complexType>
<!-- .. snip .. -->
<xsd:element name="Warning" type="WarningType">
    <xsd:annotation>
        <xsd:documentation>Defines details of a warning that occurred during message processing.</xsd:documentation>
    </xsd:annotation>
</xsd:element>
<!-- .. snip .. -->
<xsd:complexType name="WarningType">
    <xsd:annotation>
        <xsd:documentation>Defines details of a warning that occurred during message processing.</xsd:documentation>
    </xsd:annotation>
    <xsd:sequence>
        <xsd:element ref="WarningCategory"/>
        <xsd:element ref="WarningCode"/>
        <xsd:element ref="WarningShortMessage"/>
        <xsd:element ref="WarningMessage"/>
    </xsd:sequence>
</xsd:complexType>

そして、これがそれから生成されたC#コードです:

public partial class SuccessType
{

    private WarningType[][] warningsField;

    /// <remarks/>
    [System.Xml.Serialization.XmlArrayItemAttribute("Warning", typeof(WarningType), IsNullable = false)]
    public WarningType[][] Warnings
    {
        get
        {
            return this.warningsField;
        }
        set
        {
            this.warningsField = value;
        }
    }
}

Warningsの配列の配列を作成しましたWarningType。これをXMLにシリアル化しようとすると、InvalidOperationException例外が発生します。

  • 一時クラスを生成できません(result = 1)。
  • エラーCS0030:タイプ'WarningType[]'を'WarningType'に変換できません
  • エラーCS0030:タイプ'WarningType[]'を'WarningType'に変換できません
  • エラーCS0029:タイプ'WarningType'を'WarningType[]'に暗黙的に変換できません
  • エラーCS0029:タイプ'WarningType'を'WarningType[]'に暗黙的に変換できません

しかし、生成されたコードをからに変更すると、WarningType[][]正常WarningType[]にシリアル化されます。

これを再生成するたびに生成されたC#クラスを編集する以外に(今後は頻度が少なくなることを願っています)、他の解決策はありますか?これはxsd.exeのバグですか、それともXSDファイルが正しくありませんか?XmlSerializerに問題があるのではないでしょうか。

私が欲しいのは、XSDに対して検証するXMLに正しくシリアル化するC#コードです。今のところ、ジャグ配列は間違っているようです。削除するとXMLが生成されるからです。

VisualStudio2008を使用しています。

4

1 に答える 1

4

xsd.exeツールにバグがあります。この特定のものは覚えていませんが、ジャグ配列の問題を見つけたことは覚えています。これはバグのままである可​​能性があります。必要に応じて、 XsdObjbectGenツールを使用することもできます。これもMicrosoftから提供されていますが、.NETSDKから独立して帯域外でリリースされています。

逆の方向に進むことができます。C#コードを記述し、xsd.exeを使用してスキーマを生成し、何が違うかを確認します。xsd.exeは、ジャグ配列の正しいコードを正しく生成するために、スキーマを特定の方法で表示することを望んでいる可能性があります。


実際、あなたの質問を読み直したとき、あなたは本当に欲しいものを決して言いませんでした。SuccessTypeに配列の配列を含めるかどうか。

そしてそれはWarningsTypeまたはWarningTypeですか?提供したコードスニップの間にはいくつかの不一致があります。


配列の配列が必要だと仮定して、私は次のC#コードを作成しました。

public class WarningType
{
    public String oof;
}


public partial class SuccessType
{
    private WarningType[][] warningsField;

    /// <remarks/>
    [System.Xml.Serialization.XmlArrayItemAttribute("Warning", typeof(WarningType[]), IsNullable = false)]
    public WarningType[][] Warnings
    {
        get
        {
            return this.warningsField;
        }
        set
        {
            this.warningsField = value;
        }
    }
}

...次にそれをDLLにコンパイルしました。次に、そのDLLでxsd.exeを実行し、次のXSDを生成しました。

<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="WarningType" nillable="true" type="WarningType" />
  <xs:complexType name="WarningType">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="1" name="oof" type="xs:string" />
    </xs:sequence>
  </xs:complexType>
  <xs:element name="SuccessType" nillable="true" type="SuccessType" />
  <xs:complexType name="SuccessType">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="1" name="Warnings" type="ArrayOfArrayOfWarningType" />
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="ArrayOfArrayOfWarningType">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="Warning" type="ArrayOfWarningType" />
    </xs:sequence>
  </xs:complexType>
  <xs:complexType name="ArrayOfWarningType">
    <xs:sequence>
      <xs:element minOccurs="0" maxOccurs="unbounded" name="WarningType" nillable="true" type="WarningType" />
    </xs:sequence>
  </xs:complexType>
</xs:schema>

...そしてそれは往復します。次に、そのスキーマでxsd.exeを実行すると、配列の配列をラップする型が得られます。

于 2010-02-03T01:26:17.647 に答える