Доступ к элементу класса, сгенерированному из 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;
}
}
}
Я могу получить доступ к общедоступному объекту "Предмет", но как я могу пойти глубже? И когда я добираюсь до... Пис, я могу получить доступ только к "Предмету".
Один из элементов из пункта выше:
/// <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>
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: choice.