使用 xsd.exe 访问从 xml 生成的 class 项目
Access class item generated from xml using xsd.exe
好吧,我使用 .net xsd.exe 生成了一些 classes 来处理一些 xml 文件,目前没问题。我可以使用 XmlSerializaer 读取和反序列化 classes,并且可以毫无问题地读取大部分内容。
我的问题是当我到达某些地方时,例如下面的地方:
/// <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;
}
}
}
我可以访问 public 对象 "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 中的 public 字符串 vBC、pPis 和其他字符串 class。
这里是用来生成classes的XML的一部分(只是为了保存space删除了文档):
<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>
所以你有一个 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
生成这些成员。如果没有,您可以创建一个部分 class 来执行此操作:
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# Classes and 。
好吧,我使用 .net xsd.exe 生成了一些 classes 来处理一些 xml 文件,目前没问题。我可以使用 XmlSerializaer 读取和反序列化 classes,并且可以毫无问题地读取大部分内容。
我的问题是当我到达某些地方时,例如下面的地方:
/// <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;
}
}
}
我可以访问 public 对象 "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 中的 public 字符串 vBC、pPis 和其他字符串 class。
这里是用来生成classes的XML的一部分(只是为了保存space删除了文档):
<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>
所以你有一个 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
生成这些成员。如果没有,您可以创建一个部分 class 来执行此操作:
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# Classes and