2

I have the following json data, I need to read the data from it and them perform some comparisons.

{"expiration": "2013-04-01T00:00:00Z", 

"conditions": [ 
{"bucket": "the-s3-bucket-in-question"}, 
["starts-with", "$key", "donny/uploads/"],
{"acl": "private"},
["eq", "$Content-Type", "text/plain"],
["starts-with", "x-amz-meta-yourelement", ""],
["content-length-range", 0, 1048576]

]
}

By using the following code I have found the first element

var policy = Encoding.UTF8.GetString(policyByteArray); 

JObject obj = JObject.Parse(policy);  

string policyexpiration = obj.First.First.Path;

I have used JToken for finding all the conditions but I am getting only one element in that array. Can you please help me to get all the elements present in the conditions. Following is the way I have used JToken

JToken entireJson = JToken.Parse(policy);
var items = entireJson["conditions"].Value<JArray>()[0];
XmlDocument xdoc = (XmlDocument)JsonConvert.DeserializeXmlNode(items.ToString(), "root");
XmlNode xmlarray = xdoc.GetElementsByTagName("root")[0];

foreach (XmlNode xmlelement in xmlarray)
{

}
AdrianHHH
  • 13,492
  • 16
  • 50
  • 87
purna.n
  • 287
  • 1
  • 3
  • 11

3 Answers3

0

You are you only getting one element because you are selecting the value at index 0 of the JArray

var items = entireJson["conditions"].Value<JArray>()[0];

Instead of using the Value method, use Values which returns an IEnumerable

var items = entireJson["conditions"].Values<JObject>();
Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
  • Hi I am getting the following exception at XmlDocument xdoc = (XmlDocument)JsonConvert.DeserializeXmlNode(items.ToString(), "root"); If i remove the [0]. The exvception is "XmlNodeConverter can only convert JSON that begins with an object" @yuval – purna.n Apr 25 '14 at 05:39
  • You are calling ToString on an IEnumerable, which prints the class name. It does not concat your list and it is not a valid xml – Yuval Itzchakov Apr 25 '14 at 05:41
  • so What I need to write in that part sorry for late replay , thanks – purna.n Apr 25 '14 at 06:16
0

As far as I know DeserializeXmlNode() only accept string that represent JSON object. That's why it worked when you passed only the first value of conditions property :

var items = entireJson["conditions"].Value<JArray>()[0];
XmlDocument xdoc = JsonConvert.DeserializeXmlNode(items.ToString(), "root");

But throwing exception if you pass the entire value or the second value of conditions because both represent JSON array instead of JSON object :

//pass entire value
var items = entireJson["conditions"].Value<JArray>();
//or pass the second value : ["starts-with", "$key", "donny/uploads/"]
var items = entireJson["conditions"].Value<JArray>()[1];
XmlDocument xdoc = JsonConvert.DeserializeXmlNode(items.ToString(), "root");

It isn't clear what kind of XML format you want to create from given JSON string. But just to make it work, you can try to create another JSON object having one property named conditions with value copied from the initial JSON :

var items = entireJson["conditions"].Value<JArray>();
var newObject = string.Format("{{conditions : {0}}}", items.ToString());
XmlDocument xdoc = (XmlDocument)JsonConvert.DeserializeXmlNode(newObject, "root");
har07
  • 88,338
  • 12
  • 84
  • 137
  • For this I am getting the XML file but if it is a JSON Object I am getting the "Start-with" like it is dividing for every element. – purna.n Apr 25 '14 at 09:08
0

I'm not sure why you need the XML tools at all. Iterating the "conditions" in your json structure is simple with Json.NET and you're already very close.

var items = entireJson["conditions"].Value<JArray>();
foreach (JToken condition in items)
{
    //do work on one condition here
}

Note that this json structure is a little odd. A single condition can either be an array such as ["starts-with", "$key", "donny/uploads/"] OR an object such as {"bucket": "the-s3-bucket-in-question"}.

Depending what you want to do with the conditions, you may need to distinguish between the two. You can use C#'s is operator with the Json.NET types, like this:

var items = entireJson["conditions"].Value<JArray>();
foreach (JToken condition in items)
{
    if (condition is JArray)
    {
        //do something with the array
    }
    else if (condition is JObject)
    {
        //do something with the object                    
    }
}
solublefish
  • 1,681
  • 2
  • 18
  • 24