如何让Json.NET将空XML元素序列化为空字符串

时间:2014-06-23 14:04:19

标签: c# json json.net

Json.NET 6.0 Release 3的release notes状态

  

更改 - 空白XML元素将被写为空字符串   为null

但这不是我的经历。

var xmlText = @"<document xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" Version=""1.1"">
                    <empty/>
                    <space> </space>
                    <null xsi:nil=""true""/>
                </document>";
var doc = new XmlDocument();
doc.LoadXml(xmlText);
var jsonText = JsonConvert.SerializeXmlNode(doc);

我期待

"empty":"", "space":" ", "null":{"@xsi:nil":"true"}

但得到了

"empty":null, "space":"", "null":{"@xsi:nil":"true"}

现在丢失的空间不是问题,但我真的希望将空的XML元素序列化为“”而不是null。这可能吗?

1 个答案:

答案 0 :(得分:5)

如果您使用以下格式编写xml,您将获得所需内容:

var xmlText = @"<document xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" Version=""1.1"">
                <empty></empty>
                <space> </space>
                <null xsi:nil=""true""/>
            </document>";

您可以注意到要将序列化为空字符串的节点写为<empty></empty>而不是<empty />

用于将xml节点序列化为json的JSON.NET使用XmlNodeConverter类,SerializeNode方法在IsEmpty方法中检查XmlElement null属性类。您可以阅读有关此属性的更多信息here。上述方法的代码段决定if (element.IsEmpty) writer.WriteNull(); else writer.WriteValue(string.Empty); 或空字符串是否已序列化,如下所示:

<empty/>

当xml片段自闭(IsEmpty)时,<empty></empty>属性返回true,并且在json字符串中写入null,否则(<empty></empty>),它返回false并且string.empty写在json字符串中。

更新1:

此更新应解决here所述的问题。 (该答案的评论中也提供了该链接。)

为了能够序列化没有<empty/>而不是Serializetest的值的属性,我们应该执行自定义xml序列化,因此[Serializable] public class Serializetest : IXmlSerializable { public Serializetest() { Empty = string.Empty; } public string Empty { get; set; } public XmlSchema GetSchema() { return null; } public void ReadXml(XmlReader reader) { throw new NotImplementedException(); } public void WriteXml(XmlWriter writer) { writer.WriteStartElement("Empty"); writer.WriteValue(Empty); writer.WriteEndElement(); } } 类(链接中可用)上面)应该是这样的:

var serializetest = new Serializetest();
string xmlText;

var serializer = new XmlSerializer(typeof(Serializetest));
using (var textWriter = new StringWriter())
{
    using (var xmlWriter = XmlWriter.Create(textWriter))
    {
        serializer.Serialize(xmlWriter, serializetest);
    }

    xmlText = textWriter.ToString();
}

var doc = new XmlDocument();
doc.LoadXml(xmlText);
var jsonText = JsonConvert.SerializeXmlNode(doc);

var json = JObject.Parse(jsonText);
var empty = (string)json.SelectToken("Serializetest.Empty");
// This should return empty string instead of null.

然后主要方法:

{{1}}