I have marked Vadim's solution as an answer however I thought I'll post my solution, which I did before I saw his response.
The implementation below is using Extension methods and Regular Expression Match to extract the values - it is useful if you already know the fields you will be reading i.e. they are predefined - if you do not know what you'll be dealing with and they are dynamic then the answer above may be more useful to you.
Extension methods and class defining the meta info properties in the MetaInfo field you may need to retrieve:
public static class Extensions
{
public static string[] DocMetaInfoFields =
{
MetaInfoFields.Title, MetaInfoFields.Author,
MetaInfoFields.DocumentType, MetaInfoFields.ModifiedBy
};
public static string GetDocumentType(this object metaInfo)
{
var match = GetRegexMatch(metaInfo as string, MetaInfoFields.DocumentType);
return (match.Groups.Count > 1)
? match.Groups[1].Value
: string.Empty;
}
public static Dictionary<string, string> GetDocMetaProperties(this object metaInfo)
{
var properties = new Dictionary<string, string>();
foreach (var field in DocMetaInfoFields)
{
var match = GetRegexMatch(metaInfo as string, field);
properties.Add(field,
(match.Groups.Count > 1)
? match.Groups[1].Value
: string.Empty);
}
return properties;
}
public static StringBuilder FormatCamlValues(this StringBuilder sb, string valueTag, string listName,
IEnumerable<string> clientReferences)
{
foreach (var clientRef in clientReferences)
{
sb.AppendFormat(valueTag, listName, clientRef);
}
return sb;
}
public static List<ClientDocumentListItem> ToClientDocumentList(this ListItemCollection files)
{
return files.ToList().ConvertAll(ListItemToClientDocItem);
}
private static Match GetRegexMatch(string searchString, string fieldName)
{
string regexCapture = string.Format(@"^{0}:\w{{2}}\|([^.(\r|\n)]*)[\r\n|\n\r]+\w", fieldName);
return Regex.Match(searchString, regexCapture, RegexOptions.Multiline);
}
}
/// <summary>
/// Defines the field names inside the MetaInfo composite field returned while using the SharePoint client object CamlQuery() method
/// </summary>
public static class MetaInfoFields
{
public static string MetaInfoFieldName = "MetaInfo";
public static string Title = "vti_title";
public static string Author = "vti_author";
public static string DocumentType = "Document Type";
public static string ModifiedBy = "vti_modifiedby";
}
Usage
var list = ctx.Web.Lists.GetByTitle(targetListTitle);
var items = list.GetItems(CamlQuery.CreateAllItemsQuery());
ctx.Load(items, icol => icol.Include( i => i[MetaInfoFields.MetaInfoFieldName]));
//ctx.Load(items);
ctx.ExecuteQuery();
var docProperties = GetDocMetaProperties(listItem[MetaInfoFields.MetaInfoFieldName]);
var title = docProperties[MetaInfoFields.Title];
var createdBy = docProperties[MetaInfoFields.Author];
var modifiedBy = docProperties[MetaInfoFields.ModifiedBy];
var type = docProperties[MetaInfoFields.DocumentType];