Элемент класса доступа, сгенерированный из xml с помощью xsd.exe

Что ж, я создал несколько классов для работы с некоторыми файлами xml с помощью .net xsd.exe, пока проблем не возникло. Я могу читать и десериализовать классы с помощью XmlSerializaer и без проблем читать большинство итенов.

Моя проблема заключается в том, что я прибываю в некоторые места, например, ниже:

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.portalfiscal.inf.br/nfe")]
public partial class TNFeInfNFeDetImpostoPIS
{

    private object itemField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("PISAliq", typeof(TNFeInfNFeDetImpostoPISPISAliq))]
    [System.Xml.Serialization.XmlElementAttribute("PISNT", typeof(TNFeInfNFeDetImpostoPISPISNT))]
    [System.Xml.Serialization.XmlElementAttribute("PISOutr", typeof(TNFeInfNFeDetImpostoPISPISOutr))]
    [System.Xml.Serialization.XmlElementAttribute("PISQtde", typeof(TNFeInfNFeDetImpostoPISPISQtde))]
    public object Item
    {
        get
        {
            return this.itemField;
        }
        set
        {
            this.itemField = value;
        }
    }
}

Я могу получить доступ к общедоступному объекту «Элемент», но как мне углубиться? И когда я добираюсь до ...Pis, я могу получить доступ только к «Элементу».

Один из элементов из пункта выше:

 /// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.6.1055.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://www.portalfiscal.inf.br/nfe")]
public partial class TNFeInfNFeDetImpostoPISPISAliq
{

    private TNFeInfNFeDetImpostoPISPISAliqCST cSTField;

    private string vBCField;

    private string pPISField;

    private string vPISField;

    /// <remarks/>
    public TNFeInfNFeDetImpostoPISPISAliqCST CST
    {
        get
        {
            return this.cSTField;
        }
        set
        {
            this.cSTField = value;
        }
    }

    /// <remarks/>
    public string vBC
    {
        get
        {
            return this.vBCField;
        }
        set
        {
            this.vBCField = value;
        }
    }

    /// <remarks/>
    public string pPIS
    {
        get
        {
            return this.pPISField;
        }
        set
        {
            this.pPISField = value;
        }
    }

    /// <remarks/>
    public string vPIS
    {
        get
        {
            return this.vPISField;
        }
        set
        {
            this.vPISField = value;
        }
    }
}

Мне нужно было бы получить доступ к общедоступной строке vBC, pPis и другим внутри класса TNFeInfNFeDetImpostoPISPISAliq.

Вот фрагмент XML, используемый для генерации классов (просто удалена документация для экономии места):

<xs:element minOccurs = "0" name="PIS">
    <xs:annotation>
        <xs:documentation>whatever</xs:documentation>
    </xs:annotation>
    <xs:complexType>
        <xs:choice>
            <xs:element name = "PISAliq" >
                <xs:annotation>
                    <xs:documentation>whatever;</xs:documentation>
                </xs:annotation>
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name = "CST" >
                            <xs:annotation>
                                <xs:documentation>whatever;</xs:documentation>
                            </xs:annotation>
                            <xs:simpleType>
                                <xs:restriction base="xs:string">
                                    <xs:whiteSpace value = "preserve" />
                                    <xs:enumeration value = "01" />
                                    <xs:enumeration value = "02" />
                                </xs:restriction>
                            </xs:simpleType>
                        </xs:element>
                        <xs:element name = "vBC" type="TDec_1302">
                            <xs:annotation>
                                <xs:documentation>whatever</xs:documentation>
                            </xs:annotation>
                        </xs:element>

person GAltelino    schedule 20.10.2017    source источник
comment
Пожалуйста, покажите нам, как определяются соответствующие типы в XSD.   -  person dymanoid    schedule 20.10.2017


Ответы (1)


Итак, у вас есть свойство Item типа object, которое будет десериализовано либо в TNFeInfNFeDetImpostoPISPISAliq, либо в любой из трех других типов, отмеченных типами [XmlElement("PIS...", typeof(...)].

Затем вам нужно определить его тип во время выполнения:

var deserializedObjectAliq = deserialized.Item as TNFeInfNFeDetImpostoPISPISAliq;
if (deserializedObjectAliq != null)
{
    deserializedObjectAliq.WhatEver
}

var deserializedObjectNT = deserialized.Item as TNFeInfNFeDetImpostoPISPISNT;
if (deserializedObjectNT != null)
{
    deserializedObjectNT.WhatEver
}

// ...

Вам лучше сгенерировать элемент для <xsd:choice>, а не хранить его в object, чтобы вы могли просто проверить if (deserializedObject.Aliq != null) { ... }.

Я не уверен, можно ли вместо этого указать xsd.exe генерировать эти элементы. Если это не так, вы можете создать разделяемый класс, который делает это:

public partial class TNFeInfNFeDetImpostoPIS
{
    public TNFeInfNFeDetImpostoPISPISAliq Aliq
    {
        get
        {
            return Item as TNFeInfNFeDetImpostoPISPISAliq;
        }
    }       

    public TNFeInfNFeDetImpostoPISPISNT NT
    {
        get
        {
            return Item as TNFeInfNFeDetImpostoPISPISNT;
        }
    }

    // ...
}

См. также Дилемма с классами XSD, Generics и C# и XSD.exe - Как инициализировать тип, созданный из xs: выбор.

person CodeCaster    schedule 20.10.2017
comment
tks, лучший способ и для меня, просто нужно было использовать много циклов для каждого. - person GAltelino; 08.11.2017