使用xsd.exe访问从xml生成的类项

时间:2017-10-20 13:04:02

标签: c# xml xsd xsd.exe

好吧,我生成了一些类来处理一些使用.net xsd.exe的xml文件,到目前为止没问题。我可以使用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;
        }
    }
}

我可以访问公共对象“Item”,但我怎样才能更深入? 当我到达时... Pis我只能访问“Item”。

上述项目中的一个要素:

 /// <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;
        }
    }
}

我需要访问TNFeInfNFeDetImpostoPISPISAliq类中的公共字符串vBC,pPis和其他内容。

以下是用于生成类的一段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>

1 个答案:

答案 0 :(得分:2)

因此,您拥有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;
        }
    }

    // ...
}

另请参阅Dilemma with XSD, Generics and C# ClassesXSD.exe - How to initialize a type created from xs:choice