开发者

Deserialize a string that contains a repeating set of elements

开发者 https://www.devze.com 2023-04-11 10:35 出处:网络
I\'m getting the response string as follows: Navigator[sizenavigator:INTEGER (Size) modifier:size 开发者_如何学Python score:1.300855517 type:INTEGER unit:kB

I'm getting the response string as follows:

Navigator[sizenavigator:INTEGER (Size) 
          modifier:size
         开发者_如何学Python score:1.300855517 type:INTEGER unit:kB
          hits:7744 
          hitsUsed:7744 
          ratio:1
          min:65 
          max:66780 
          mean:3778
          sum: 29259942
          frequencyError:-1
          entropy:1.300855533 
          points:
          Name:Less than 1 
          Interval: ->1023 
          Value:[;1023] 
          Count:1121
          Name:Between 1 and 2 
          Interval: 1024->2047 
          Value:[1024;2047] 
          Count:3325
          Name:Between 2 and 3 
          Interval: 2048->3071 
          Value:[2048;3071] 
          Count:1558
          Name:More than 3 
          Interval: 3072-> 
          Value:[3072;] 
          Count:1740
         ]

As you can see Name, Interval, Value, Count is repeating and this will repeat 'n' no. of times. How can I de-serialize it by creating a type (class) for this process ?

Say if the class is somewhat like:

class Navigator
{
 string modifier;
 string score;
 .
 .
 string Name;
 string Interval;
 string Value;
 int Count;
}

How can we get the repeated values for Name, Interval, Value, Count ??

Thanks in advance.


I would suggest you make liberal use of regular expressions to extract the information you require. This adds alot of complexity, but your other option is tokenisation which IMO will be just as complex to implement given the input.

The regex for the modifier is pretty simple. It requires you look for the literal string "modifier:" and capture whatever is after the : until the end of the line - demarked by a cr lf \r\n. You can make use of a capture group in order to pull the info you want so the regex is:

modifier:(.*[^\r\n])

The regex for score is just as simple, look for literal string score: and capture everything after the : until the end of the line:

score:(.*[^\n\r])

The regex for your repeating items os much much more complex, and again makes use of capture groups (this time named to make extracting them easier) to get to the information you're interested in. This is tested and works:

Name:\s*(?<name>.*[^\r\n])\s*\r\n\s+Interval:\s(?<interval>\d*\-\>\d*)\s*\r\n\s+Value:\s*(?<value>\[\d*;\d*\])\s*\r\n\s+Count:\s*(?<count>\d+) 

Given your input data in a variable called input you would use this code as follows:

var modifierRegex = new Regex(@"modifier:(.*[^\r\n])");
var scoreRegex = new Regex(@"score:(.*[^\n\r])");
var itemsRegex = new Regex(@"Name:\s*(?<name>.*[^\r\n])\s*\r\n\s+Interval:\s(?<interval>\d*\-\>\d*)\s*\r\n\s+Value:\s*(?<value>\[\d*;\d*\])\s*\r\n\s+Count:\s*(?<count>\d+)");
var modifierMatch = modifierRegex.Match(input);
var scoreMatch = scoreRegex.Match(input);
var itemsMatches = itemsRegex.Matches(input);

var modifier = modifierMatch.Groups[1].Value;
var score = scoreMatch.Groups[1].Value;
foreach(Match match in itemsMatches)
{
  var name = match.Groups["name"].Value;
  var interval = match.Groups["interval"].Value;
  var value = match.Groups["value"].Value;
  var count = match.Groups["count"].Value;
}

Live example: http://rextester.com/rundotnet?code=OQTZE85773

That shows you how to extract the values you want. Now use a data structure such as described by @Jeremy McGee and read the values much as he describes.


What I think you're looking for is a way to turn the text string given into some kind of internal C# data structure. For the repeating structure you'll need two classes: one for the "main" body of the text and one for the repeating items:

class Navigator
{
 string modifier;
 string score;
 .
 .
 List<IntervalItem> Intervals;
}

class IntervalItem
{
    string Name;
    string Interval;
    string Value;
    int Count;
}

Then in the code that deserializes the text, something like:

Navigator navigator = new Navigator();
// ... populate the modifier, score, and suchlike
navigator.Intervals = new List<IntervalItem>();

while ( // something to test if we have an interval to read // )
{
  IntervalItem intervalItem = new IntervalItem();
  // ... populate the interval from the name, interval, value
  navigator.Intervals.Add(intervalItem);
}

(You'll need to figure out an appropriate way to test if you've got another interval to read based on how you're scanning through the text.)

0

精彩评论

暂无评论...
验证码 换一张
取 消