use*_*872 2 c# class xml-attribute xmlserializer xmlignore
我试图使用XmlAttributeOverrides来控制哪些类属性在序列化后显示在xml中。它适用于“根”类上的属性,但不适用于嵌套属性。这是一个简单的示例,以说明我要完成的工作。
我的班级层次结构如下:
public class Main
{
public string Name { get; set; }
public Location Address { get; set; }
}
public class Location
{
public string StreetAddress { get; set; }
public Contact ContactInfo{ get; set; }
}
public class Contact
{
public string PhoneNumber { get; set; }
public string EmailAddr { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
当我序列化Main()时,我得到如下信息:
<Main>
<Name></Name>
<Address>
<StreetAddress></StreetAddress>
<ContactInfo>
<PhoneNumber></PhoneNumber>
<EmailAddr></EmailAddr>
</ContactInfo>
</Address>
</Main>
Run Code Online (Sandbox Code Playgroud)
我所能做的就是通过使用以下命令来避免显示名称或地址:
XmlAttributeOverrides overrides = new XmlAttributeOverrides();
XmlAttributes attribs = new XmlAttributes();
attribs.XmlIgnore = true;
attribs.XmlElements.Add(new XmlElementAttribute("Address"));
overrides.Add(typeof(Main), "Address", attribs);
xs = new XmlSerializer(typeof(Main), overrides);
Run Code Online (Sandbox Code Playgroud)
我还需要能够做的就是保持Main.Address.ContactInfo被序列化SOMETIMES(如果它是空的)。我尝试了以下方法,但它们没有起作用:
XmlAttributeOverrides overrides = new XmlAttributeOverrides();
XmlAttributes attribs = new XmlAttributes();
attribs.XmlIgnore = true;
attribs.XmlElements.Add(new XmlElementAttribute("ContactInfo "));
overrides.Add(typeof(Contact), "ContactInfo ", attribs);
xs = new XmlSerializer(typeof(Contact), overrides);
Run Code Online (Sandbox Code Playgroud)
和...
XmlAttributeOverrides overrides = new XmlAttributeOverrides();
XmlAttributes attribs = new XmlAttributes();
attribs.XmlIgnore = true;
attribs.XmlElements.Add(new XmlElementAttribute("ContactInfo "));
overrides.Add(typeof(Main.Address.ContactInfo), "ContactInfo ", attribs);
xs = new XmlSerializer(typeof(Main.Address.ContactInfo), overrides);
Run Code Online (Sandbox Code Playgroud)
实际上,我已经做了很多尝试,包括使用XPath语句指定要定位的属性名称,但又不想用失败的尝试来填充此页面。通过这种方法我问的可能吗?
有更简单的方法可以实现您想要的目标。
您说您想要实现的是/Main/Address/ContactInfo如果不包含数据则不序列化ContactInfo。
如果您保持代码不变,它将序列化 Main 的所有属性,无论它们是否为 null 或空。第一步,您需要XmlSerializerNamespaces向所有对象添加一个属性,否则每个空对象将被序列化为<myElement xsi:nil="true" />. 这可以很容易地完成,如下所示:
public MyXmlElement
{
public MyXmlElement()
{
// Add your own default namespace to your type to prevet xsi:* and xsd:*
// attributes from being generated.
this._namespaces = new XmlSerializerNamespaces(new XmlQualifiedName[] {
new XmlQualifiedName(string.Empty, "urn:myDefaultNamespace") });
}
[XmlElement("MyNullableProperty", IsNullable=false)]
public string MyNullableProperty
{
get
{
return string.IsNullOrWhiteSpace(this._myNullableProperty) ?
null : this._myNullableProperty;
}
set { this._myNullableProperty = value; }
}
[XmlNamespacesDeclaration]
public XmlSerializerNamespaces Namespaces { get { return this._namespaces; } }
private XmlSerializerNamespaces _namespaces;
}
Run Code Online (Sandbox Code Playgroud)
上面的代码声明了一个Namespaces属性,该属性保存 XML 对象的所有相关命名空间。您应该为所有对象提供默认名称空间(根据上面的代码建模)。这可以防止在序列化对象时输出xsi:*和属性。xsd:*另外,使用 指定该元素不可为空System.Xml.Serialization.XmlElementAttribute。
此外,通过检查string.IsNullOrWhiteSpace(someVariable)并返回 null,完成上述操作后该属性将不会被序列化。
因此,将这些内容整合到您的Location班级中:
public class Location
{
// You should have a public default constructor on all types for (de)sereialization.
public Location()
{
this._namespaces = new XmlSerializerNamespaces(new XmlQualifiedName[] {
new XmlQualifiedName(string.Empty, "urn:myNamespace"); // Default namespace -- prevents xsi:nil="true" from being generated, as well as xsd:* attributes.
});
}
public string StreetAddress
{
// If you don't want <StreetAddress xsi:nil="true" /> to be generated, do this:
get { return string.IsNullOrEmpty(this._streetAddress) ? null : this._streetAddress; }
// Otherwise, if you don't care, just do
// get;
// Only need to implement setter if you don't want xsi:nil="true" to be generated.
set { this._streetAddress = value; }
// Otherwise, just
// set;
}
private string _streetAddress;
[XmlElement("ContactInfo", IsNullable=false)]
public Contact ContactInfo
{
// You must definitely do this to prevent the output of ContactInfo element
// when it's null (i.e. contains no data)
get
{
if (this._contactInfo != null && string.IsNullOrWhiteSpace(this._contactInfo.PhoneNumber) && string.IsNullOrWhiteSpace(this._contactInfo.EmailAddr))
return null;
return this._contactInfo;
}
set { this._contactInfo = value; }
}
private Contact _contactInfo;
[XmlNamespacesDeclarations]
public XmlSerializerNamespaces Namespaces
{
get { return this._namespaces; }
}
private XmlSerializerNamespaces _namespaces;
}
Run Code Online (Sandbox Code Playgroud)
通过对Location类进行这些更改,ContactInfo当所有属性都不为 null、空或空格或者本身为 null 时,空属性不应再序列化为 XML ContactInfo。
您应该对其他对象进行类似的更改。
有关 .NET XML 序列化的更多信息,请参阅我的其他 stackoverflow 答案:
小智 5
对于其他尝试使用XmlAttributeOverrides进行此操作的人来说,@ user1437872非常接近寻找答案。这是忽略嵌套元素ContactInfo的替代代码。
XmlAttributeOverrides overrides = new XmlAttributeOverrides();
XmlAttributes attribs = new XmlAttributes();
attribs.XmlIgnore = true;
attribs.XmlElements.Add(new XmlElementAttribute("ContactInfo"));
overrides.Add(typeof(Address), "ContactInfo ", attribs);
xs = new XmlSerializer(typeof(Main), overrides);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
8371 次 |
| 最近记录: |