使用 xsi:nil="true" 删除 xml 元素C#序列化 [英] Remove xml element with xsi:nil="true" C# serialization

查看:79
本文介绍了使用 xsi:nil="true" 删除 xml 元素C#序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 XML,它有一些值,有时可能有 null 值,如下所示: 我不希望在 XML 中列出 null 的节点!元素在类中设置 IsNullable = true.任何建议,因为我已经在谷歌尝试了很多东西......没有任何帮助!

I have an XML which has some values and at times there can be null values as shown below: I do not want the nodes with null listed at all in the XML! The elements are set IsNullable = true in the class. Any suggestions as I have tried out many stuffs in Google.. nothing helped!

<?xml version="1.0" encoding="utf-8"?>
<Materials>
  <Material>
    <MaterialName>ABC</MaterialName>
    <Weight Value="0.303">
      <Weight_A xsi:nil="true" />
      <Weight_B xsi:nil="true" />
    </Weight>
    <Density Value="800">
      <Density_A xsi:nil="true" />
      <Density_B xsi:nil="true" />
    </Density>
    <Volume Value="8771.427" />
  </Material>
  <Material>
    <MaterialName>ABC</MaterialName>
    <Weight>
      <V5_Weight>2.009</V5_Weight>
      <V6_Weight>1.3318154561904</V6_Weight>
    </Weight>
    <Density>
      <V5_density>1000</V5_density>
      <V6_density>663</V6_density>
    </Density>
    <Volume Value="2008771.427" />
  </Material>
</Materials>

类结构如下:

[XmlRoot(ElementName = "Weight")]
public class Weight
{
    [XmlElement(ElementName = "Weight_A", IsNullable = true)]
    public string Weight_A { get; set; }

    [XmlElement(ElementName = "Weight_B", IsNullable = true)]
    public string Weight_B { get; set; }

    [XmlAttribute(AttributeName = "Value")]
    public string Value { get; set; }

}

[XmlRoot(ElementName = "Density")]
public class Density
{
    [XmlElement(ElementName = "Density_A", IsNullable = true)]
    public string Density_A { get; set; }
    [XmlElement(ElementName = "Density_B", IsNullable = true)]
    public string Density_B { get; set; }

    [XmlAttribute(AttributeName = "Value")]
    public string Value { get; set; }
}

[XmlRoot(ElementName = "Volume")]
public class Volume
{
    [XmlElement(ElementName = "Volume_A")]
    public string Volume_A { get; set; }
    [XmlElement(ElementName = "Volume_B")]
    public string Volume_B { get; set; }

    [XmlAttribute(AttributeName = "Value")]
    public string Value { get; set; }
}

[XmlRoot(ElementName = "Material")]
public class Material
{
    [XmlElement(ElementName = "MaterialName")]
    public string MaterialName { get; set; }
    [XmlElement(ElementName = "Weight")]
    public Weight Weight { get; set; }

    [XmlElement(ElementName = "Density")]
    public Density Density { get; set; }
    [XmlElement(ElementName = "Volume")]
    public Volume Volume { get; set; }
}

[XmlRoot(ElementName = "Materials")]
public class Materials
{
    [XmlElement(ElementName = "Material")]
    public List<Material> Material { get; set; }
}

推荐答案

基本问题是您设置了 XmlElementAttribute.IsNullable = true.来自 文档:

The basic issue is that you have set XmlElementAttribute.IsNullable = true. From the docs:

获取或设置一个值,该值指示 XmlSerializer 必须将设置为 null 的成员序列化为空标记,并将 xsi:nil 属性设置为 true.

Gets or sets a value that indicates whether the XmlSerializer must serialize a member that is set to null as an empty tag with the xsi:nil attribute set to true.

因此理论上您可以将其设置为 false(或根本不设置)和 xsi:nil 属性不会为空值发出:

Thus in theory you could just set it to be false (or don't set it at all) and the xsi:nil attributes will not be emitted for null values:

[XmlRoot(ElementName = "Weight")]
public class Weight
{
    [XmlElement(ElementName = "Weight_A" /*, IsNullable = true*/)]
    public string Weight_A { get; set; }
    [XmlElement(ElementName = "Weight_B" /*, IsNullable = true*/)]
    public string Weight_B { get; set; }

    [XmlAttribute(AttributeName = "Value")]
    public string Value { get; set; }
}

[XmlRoot(ElementName = "Density")]
public class Density
{
    [XmlElement(ElementName = "Density_A"/*, IsNullable = true*/)]
    public string Density_A { get; set; }
    [XmlElement(ElementName = "Density_B"/*, IsNullable = true*/)]
    public string Density_B { get; set; }

    [XmlAttribute(AttributeName = "Value")]
    public string Value { get; set; }
}

但是,如果这样做,您可能会在反序列化遗留 XML 文件时遇到问题,即字符串值的 xsi:nil 元素现在将反序列化为空字符串而不是 null 字符串.(演示小提琴 #1 此处.)如果这成为一个问题,您必须保留 XmlElementAttribute.IsNullable= true 设置,而是使用此答案中描述的条件序列化模式之一来ShouldSerialize*() vs *Specified Conditional Serialization Pattern:

However, if you do that, you may encounter a problem deserializing legacy XML files, namely that string-valued xsi:nil elements will now get deserialized as empty strings rather than null strings. (Demo fiddle #1 here.) If this becomes a problem, you must leave the XmlElementAttribute.IsNullable = true setting and instead use the one of the conditional serialization patterns described in this answer to ShouldSerialize*() vs *Specified Conditional Serialization Pattern:

[XmlRoot(ElementName = "Weight")]
public class Weight
{
    [XmlElement(ElementName = "Weight_A", IsNullable = true)]
    public string Weight_A { get; set; }

    public bool ShouldSerializeWeight_A() { return Weight_A != null; }

    [XmlElement(ElementName = "Weight_B", IsNullable = true)]
    public string Weight_B { get; set; }

    public bool ShouldSerializeWeight_B() { return Weight_B != null; }

    [XmlAttribute(AttributeName = "Value")]
    public string Value { get; set; }
}

[XmlRoot(ElementName = "Density")]
public class Density
{
    [XmlElement(ElementName = "Density_A", IsNullable = true)]
    public string Density_A { get; set; }

    public bool ShouldSerializeDensity_A() { return Density_A != null; }

    [XmlElement(ElementName = "Density_B", IsNullable = true)]
    public string Density_B { get; set; }

    public bool ShouldSerializeDensity_B() { return Density_B != null; }

    [XmlAttribute(AttributeName = "Value")]
    public string Value { get; set; }
}

完成此操作后,<NodeName xsi:nil="true"/> 元素将在反序列化期间映射到 null 字符串,并在序列化期间完全跳过.

Having done this, the <NodeName xsi:nil="true" /> elements will get mapped to a null string during deserialization and skipped entirely during serialization.

注意事项:

  • 您的 XML 格式不正确.它缺少 xsi: 命名空间前缀的定义,可能是因为它是某个较大文档的片段.这个答案假设它应该是:

  • Your XML is not well-formed. It lacks a definition for the xsi: namespace prefix, perhaps because it's a fragment of some larger document. This answer assumes it should be:

<Materials 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

  • 某些元素根本没有绑定到您的 c# 数据模型,包括:

  • Some elements are not bound to your c# data model at all including:

    <V5_Weight>2.009</V5_Weight>
    <V6_Weight>1.3318154561904</V6_Weight>
    

    <V5_density>1000</V5_density>
    <V6_density>663</V6_density>
    

    这个答案并不试图解决这个问题(如果它实际上是一个问题).

    This answer does not attempt to address this problem (if it is, in fact, a problem).

    示例小提琴 #2 此处.

    这篇关于使用 xsi:nil="true" 删除 xml 元素C#序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆