A quick search around on Google, and I couldn't find what I thought was pretty basic function in C#. I mean, someone, somewhere else in the world needed to be able to do this. The Javascript serializer would work if I had an object to start with, but in my case, there wasn't an object just a string. So I wrote a basic formatter for presentation of JSon data. It's not all that impressive, but it works, and creates presentable data that the user can view and work with.
I also added a quick method as well that would convert an object to a string, and then apply the same formatting algorithm in-case you have a need to present both and want to have the same presentation.
So instead of this:
You get this:
The Code:
public class JSonPresentationFormatter { public string Format(object obj) { var serializer = new JavaScriptSerializer(); var text = serializer.Serialize(obj); return Format(text); } public string Format(string text) { if (string.IsNullOrEmpty(text)) return string.Empty; text = text.Replace(System.Environment.NewLine, string.Empty).Replace("\t", string.Empty); var offset = 0; var output = new StringBuilder(); Action
tabs = (sb, pos) => { for (var i = 0; i < pos; i++) { sb.Append("\t"); } }; Func > previousNotEmpty = (s, i) => { if (string.IsNullOrEmpty(s) || i <= 0) return null; Nullable prev = null; while (i > 0 && prev == null) { prev = s[i - 1]; if (prev.ToString() == " ") prev = null; i--; } return prev; }; Func > nextNotEmpty = (s, i) => { if (string.IsNullOrEmpty(s) || i >= (s.Length - 1)) return null; Nullable next = null; i++; while (i < (s.Length - 1) && next == null) { next = s[i++]; if (next.ToString() == " ") next = null; } return next; }; for (var i = 0; i < text.Length; i++) { var chr = text[i]; if (chr.ToString() == "{") { offset++; output.Append(chr); output.Append(System.Environment.NewLine); tabs(output, offset); } else if (chr.ToString() == "}") { offset--; output.Append(System.Environment.NewLine); tabs(output, offset); output.Append(chr); } else if (chr.ToString() == ",") { output.Append(chr); output.Append(System.Environment.NewLine); tabs(output, offset); } else if (chr.ToString() == "[") { output.Append(chr); var next = nextNotEmpty(text, i); if (next != null && next.ToString() != "]") { offset++; output.Append(System.Environment.NewLine); tabs(output, offset); } } else if (chr.ToString() == "]") { var prev = previousNotEmpty(text, i); if (prev != null && prev.ToString() != "[") { offset--; output.Append(System.Environment.NewLine); tabs(output, offset); } output.Append(chr); } else output.Append(chr); } return output.ToString().Trim(); } }
You can download a copy of the source here: JSonPresentationFormatterExample:
Key Words://From object var employees = new[] { new {Name= "John Vansteen",ID="1", Age="35"} ,new {Name = "Joe Yankin", ID = "2", Age = "44" } ,new {Name = "Larry Yon", ID = "3", Age = "33" } }; Console.Write(new JSonPresentationFormatter().Format(employees)); //From string var jSonAsString = "{\"glossary\": {\"title\": \"example glossary\",\"GlossDiv\": {\"title\": \"S\",\"GlossList\": {\"GlossEntry\": {\"ID\": \"SGML\",\"SortAs\": \"SGML\",\"GlossTerm\": \"Standard Generalized Markup Language\",\"Acronym\": \"SGML\",\"Abbrev\": \"ISO 8879:1986\",\"GlossDef\": {\"para\": \"A meta-markup language, used to create markup languages such as DocBook.\",\"GlossSeeAlso\": [\"GML\", \"XML\"]},\"GlossSee\": \"markup\"}}}}}"; Console.Write(new JSonPresentationFormatter().Format(jSonAsString));
JSon C# Presentation Formatter
References:
IFormatProvider Interface
Source:
JSonPresentationFormatter
9 comments:
Hi, can you please check your code.
there are syntax errors.
Func> previousNotEmpty = (s, i) =>
{...};
does not exist
@fleurdelys - Thanks for the comment. Blogger is messing up the formatting. previousNotEmpty and nextNotEmpty are both anonymous functions, and are within the Format(string text) method.
It should be:
Func> previousNotEmpty
Func> nextNotEmpty
You can download the .cs file from here:
http://dl.dropbox.com/u/52219470/Source/JSonPresentationFormatter.cs
If I can help any more, please do not hesitate to ask.
@fleurdelys. Sorry.. it messed up the syntax in the comment as well! Just take a look at the file download. It has what your looking for.
JSonPresentationFormatter
Thanks for this routine, I've been looking for months. It works great for me.
Thanks, works nicely. I just changed the class to a static one.
Thanks for this! Here's a small enhancement to detect quoted elements:
if (chr == '"' && !ignoreQuote) inQuote = !inQuote;
if (chr == '\'' && inQuote) ignoreQuote = !ignoreQuote;
if (inQuote) {
output.Append(chr);
}
else if (chr.ToString() == "{")
I put your code on a public gist with minor modification:
https://gist.github.com/ca0v/5de495eccdc2874fecbd#file-jsonpresentationformatter-cs
I translated your code into Java due to I needed. I post, maybe could be useful for anyone more.
Thanks for your code.
import java.io.IOException;
import java.io.Writer;
public final class PrettyJsonSerializer {
private PrettyJsonSerializer() {
}
public static String serializePrettyHtml(String text, Writer writer)
throws IOException {
if (text == null || text.isEmpty()) {
return null;
}
text = text.replaceAll("\n", "").replaceAll("\t", "");
int offset = 0;
StringBuilder output = new StringBuilder();
for (int i = 0; i < text.length(); i++) {
char chr = text.charAt(i);
if (chr == '{') {
offset++;
output.append(chr);
output.append("\n");
addTabs(output, offset);
} else if (chr == '}') {
offset--;
output.append("\n");
addTabs(output, offset);
output.append(chr);
} else if (chr == ',') {
output.append(chr);
output.append("\n");
addTabs(output, offset);
} else if (chr == '[') {
output.append(chr);
Character next = getNextCharNotEmpty(text, i);
if (next != null && !next.toString().equals("]")) {
offset++;
output.append("\n");
addTabs(output, offset);
}
} else if (chr == ']') {
Character prev = getPreviousCharNotEmpty(text, i);
if (prev != null && !prev.toString().equals("[")) {
offset--;
output.append("\n");
addTabs(output, offset);
}
output.append(chr);
} else
output.append(chr);
}
return output.toString().trim();
}
/**
* Use this method to add tabs till given position
*
*/
private static void addTabs(StringBuilder sb, int pos) {
for (int i = 0; i < pos; i++) {
sb.append("\t");
}
}
/**
* Use this method to get previous character not empty
*
* @param s
* @param i
* @return
*/
private static Character getPreviousCharNotEmpty(String s, int i) {
if (s == null || s.isEmpty() || i <= 0)
return null;
Character prev = null;
while (i > 0 && prev == null) {
prev = s.charAt(i - 1);
if (prev == ' ')
prev = null;
i--;
}
return prev;
}
/**
* Use this method to get next character not empty
*
* @param s
* @param i
* @return
*/
private static Character getNextCharNotEmpty(String s, int i) {
if (s == null || s.isEmpty() || i >= (s.length() - 1))
return null;
Character next = null;
i++;
while (i < (s.length() - 1) && next == null) {
next = s.charAt(i++);
if (next == ' ')
next = null;
}
return next;
};
}
Post a Comment