在序列化XmlDocument 时,Json.NET 无法插入硬编码的comment——XmlNodeConverter 中根本没有任何逻辑可以做到这一点。 XmlNodeConverter 唯一会写注释的情况是,如果在 XML DOM 层次结构中实际遇到了 XmlNodeType.Comment 类型的 XML 节点,在源代码中的 1502 行附近:
case XmlNodeType.Comment:
if (writePropertyName)
{
writer.WriteComment(node.Value);
}
break;
因此,只有几种方法可以将此类注释字符串添加到您的 JSON 输出中,包括:
-
在您的 XML 中实际上可能有 comments,由 Zillow API 或您自己的应用程序在其代码堆栈中的某个位置添加。例如,给定以下 XML:
<?xml version="1.0" encoding="utf-8" ?>
<root>
<childNode>
<innerChildNode>Some Text</innerChildNode>
</childNode>
<!-- H:011 T:134ms S:1206 R:Tue May 02 07:59:03 PDT 2017 B:5.0.42642-master.3acb9f9~hotfix_pre.b72ccda -->
</root>
<!-- H:011 T:134ms S:1206 R:Tue May 02 07:59:03 PDT 2017 B:5.0.42642-master.3acb9f9~hotfix_pre.b72ccda -->
Json.NET 将生成以下 JSON:
{
"?xml": {
"@version": "1.0",
"@encoding": "utf-8"
},
"root": {
"childNode": {
"innerChildNode": "Some Text"
}/* H:011 T:134ms S:1206 R:Tue May 02 07:59:03 PDT 2017 B:5.0.42642-master.3acb9f9~hotfix_pre.b72ccda */
}/* H:011 T:134ms S:1206 R:Tue May 02 07:59:03 PDT 2017 B:5.0.42642-master.3acb9f9~hotfix_pre.b72ccda */
}
-
在您的代码堆栈中的某个位置,您的应用可能在JsonConvert.DefaultSettings 中安装了自己的XmlNodeConverter 版本,该版本将cmets 插入到输出中。例如,给定以下全局转换器:
JsonConvert.DefaultSettings = () => new JsonSerializerSettings
{
Converters = { new FixedXmlNodeConverter() },
};
public class FixedXmlNodeConverter : Newtonsoft.Json.Converters.XmlNodeConverter
{
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
base.WriteJson(writer, value, serializer);
writer.WriteComment("Global Comment: H:011 T:134ms S:1206 R:Tue May 02 07:59:03 PDT 2017 B:5.0.42642-master.3acb9f9~hotfix_pre.b72ccda");
}
}
生成的 JSON 将包含额外的 cmets:
{
"?xml": {
"@version": "1.0",
"@encoding": "utf-8"
},
"root": {
"childNode": {
"innerChildNode": "Some Text"
}/* H:011 T:134ms S:1206 R:Tue May 02 07:59:03 PDT 2017 B:5.0.42642-master.3acb9f9~hotfix_pre.b72ccda */
}/* H:011 T:134ms S:1206 R:Tue May 02 07:59:03 PDT 2017 B:5.0.42642-master.3acb9f9~hotfix_pre.b72ccda */
}/*Global Comment: H:011 T:134ms S:1206 R:Tue May 02 07:59:03 PDT 2017 B:5.0.42642-master.3acb9f9~hotfix_pre.b72ccda*/
您可能正在使用自己的自定义 Json.NET 构建和自定义版本的 XmlNodeConverter。
示例fiddle 展示了前两种可能性。
如果您的 XML 中确实有注释节点,您可以按照How to remove all comment tags from XmlDocument 中的建议之一或任何数量的类似问题来去除它们。如果您安装了全局转换器,则可以通过手动分配XmlNodeConverter 并将其传递给JsonConvert.SerializeObject() 来取代它。
要处理这两种情况,您的GetJson() 可能会变成:
public String GetJson(XmlDocument xml)
{
XmlNodeList list = xml.SelectNodes("//comment()");
foreach(XmlNode node in list)
{
node.ParentNode.RemoveChild(node);
}
var converter = new Newtonsoft.Json.Converters.XmlNodeConverter();
// Use Newtonsoft.Json.Formatting.None in your production code
return Newtonsoft.Json.JsonConvert.SerializeObject(xml, Newtonsoft.Json.Formatting.Indented, converter);
}
示例fiddle。
如果您使用自己的 Json.NET 自定义构建,则需要调查并解决发生这种情况的原因。
如果由于某种原因您无法修改传入的 XmlDocument(或无法修复您的 Json.NET 的自定义构建),您可以继承 JsonTextWriter 并覆盖 WriteComment(可能还有 WriteCommentAsync,尽管这里不需要)让他们什么都不做:
public class NoCommentJsonTextWriter : JsonTextWriter
{
public NoCommentJsonTextWriter(TextWriter writer)
: base(writer)
{
}
public override void WriteComment(string text)
{
}
}
然后按如下方式使用:
public String GetJson(XmlDocument xml)
{
var sb = new StringBuilder();
using (var textWriter = new StringWriter(sb))
// Use Newtonsoft.Json.Formatting.None in your production code
using (var writer = new NoCommentJsonTextWriter(textWriter) { Formatting = Newtonsoft.Json.Formatting.Indented })
{
JsonSerializer.CreateDefault().Serialize(writer, xml);
}
return sb.ToString();
}
示例fiddle。