0

複数の XSD から C# クラスを生成する際に、かなり大きな問題が発生しています。シリアル化中に、列挙型メンバーが間違った値を取得します。このプロパティは、シリアライズしている XML には存在しないため、NULL または '0' であると予想されますが、代わりに、列挙型で最初に使用可能な値である値 '1' を取得します。

「person.xsd」という XSD があり、次のようになっているとします。

person.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema>
    <xs:import namespace="http://www.somewhere.nl/folder1/1_1/basisschema/schema/1" schemaLocation="basisschema.xsd"/>
    <xs:complexType name="Person">
        <xs:annotation>
            <xs:documentation>Personal information</xs:documentation>
        </xs:annotation>
        <xs:sequence>
            <xs:element name="SomeType" type="ns:CDT_SomeType" minOccurs="0">
                <xs:annotation>
                    <xs:documentation>Some type.</xs:documentation>
                </xs:annotation>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
</xs:schema>

person XSD には、「basisschema.xsd」と呼ばれる基本スキーマが含まれています。そのファイルは次のようになります。

基本スキーマ.xsd

<xs:schema targetNamespace="http://www.somewhere.nl/folder1/1_1/basisschema/schema/1" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ns="http://www.somewhere.nl/folder1/1_1/basisschema/schema/1">
    <xs:complexType name="CDT_SomeType">
        <xs:annotation>
            <xs:documentation>Some type.</xs:documentation>
        </xs:annotation>
        <xs:sequence>
            <xs:element name="SomeEnumElement" type="ns:LDT_SomeEnumElement">
                <xs:annotation>
                    <xs:documentation>Some enum</xs:documentation>
                </xs:annotation>
            </xs:element>
        </xs:sequence>
    </xs:complexType>
</xs:schema>

生成されたコードは次のようになります。

Client.cs

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.6.81.0")]
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://www.somewhere.nl/folder1/1_1/basisschema/schema/1")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://www.somewhere.nl/folder1/1_1/basisschema/schema/1", IsNullable = true)]
public class Client
{
    private CdtSomeType _someType;

    public Client()
    {
        _someType = new CdtSomeType();
    }

    public CdtSomeType SomeType
    {
        get
        {
            return _someType;
        }
        set
        {
            _someType = value;
        }
    }   
}

CdtSomeType.cs

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.6.81.0")]
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace = "http://www.somewhere.nl/folder1/1_1/basisschema/schema/1")]
public class CdtSomeType
{
    private LDTSomeEnumElement _someEnumElement;

    public LDTSomeEnumElement SomeEnumElement
    {
        get
        {
            return _verklaringField;
        }
        set
        {
            _verklaringField = value;
        }
    }
}

Person.cs に 'CdtSomeType' 型のオプション プロパティがあると思っていましたが、そうはなりませんでした。次に、次のコードを使用して、この XSD に一致する XML ファイルをシリアル化します。

using (var reader = new StringReader(message))
{
    var myXmlObject = (Person)serializer.Deserialize(reader);

    //This value isn't available in the XML so I want this to be NULL instead of the default Enum value.
    var test = myXmlObject.SomeType.SomeEnumElement;
}

次に、プロパティ「SomeEnumElement」には、NULL または「0」ではなく、デフォルトの列挙値 (1) があります。これはシリアル化中に発生します。この問題を解決するにはどうすればよいでしょうか?

4

1 に答える 1

0

ここでの問題は、enum プロパティが xsd で nullable でないことです。したがって、xsd 構造体を変更せずに null または 0 を返すことはできません (0 は enum の最初の要素にすることもできます)。XSD2Code は、この enum 要素が親に存在するかどうかを示すプロパティも生成する必要があります。

このようなもの

[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool LDTSomeEnumElementSpecified
    {
        get
        {
            return _verklaringField;
        }
        set
        {
            _verklaringField = value;
        }
    } 

このプロパティに基づいて ([System.Xml.Serialization.XmlIgnoreAttribute()] 属性が必要になることに注意してください)、たとえばこのようにコードで処理できます。

string tmp = deserializedObject.LDTSomeEnumElementSpecified ? deserializedObject.LDTSomeEnumElement.ToString() : String.Empty;
于 2016-01-06T15:38:58.703 に答える