I have a question regarding bookmarks in PDF.
I'm importing list of parameters from file and want to compare them with extracted bookmarks. I'm having troubles looping through list of imported parameters and my extracted bookmarks.
Can someone take a look at this piece of code and help me out a bit?
Thanks!
public static void CompareBookmarks(string MyPDf, List<string> MyTitles)
{
PdfReader reader = new PdfReader(MyPdf);
IList<Dictionary<string, object>> bookmarks = SimpleBookmark.GetBookmark(reader);
foreach (Dictionary<string, object> itemBookmark in bookmarks)
{
foreach (KeyValuePair<string, object> item in itemBookmark)
{
foreach (var title in MyTitles)
{
if (item.Value == str.ToString())
{
Console.WriteLine("Found");
}
else
{
Console.WriteLine("Not found");
}
}
}
}
Problem is, as I can see now, that each item in bookmark have 3 key/pair values(title, page number.). So the issue is- how can I compare only first value- Title with my string?
I see no reason to enumerate all items in the bookmark since you are only interested in the title. So without testing, I would expect something like this:
foreach (Dictionary<string, object> bookmark in bookmarks)
{
foreach (var title in MyTitles)
{
if (bookmark["Title"].ToString() == title)
{
// found
}
}
}
public static void CompareBookmarks(string MyPDf, List<string> MyTitles)
{
PdfReader reader = new PdfReader(MyPdf);
IList<Dictionary<string, object>> bookmarks = SimpleBookmark.GetBookmark(reader);
foreach (Dictionary<string, object> itemBookmark in bookmarks)
{
KeyValuePair<string, object> firstPairOfDictionary = item.FirstOrDefault();
foreach (var title in myTitles)
{
if (firstPairOfDictionary.Value != title.ToString())
{
Console.WriteLine("Did not found");
continue;
}
break;
}
}
The solution was to get first object in KeyValuePair.
I made a mistake and iterate through all objects in each bookmark.
Related
I'm working on a project where I want to build tokens from a JSON Array.
//Data fed to the system
{"Fruits":[{"Number":"111", "Name":"Apple"}, {"Number":"112", "Name":"Orange"},{"Number":"113", "Name":"Peach"}]}
//serializes the http content to a string
string result = Request.Content.ReadAsStringAsync().Result;
//deserializes result
Dictionary<string, dynamic> data = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(result);
//builds custom tokens
var customTokens = new Dictionary<string, object>();
foreach (var dataField in data)
{
if (dataField.Value is JArray)
{
string nameValue = "";
foreach (JObject content in dataField.Value.Children<JObject>())
{
foreach (JProperty prop in content.Properties())
{
nameValue += prop.Name.ToString() + " : " + prop.Value.ToString();
}
}
customTokens.Add($"{dataField.Key}", nameValue);
}
}
The above code managed to create token $Fruits.
But i also want to achieve token $Number and $Name, where values of each token is from the concatenated values of same key. Example, If I use the "$Number", it will be replaced by 111, 112, 113 and If I use the $Name, it will be replaced by Apple, Orange, Peach.
Also, I'm not using any strongly type models as I don't know what data will be fed to the system.
Any help?
There are a few minor changes to your code to achieve this. First make your dictionary look like this:
var customTokens = new Dictionary<string, List<string>>();
Then, when you loop over all the properties in the array, check if the property has been added, and if not add it.
foreach (JProperty prop in content.Properties())
{
if(customTokens.ContainsKey(prop.Name))
{
customTokens[prop.Name].Add(prop.Value.ToString());
}
else
{
customTokens.Add(prop.Name, new List<string> { prop.Value.ToString() });
}
}
At the end you have a dictionary where the key is the property name and the value is a List<string> - this can be concatenated together:
foreach(var item in customTokens)
{
Console.WriteLine(item.Key + ":" + String.Join(",", item.Value));
}
Or, if you really want it in a dictionary of concatenated strings just do this
var finalResult = customTokens.ToDictionary(k => k.Key, v => String.Format(",",v.Value));
Note you'll need to add using System.Linq to the top of your file to use ToDictionary
Final test code:
var result = "{ \"Fruits\":[{\"Number\":\"111\", \"Name\":\"Apple\"}, {\"Number\":\"112\", \"Name\":\"Orange\"},{\"Number\":\"113\", \"Name\":\"Peach\"}]}";
Dictionary<string, dynamic> data = JsonConvert.DeserializeObject<Dictionary<string, dynamic>>(result);
var customTokens = new Dictionary<string, List<string>>();
foreach (var dataField in data)
{
if (dataField.Value is JArray)
{
foreach (JObject content in dataField.Value.Children<JObject>())
{
foreach (JProperty prop in content.Properties())
{
if(customTokens.ContainsKey(prop.Name))
{
customTokens[prop.Name].Add(prop.Value.ToString());
}
else
{
customTokens.Add(prop.Name, new List<string> { prop.Value.ToString() });
}
}
}
foreach(var item in customTokens)
{
Console.WriteLine(item.Key + ":" + String.Join(",", item.Value));
}
}
}
I'm actually trying to check if a string is equal to any of the key's in my Dictionary object.
Here is what I have done so far:
using (var oStreamReader = new StreamReader(path))
{
Dictionary<String, String> typeNames = new Dictionary<string, string>();
typeNames.Add("Kind","nvarchar(1000)");
typeNames.Add("Name","nvarchar(1000)");
DataTable oDataTable = new DataTable();
var headLine = oStreamReader.ReadLine().Trim().Replace("\"", "");
var columnNames = headLine.Split(new[] { ';' });
String[] oStreamDataValues;
/*
*create DataTable header with specific datatypes and names
*/
int countCol = 0;
foreach (string readColumn in columnNames)
{
if ((readColumn.ToString().Replace("\"", "").CompareTo(typeNames) == true))
{
// this comparison doesn't work
}
}
}
I am not quite sure what exactly you are trying to achieve. If you have a C# dictonary you can use linq to check for values that match the required value, e.g.
string valueToCompare = "Value to match";
Dictionary<string, string> dict = new Dictionary<string, string>
{
{"Key 1", "A value"},
{"Key 2", "Another value"}
};
bool found= dict.Values
.Any(value
=>
value.Equals(valueToCompare,
StringComparison.CurrentCultureIgnoreCase)
);
Since you want check if exist an entry in your Dictionary that as the same key of one of the values in your columnNames object I suggest you to use ContainsKey method
Dictionary<string, string> d = new Dictionary<string, string>();
string keyvalue;
if (d.ContainsKey("value to find"))
{
if (d.TryGetValue("value to find", out keyvalue))
{
//// here keyvalue variable has the value
}
else
{
///value is null or throws exception
}
}
else
{
////key no exists
}
I have solved this (by inspiration of Paul Houlston and Thomas Lielacher)
string headLine = oStreamReader.ReadLine().Trim().Replace("\"", "");
string columnNames = headLine.Split(new[] { ';' });
foreach (string readColumn in columnNames)
{
if (typeNames.Keys.Contains(readColumn, StringComparer.CurrentCultureIgnoreCase) == true)
{
DataColumn oDataColumn = new DataColumn(readColumn,typeof(System.String));
oDataTable.Columns.Add(oDataColumn);
}
}
I am surely missing something small here. I am trying to open multiple resx files, load them into a dictionary, then cross reference a translation file. The problem is that when I open up the resx file with resxResourceReader, it reads in all the the form setup data as well. I.E. container information, control names, etc.
Now I noticed in the resx file that the entries I want have "xml:space" along with them. What is the correct way to only get the strings I want, and leave all the other stuff behind?
Thanks!
foreach (String s in sourceLocations)
{
Dictionary<string, string> sourceTemp = new Dictionary<string, string>();
Dictionary<string, object> Temp = new Dictionary<string, object>();
using (ResXResourceReader rsxr = new ResXResourceReader(s))
{
foreach (DictionaryEntry entry in rsxr)
{
string[] parts = s.Split('\\');
if (!entry.Key.ToString().Contains(">>"))
{
sourceTemp.Add(parts[parts.Count() - 1] + "_" + entry.Key.ToString(), entry.Value.ToString());
}
}
sources.Add(sourceTemp);
}
}
For anyone who runs into this later, this ended up working :
foreach (String s in sourceLocations)
{
Dictionary<string, string> sourceTemp = new Dictionary<string, string>();
Dictionary<string, object> Temp = new Dictionary<string, object>();
using (ResXResourceReader rsxr = new ResXResourceReader(s))
{
rsxr.UseResXDataNodes = true;
foreach (DictionaryEntry entry in rsxr)
{
string[] parts = s.Split('\\');
if ((!entry.Key.ToString().Contains(">>")))
{
if (isNodeString((ResXDataNode)entry.Value))
sourceTemp.Add(parts[parts.Count() - 1] + "_" + entry.Key.ToString(), getNodeValue((ResXDataNode)entry.Value));
}
}
sources.Add(sourceTemp);
}
}
private string getNodeValue(ResXDataNode node)
{
if (node.FileRef == null)
{
return node.GetValue((ITypeResolutionService)null).ToString();
}
else return String.Empty;
}
private bool isNodeString(ResXDataNode node)
{
string result = node.GetValueTypeName((ITypeResolutionService)null);
if (result.Contains("System.String")) return true;
else return false;
}
I've an hash table with the details as mentioned below
public void get_Unique_Sequence(List<string> name, List<List<string>> nameSequence)
{
Hashtable test = new Hashtable();
test.Add(nameSequence, name)
foreach (DictionaryEntry entry in test)
{
Console.WriteLine("{0}: {1}", entry.Key, entry.Value);
}
}
I'm trying to print the contents of the hash table with the help of foreach loop. However the output which I'm getting is
output:
System.Collections.Generic.List`1[System.String]: System.Collections.Generic.List`1[System.String]
Please guide me to get the key and value (that is the contents) of the hashtable.
You probably don't want to insert the lists objects in the hash table, but the elements in the list.
So first you have to do something like:
(assuming that the list are not null and have the same size)
for(int i =0;i<name.Count;i++){
test.Add(nameSequence[i], name[i]);
}
instad of:
test.Add(nameSequence, name);
And then your method should work.
I don't know how you would like to format the output, but to print the content of a List you have to iterate on it.
On the List of lists you need to iterate two times.
Maybe a solution could be this:
public void get_Unique_Sequence(List<string> name, List<List<string>> nameSequence)
{
Hashtable test = new Hashtable();
test.Add(nameSequence, name);
foreach (DictionaryEntry entry in test)
{
string key = string.Empty;
foreach (string s in (List<string>)entry.Key)
{
key += s + " ";
}
foreach (List<string> list in (List<List<string>>)entry.Value)
{
string value = string.Empty;
foreach (string s in list)
{
value += s + " ";
}
Console.WriteLine("{0}: {1}", key, value);
}
}
}
Of course, you need to format the output according to your needs.
Well, the issue isn't about printing the hashtable. It's about printing a List<List<string>>.
You want something like this for each key and value:
foreach (var sublist in result)
{
foreach (var obj in sublist)
{
Console.WriteLine(obj);
}
}
I'm having trouble pulling individual address components from google map's api results.
Here are the results received from this url:
http://maps.googleapis.com/maps/api/geocode/json?address=jobing.com+glendale+arizona&sensor=false
This url is in the "uri" variable. Here's the code I'm using to try and retrieve the address_component by type. Take into consideration that I'm a bit new at c#.
String Output = client.DownloadString(uri);
Dictionary<String, Object> RinkData = JsonConvert.DeserializeObject<Dictionary<String, Object>>(Output);
Dictionary<String, Object> RinkDataResults = (Dictionary<String, Object>) RinkData["results"];
if (RinkDataResults.ContainsKey("formatted_address"))
{
Route = GetAddressComponentByType(RinkDataResults["address_components"], "route");
}
And here is the function I'm using "GetAddressComponentByType"
protected String GetAddressComponentByType(Object AddressComponents, String AddressType)
{
Boolean MatchFound = false;
String MatchingLongName = "";
Dictionary<String, Object> AddressComponentsDict = (Dictionary<String, Object>)AddressComponents;
foreach (KeyValuePair<String, Object> ac in AddressComponentsDict)
{
Dictionary<String, Object> acDict = (Dictionary<String, Object>) ac.Value;
ArrayList acTypes = (ArrayList) acDict["types"];
foreach (String acType in acTypes)
{
if (acType == AddressType)
{
MatchFound = true;
break;
}
}
if (MatchFound)
{
MatchingLongName = (String) acDict["long_name"];
}
}
return MatchingLongName;
}
The problem is, it doesn't even get to my component retrieval function. It bombs converting RinkData["results"] to a Dictionary saying it's an invalid conversion.
Does anyone see what I'm doing wrong? Or maybe someone has a custom object I can read google maps geocode results into that works?
Ah, nevermind. I can extract address components easily if I start with this object
dynamic googleResults = new Uri(uri).GetDynamicJsonObject();
foreach (var result in googleResults.results)
{
foreach (var addressComp in result.address_components)
{
Literal1.Text += "<br />" + addressComp.long_name;
}
}
It's an extension class for JSON.NET found here. From L.B.'s answer to this question.