0

How do I remove the comment at the bottom of created json string?

I am attempting to use Json.net to convert xml to json. Specifically, I am fetching data from the Zillow API which returns XML which I need to deliver to a web browser as a json string. Thanks to questions/answers found on this site, I have been able to use json.net in my c# page to maket the conversion, BUT...

I use the following to convert my xml to json:

public String GetJson(XmlDocument xml) { return Newtonsoft.Json.JsonConvert.SerializeObject(xml); } 

I successfully get a json formatted String, but this comment is added at the bottom of the json (seems to be a timestamp).

{ ... json-formatted output... /* H:011 T:134ms S:1206 R:Tue May 02 07:59:03 PDT 2017 B:5.0.42642-master.3acb9f9~hotfix_pre.b72ccda */ } 

I have checked the original xml to verify the comment is not there, so I have concluded it is added by json.net. I have searched this site - and Google - for info on this, but I am not finding the right search tokens to find any mention of this comment.

Thanks!

1
  • 1
    We need a minimal reproducible example showing how you got the XML and what its string value is. Commented May 2, 2017 at 21:32

1 Answer 1

4

There is no way that Json.NET will insert a hardcoded comment when serializing an XmlDocument -- there simply isn't any logic to do this in XmlNodeConverter. The only time XmlNodeConverter will write a comment is if an XML node of type XmlNodeType.Comment was actually encountered in the XML DOM hierarchy, at around line 1502 in the source code:

 case XmlNodeType.Comment: if (writePropertyName) { writer.WriteComment(node.Value); } break; 

Thus there are only a few ways such a comment string could have gotten added to your JSON output, including:

  1. There might actually be comments in your XML, added by the Zillow API or by your own app somewhere in its code stack. For instance, given the following 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 will generate the following 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 */ } 
  2. Somewhere in your code stack, your app might have installed its own version of XmlNodeConverter in JsonConvert.DefaultSettings that inserts comments into the output. For instance, given the following global converter:

    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"); } } 

    The JSON generated will contain extra comments:

    { "?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*/ 
  3. You might be using your own custom build of Json.NET with a customized version of XmlNodeConverter.

Sample fiddle demonstrating the first two possibilities.

If you actually have comment nodes in your XML, you can strip them by following one of the suggestions in How to remove all comment tags from XmlDocument or any number of similar questions. If you have a global converter installed, you can supersede it by manually allocating an XmlNodeConverter and passing it to JsonConvert.SerializeObject().

To handle these two cases, your GetJson() might become:

 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); } 

Sample fiddle.

If you are using your own custom build of Json.NET, you would need to investigate and fix why this is happening.

If for whatever reason you cannot modify the incoming XmlDocument (or cannot fix your custom build of Json.NET) you could subclass JsonTextWriter and override WriteComment (and possibly WriteCommentAsync though that's not needed here) and make them do nothing:

public class NoCommentJsonTextWriter : JsonTextWriter { public NoCommentJsonTextWriter(TextWriter writer) : base(writer) { } public override void WriteComment(string text) { } } 

Then use it as follows:

 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(); } 

Sample fiddle.

Sign up to request clarification or add additional context in comments.

1 Comment

It was item 1; the comment was in the xml, but was not in the same spot in the json (at least as I viewed the xml in a console window.) Thanks for the thorough answer, @dbc, you actually helped me with another issue with this description.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.