Json.NET 6.0 Release 3 的发行说明指出
更改 - 空白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);
Run Code Online (Sandbox Code Playgroud)
我期望
"empty":"", "space":" ", "null":{"@xsi:nil":"true"}
Run Code Online (Sandbox Code Playgroud)
但得到了
"empty":null, "space":"", "null":{"@xsi:nil":"true"}
Run Code Online (Sandbox Code Playgroud)
丢失的空间现在不是问题,但我真的希望将空XML元素序列化为""而不是null.这可能吗?
如果以下列格式编写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>";
Run Code Online (Sandbox Code Playgroud)
您可以注意到要将序列化为空字符串的节点写为<empty></empty>而不是<empty />.
问题在于JSON.NET用于将xml节点序列化为json,它使用XmlNodeConverter在其SerializeNode方法中检查类IsEmpty属性的XmlElement类.你可以阅读更多有关此属性在这里.上述方法的代码段决定是否null序列化空字符串,如下所示:
if (element.IsEmpty)
writer.WriteNull();
else
writer.WriteValue(string.Empty);
Run Code Online (Sandbox Code Playgroud)
当xml片段是自闭(<empty/>)时,该IsEmpty属性返回true,并且在json字符串中写入null,否则(<empty></empty>),它返回false并且在json字符串中写入string.empty.
更新1:
此更新应解决此处描述的问题.(该答案的评论中也提供了该链接).
为了能够序列化没有值的属性<empty></empty>而不是<empty/>,我们应该执行自定义xml序列化,因此Serializetest该类(在上面的链接中可用)应如下所示:
[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();
}
}
Run Code Online (Sandbox Code Playgroud)
然后主要方法:
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.
Run Code Online (Sandbox Code Playgroud)