12

我在我的可序列化类中添加了一些可为空的值类型。我使用执行序列化,XmlSerializer但是当值设置为 时null,我得到一个空节点xsi:nil="true"。这是我在Xsi:nil Attribute Binding Support找到的正确行为。

有没有办法关闭此选项,以便在值类型为 时不输出任何内容null

4

6 回答 6

8

我遇到了同样的问题..这是我读到的关于在序列化为 XML 时处理可为空值类型的地方之一:http ://stackoverflow.com/questions/244953/serialize-a-nullable-int

他们提到使用内置模式,例如为可空值类型创建附加属性。就像一个名为

public int? ABC

你必须要么添加要么public bool ShouldSerializeABC() {return ABC.HasValue;} 公开bool ABCSpecified { get { return ABC.HasValue; } }

我只是序列化到 xml 以发送到 sql 存储过程,所以我也避免更改我的类。我正在[not(@xsi:nil)]检查 .value() 查询中的所有可空元素。

于 2010-06-06T12:25:53.590 回答
5

我必须为ShouldSerialize每个可为空的值添加一个方法。

[Serializable]
public class Parent
{
    public int? Element { get; set; }

    public bool ShouldSerializeElement() => Element.HasValue;
}
于 2018-08-31T20:01:17.340 回答
4

我发现 public bool ABCSpecified 是唯一一个与 .NET 4.0 一起工作的。我还必须添加 XmlIgnoreAttribute

这是我在 Web Reference Resource.cs 文件中抑制名为 ABC 的字符串的完整解决方案:

// backing fields
private string abc;
private bool abcSpecified; // Added this - for client code to control its serialization

// serialization of properties
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public string ABC
{
    get
    {
        return this.abc;
    }
    set
    {
        this.abc= value;
    }
}

// Added this entire property procedure
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool ABCSpecified
{
    get
    {
        return this.abcSpecified;
    }
    set
    {
        this.abcSpecified = value;
    }
}
于 2011-04-15T05:23:10.517 回答
1

这可能是最不复杂的答案,但我通过简单的字符串替换为我解决了这个问题。

.Replace(" xsi:nil=\"true\" ", "");

无论如何,我首先要序列化为字符串。我可以稍后保存到文件中。

它使我所有的 XmlWriterSettings 保持不变。我发现她搞砸的另一种解决方案:)

    private static string Serialize<T>(T details)
    {
        var serializer = new XmlSerializer(typeof(T));
        using (var ms = new MemoryStream())
        {
            var settings = new XmlWriterSettings
            {
                Encoding = Encoding.GetEncoding("ISO-8859-1"),
                NewLineChars = Environment.NewLine,
                ConformanceLevel = ConformanceLevel.Document,
                Indent = true,
                OmitXmlDeclaration = true
            };

            using (var writer = XmlWriter.Create(ms, settings))
            {
                serializer.Serialize(writer, details);
                return Encoding.UTF8.GetString(ms.ToArray()).Replace(" xsi:nil=\"true\" ", "");
            }
        }
    }
于 2018-02-28T14:17:07.217 回答
1

SpecifiedShouldSerialize等所有元方法只是 Microsoft .Net XML 结构的糟糕编程设计。如果您无法直接访问要序列化的类,情况会变得更加复杂。

在他们的序列化方法中,他们应该只添加一个像“ignoreNullable”这样的属性。

我当前的解决方法是序列化 xml,然后使用以下函数删除所有具有nil="true"的节点。

/// <summary>
/// Remove optional nullabe xml nodes from given xml string using given scheme prefix.
/// 
/// In other words all nodes that have 'xsi:nil="true"' are being removed from document.
/// 
/// If prefix 'xmlns:xsi' is not found in root element namespace input xml content is returned.
/// </summary>
/// <param name="xmlContent"></param>
/// <param name="schemePrefix">Scheme location prefix</param>
/// <returns></returns>
public static String RemoveNilTrue(String xmlContent, String schemePrefix = "xsi")
{
    XmlDocument xmlDocument = new XmlDocument();
    xmlDocument.LoadXml(xmlContent);

    XmlNamespaceManager nsMgr = new XmlNamespaceManager(xmlDocument.NameTable);

    bool schemeExist = false;

    foreach (XmlAttribute attr in xmlDocument.DocumentElement.Attributes)
    {
        if (attr.Prefix.Equals("xmlns", StringComparison.InvariantCultureIgnoreCase)
            && attr.LocalName.Equals(schemePrefix, StringComparison.InvariantCultureIgnoreCase))
        {
            nsMgr.AddNamespace(attr.LocalName, attr.Value);
            schemeExist = true;
            break;
        }
    }

    // scheme exists - remove nodes
    if (schemeExist)
    {
        XmlNodeList xmlNodeList = xmlDocument.SelectNodes("//*[@" + schemePrefix + ":nil='true']", nsMgr);

        foreach (XmlNode xmlNode in xmlNodeList)
            xmlNode.ParentNode.RemoveChild(xmlNode);

        return xmlDocument.InnerXml;
    }
    else
        return xmlContent;
}
于 2017-11-28T16:22:52.013 回答
0

我是这样完成的:

    private bool retentionPeriodSpecified;
    private Nullable<int> retentionPeriod;

    [XmlElement(ElementName = "retentionPeriod", IsNullable = true, Order = 14)]
    public Nullable<int> RetentionPeriod { get => retentionPeriod; set => retentionPeriod = value; }

    [System.Xml.Serialization.XmlIgnore()]
    public bool RetentionPeriodSpecified
    {
        get { return !(retentionPeriod is null); }
    }
于 2019-07-11T15:37:27.810 回答