JSON.NET and Replacing @ Sign in XML to JSON converstion

It took me quite a while to find the right answer, so I thought I'd share:

var xDocument = XDocument.Parse("<xml><a attr=\"b\">c</a></xml>");
var builder = new StringBuilder();
JsonSerializer.Create().Serialize(new CustomJsonWriter(new StringWriter(builder)), xDocument);
var serialized = builder.ToString();

public class CustomJsonWriter : JsonTextWriter
{
    public CustomJsonWriter(TextWriter writer): base(writer){}

    public override void WritePropertyName(string name)
    {
        if (name.StartsWith("@") || name.StartsWith("#"))
        {
            base.WritePropertyName(name.Substring(1));
        }
        else
        {
            base.WritePropertyName(name);
        }
    }
}

Output:

{"xml":{"a":{"attr":"b","text":"c"}}}

Another option is to create your own OneWayXmlNodeConverter inheriting from JsonConverter and call SerializeObject instead of SerializeXmlNode like this:

var json = JsonConvert.SerializeObject(xmlNode, new OneWayXmlNodeConverter());

I call it "One Way" because I assume the default XmlNodeConverter adds the "@" sign so it can convert back to XML from the resulting JSON.

If you include the JSON.NET source in your project (as opposed to just the compiled library), an easy way to create the OneWayXmlNodeConverter is to copy the XmlNodeConverter code, remove the hard-coded "@" sign in the private GetPropertyName method, and save it as OneWayXmlNodeConverter.

Note: I know that your question is specific to "replacing" the "@" sign, but the linked Preventing variation of this question is marked as duplicate.


The Regex not always work great,when content has the @ character and in the first place,that will be replace too. so I think(?<!:)(\"@)(?!.\":\\s ) may be better.


I went ahead and used this. Let me know if there is a better way.

public ActionResult Layout()
{
    var xml = new XmlDocument();
    xml.XmlResolver = null;
    xml.Load(Server.MapPath("~/App_Data/Navigation.xml"));

    var jsonText = JsonConvert.SerializeXmlNode(xml, Newtonsoft.Json.Formatting.Indented);
    return Content(Regex.Replace(jsonText, "(?<=\")(@)(?!.*\":\\s )", string.Empty, RegexOptions.IgnoreCase));
}

Tags:

Xml

Json

Json.Net