Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force JsonConvert.SerializeXmlNode to serialize node value as an Integer or a Boolean

Tags:

json

c#

json.net

The SerializeXmlNode function from Newtonsoft.Json.JsonConvert class always outputs the value of the last child nodes of a XML as a string type in the serialization process, when sometimes you might need them to be serialized as an Integer or a Boolean.

Sample code:

<Object>
  <ID>12</ID>
  <Title>mytitle</Title>
  <Visible>false</Visible>
</Object>

Output:

{ "ID" : "12",
  "Title" : "mytitle",
  "Visible" : "false"
}

Desired output:

{ "ID" : 12,
  "Title" : "mytitle",
  "Visible" : false
}

Is there a way to force a XML node to be serialized as a Integer or a Boolean?

Thank you.

Note: Please avoid posting workarounds when the XML is already serialized to a JSON string, as those workarounds are the ones that we are willing to avoid.

like image 919
Iván Pérez Gómez Avatar asked Sep 04 '13 10:09

Iván Pérez Gómez


People also ask

What is Jsonconvert SerializeObject in C#?

SerializeObject Method (Object, Type, JsonSerializerSettings) Serializes the specified object to a JSON string using a type, formatting and JsonSerializerSettings. Namespace: Newtonsoft.Json.

What is Serializexmlnode?

Serializes the XmlNode to a JSON string using formatting.


2 Answers

JSON.NET is not a tool for XML serialization. It's serialization of XML nodes is meant to provide one-to-one correspondence between XML and JSON. As attributes in XML can be only of type string, type information is not preserved during the serialization. It will be useless when deserializing back to JSON.

If you need to convert XML to JSON, I suggest using a DTO class which supports both XML and JSON serialization.

[XmlRoot ("Object"), JsonObject]
public class Root
{
    [XmlElement, JsonProperty]
    public int Id { get; set; }

    [XmlElement, JsonProperty]
    public string Title { get; set; }

    [XmlElement, JsonProperty]
    public bool Visible { get; set; }
}

Deserialize from XML and then serialize to JSON:

public class Program
{
    private const string xml = @"
        <Object>
          <Id>12</Id>
          <Title>mytitle</Title>
          <Visible>false</Visible>
        </Object>";

    private static void Main ()
    {
        var serializer = new XmlSerializer(typeof(Root));
        var root = (Root)serializer.Deserialize(new StringReader(xml));
        Console.WriteLine(JsonConvert.SerializeObject(root, Formatting.Indented));
        Console.ReadKey();
    }
}

Output:

{
  "Id": 12,
  "Title": "mytitle",
  "Visible": false
}
like image 78
Athari Avatar answered Oct 04 '22 17:10

Athari


The current JSON.NET build doesn't provide the requested feature, so I modified the source code to provide this functionality:

https://github.com/lukegothic/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/Converters/XmlNodeConverter.cs

This modification provides the XmlNodeConverter a way to read an optional attribute from XML nodes called "Type" that holds the desired serialization of a node value. By default, the converter serializes all values as string in the result JSON string, but now you can add an attribute that specifies the desired DataType output. The allowed types are Integer, Float, Boolean and Date.

For example, if you have this source XML:

<Object>
  <ID json:Type='Integer'>12</ID>
  <Title>mytitle</Title>
  <Visible json:Type='Boolean'>false</Visible>
  <Price json:Type='Float'>1.55</Price>
  <ExpirationDate json:Type='Date'>2013-12-31</ExpirationDate>
</Object>

It will be serialized as:

{
    "ID":12,
    "Title":"mytitle",
    "Visible":false,
    "Price":1.55,
    "ExpirationDate":"2013-12-31T00:00:00"
}
like image 21
Iván Pérez Gómez Avatar answered Oct 04 '22 16:10

Iván Pérez Gómez