I'm going to parsing a website content Website HTML Content. I use follow codes:
private async void loadButton_Click(object sender, RoutedEventArgs e)
{
string address = "http://www.iiees.ac.ir/fa/eqcatalog";
loadButton.IsEnabled = false;
//string htmlCode = await DownloadStringAsync(address, Encoding.UTF8);
string htmlCode = await GetDataAsync(address, Encoding.UTF8);
paragraph1.Inlines.Add(new Run(htmlCode));
loadButton.IsEnabled = true;
}
private async Task<string> GetDataAsync(string address, Encoding encoding)
{
string htmlCode = await DownloadStringAsync(address, encoding);
List<string> options = new List<string>();
HtmlDocument doc = new HtmlDocument();
doc.LoadHtml(htmlCode);
foreach (var table in doc.DocumentNode.SelectNodes("//table"))
{
if (table.Id == "CatalogForm")
{
foreach (HtmlNode row in table.SelectNodes("tr"))
{
if (row.Attributes.Any(a => a.Value == "hidecircle"))
{
foreach (HtmlNode td in row.SelectNodes("TD"))
{
foreach (HtmlNode option in td.SelectNodes("option"))
{
options.Add(option.InnerText);
}
}
}
}
}
}
var sb = new StringBuilder();
options.ForEach(str => sb.AppendLine(str));
return sb.ToString();
}
But throw in "An unhandled exception of type 'System.ArgumentNullException' occurred in mscorlib.dll" exception.
For more information, I upload my project here.
Download project
I created a sample from your code, and I found the following:
I am not particularly familiar with xpath, but seems it is case sensitive. Searching for "TD" will return nothing, while searching for "td" will.
SelectNodes will return null whenever nothing was found, and a foreach that depends on it will always throw an exception. So it is better to check whether the result of SelectNodes is not null before trying to loop over it.
foreach (HtmlNode td in row.SelectNodes("td"))
{
var ops = td.SelectNodes("option");
if (ops != null)
{
foreach (HtmlNode option in ops)
{
options.Add(option.InnerText);
}
}
}
Related
I cannot find a decent example of how to use the latest version of Azure BlobClient to get the byte count of an existing blob.
Here is the code I am working with so far. I cannot figure out how to filter the blob I need to find. I can get them all, but it takes ages.
protected BlobContainerClient AzureBlobContainer
{
get
{
if (!isConfigurationLoaded) { throw new Exception("AzureCloud currently has no configuration loaded"); }
if (_azureBlobContainer == null)
{
if (!string.IsNullOrEmpty(_configuration.StorageEndpointConnection))
{
BlobServiceClient blobClient = new BlobServiceClient(_configuration.StorageEndpointConnection);
BlobContainerClient container = blobClient.GetBlobContainerClient(_configuration.StorageContainer);
container.CreateIfNotExists();
_azureBlobContainer = container;
}
}
return _azureBlobContainer;
}
}
public async Task<Response<BlobProperties>> GetAzureFileSize(string fileName)
{
BlobClient cloudFile = AzureBlobContainer.GetBlobClient(fileName);
await foreach (BlobItem blobItem in AzureBlobContainer.GetBlobsAsync())
{
Console.WriteLine("\t" + blobItem.Name);
}
// Am i supposed to just iterate every single blob on there? how do I filter?
return blobProps;
}
Thoughts?
Ended up doing it like this... I get that it isn't the proper way, but it works.
public async Task<(BlobClient cloudFile, CopyFromUriOperation result)> MigrateFileToAzureBlobAsync(Uri url, string fileName, long? bytesCount)
{
BlobClient cloudFile = AzureBlobContainer.GetBlobClient(fileName);
cloudFile.DeleteIfExists();
BlobCopyFromUriOptions options = new BlobCopyFromUriOptions();
options.Metadata = new Dictionary<string, string>();
options.Metadata.Add("confexbytecount", bytesCount.ToString());
CopyFromUriOperation result = await cloudFile.StartCopyFromUriAsync(url, options);
Response x = await result.UpdateStatusAsync();
await result.WaitForCompletionAsync();
return (cloudFile, result);
}
public async Task<long> GetAzureFileSize(string fileName)
{
long retVal = 0;
await foreach (BlobItem blobItem in AzureBlobContainer.GetBlobsAsync(BlobTraits.All, BlobStates.All, fileName))
{
if (blobItem.Metadata.TryGetValue("confexbytecount", out string confexByteCount))
{
long.TryParse(confexByteCount, out retVal);
}
}
return retVal;
}
I am attempting to retrieve the names and phone number(s) of all contacts and show them into tableview in Xamarin.iOS. I have made it this far:
var response = new List<ContactVm>();
try
{
//We can specify the properties that we need to fetch from contacts
var keysToFetch = new[] {
CNContactKey.PhoneNumbers, CNContactKey.GivenName, CNContactKey.FamilyName, CNContactKey.EmailAddresses
};
//Get the collections of containers
var containerId = new CNContactStore().DefaultContainerIdentifier;
//Fetch the contacts from containers
using (var predicate = CNContact.GetPredicateForContactsInContainer(containerId))
{
CNContact[] contactList;
using (var store = new CNContactStore())
{
contactList = store.GetUnifiedContacts(predicate, keysToFetch, out
var error);
}
//Assign the contact details to our view model objects
response.AddRange(from item in contactList
where item?.EmailAddresses != null
select new ContactVm
{
PhoneNumbers =item.PhoneNumbers,
GivenName = item.GivenName,
FamilyName = item.FamilyName,
EmailId = item.EmailAddresses.Select(m => m.Value.ToString()).ToList()
});
}
BeginInvokeOnMainThread(() =>
{
tblContact.Source = new CustomContactViewController(response);
tblContact.ReloadData();
});
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
and this is my update cell method
internal void updateCell(ContactVm contact)
{
try
{
lblName.Text = contact.GivenName;
lblContact.Text = ((CNPhoneNumber)contact.PhoneNumbers[0]).StringValue;
//var no = ((CNPhoneNumber)contact.PhoneNumbers[0]).StringValue;
//NSString a = new NSString("");
// var MobNumVar = ((CNPhoneNumber)contact.PhoneNumbers[0]).ValueForKey(new NSString("digits")).ToString();
var c = (contact.PhoneNumbers[0] as CNPhoneNumber).StringValue;
}
catch(Exception ex)
{
throw ex;
}
}
I would like to know how to retrieve JUST the phone number(s) as a string value(s) i.e. "XXXXXXXXXX". Basically, how to call for the digit(s) value.
this line of code
lblContact.Text = ((CNPhoneNumber)contact.PhoneNumbers[0]).StringValue;
throw a run time exception as specified cast is not valid
Yes, exception is correct. First of all, you don't need any casts at all, contact.PhoneNumbers[0] will return you CNLabeledValue, so you just need to write it in next way
lblContact.Text = contact.PhoneNumbers[0].GetLabeledValue(CNLabelKey.Home).StringValue
//or
lblContact.Text = contact.PhoneNumbers[0].GetLabeledValue(CNLabelPhoneNumberKey.Mobile).StringValue
or you may try, but not sure if it works
contact.PhoneNumbers[0].Value.StringValue
I got solution. Here is my code if any one required.
CNLabeledValue<CNPhoneNumber> numbers =
(Contacts.CNLabeledValue<Contacts.CNPhoneNumber>)contact.PhoneNumbers[0];
CNPhoneNumber number = numbers.Value;
string str = number.StringValue;
lblContact.Text = str;
I'm attempting to write a parser to extract details from a word document using NPOI. I'm able to retrieve details from each table in the document but I need to be able to identify which section of the document the table comes from in order to differentiate between them. While I can identify all of the lines that have the specific heading type I need, I can't work out how to tell which heading precedes which table.
Can anybody offer any advice? If it's not possible with NPOI, can anybody recommend another way to do it?
If you are parsing word document. I'll suggest you to use OpenXMlpowertool by Eric white, download it from NuGet package manager or download directly from net.
Here is the code snippet i have used to parse document , code snippet is very small, clean and stable. You must first debug it to understand it working which will help you to customize it for yourself. it will read all text, paragraphs , bullets and contents etc. go through the documentation of Eric White for more details but below code snippet is the most you'll need to parse and top of it you can build your functionality.
using DocumentFormat.OpenXml.Packaging;
using OpenXmlPowerTools;
private static WordprocessingDocument _wordDocument;
_wordDocument = WordprocessingDocument.Open(wordFileStream, false); // stream wordFileStream in constructor
// To get header and footer use this
var headerList = _wordDocument.MainDocumentPart.HeaderParts.ToList();
var footerList = _wordDocument.MainDocumentPart.FooterParts.ToList();
private void GetDocumentBodyContents()
{
List<string> allList = new List<string>();
List<string> allListText = new List<string>();
try
{
//RevisionAccepter.AcceptRevisions(_wordDocument);
XElement root = _wordDocument.MainDocumentPart.GetXDocument().Root;
XElement body = root.LogicalChildrenContent().First();
OutputBlockLevelContent(_wordDocument, body);
}
catch (Exception ex)
{ }
}
private void OutputBlockLevelContent(WordprocessingDocument wordDoc, XElement blockLevelContentContainer)
{
try
{
string currentItem = string.Empty, currentItemText = string.Empty, numberText = string.Empty;
foreach (XElement blockLevelContentElement in
blockLevelContentContainer.LogicalChildrenContent())
{
if (blockLevelContentElement.Name == W.p)
{
currentItem = ListItemRetriever.RetrieveListItem(wordDoc, blockLevelContentElement);
//currentItemText = blockLevelContentElement
// .LogicalChildrenContent(W.r)
// .LogicalChildrenContent(W.t)
// .Select(t => (string)t)
// .StringConcatenate();
currentItemText = blockLevelContentElement
.LogicalChildrenContent(W.r)
.Select(t =>
{
if (t.LogicalChildrenContent(W.br).Count() > 0)
{
//Adding line Break for Steps because it is truncated when typecaste with String
t.SetElementValue(W.br, "<br />");
}
return (string)t;
}
).StringConcatenate();
continue;
}
// If element is not a paragraph, it must be a table.
foreach (var row in blockLevelContentElement.LogicalChildrenContent())
{
foreach (var cell in row.LogicalChildrenContent())
{
// Cells are a block-level content container, so can call this method recursively.
OutputBlockLevelContent(wordDoc, cell);
}
}
}
}
catch (Exception ex)
{
}
}
How do I troubleshoot System.Diagnostics trace when it quietly fails to do anything at all?
I'm so glad you asked! This problem happened to me recently. I suspected something in the chain of TraceSwitches, TraceSources and TraceListeners had gone awry. But with no trace and no error messages, I needed more information. The authors of the BCL helpfully put all the diagnostic information in a private list whose values disappear when ever the garbage collector feels like it. Still, the info was good enough and accessible via reflection. It turned out that I had several TraceSource's but the one in question didn't have a Switch set to something other than Off. (Another bad sign would be no listeners or only the "Default" listener)
This is the Page_Load event for a page with a label called DumpText. I'm sure this code could be adapted for Console or WinForms.
protected void Page_Load(object sender, EventArgs e)
{
TraceSource ts = new TraceSource("foo");
List<WeakReference> list = (List<WeakReference>)GetInstanceField(typeof(TraceSource), ts, "tracesources");
Dictionary<string, TraceSource> sources = new Dictionary<string, TraceSource>();
foreach (var weakReference in list)
{
if (!weakReference.IsAlive) continue;
TraceSource source = (weakReference.Target as TraceSource);
if (source == null || source.Name == "foo") continue;
if (sources.ContainsKey(source.Name)) continue;
sources.Add(source.Name, source);
}
StringBuilder sb = new StringBuilder();
foreach (KeyValuePair<string,TraceSource> kvp in sources.OrderBy((x) => x.Key))
{
TraceSource source = kvp.Value;
if (source == null)
{
continue;
}
sb.Append("<h3>");
sb.Append(source.Name);
sb.Append(" - ");
sb.Append(source.Switch.Level);
sb.Append("</h3>");
if (source.Switch.Level == SourceLevels.Off)
{
continue;
}
foreach (TraceListener l in source.Listeners)
{
sb.Append(l.Name);
sb.Append(" - ");
sb.Append(l.GetType().ToString());
sb.Append("<br/>");
foreach (string att in l.Attributes.Values)
{
sb.Append(" ");
sb.Append(att);
sb.Append(",");
}
}
sb.Append("<br/>");
}
this.DumpText.Text = sb.ToString();
}
internal static object GetInstanceField(Type type, object instance, string fieldName)
{
BindingFlags bindFlags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic
| BindingFlags.Static;
FieldInfo field = type.GetField(fieldName, bindFlags);
return field.GetValue(instance);
}
I am using the following code to get a record from my database table tblDatabases. I then populate Controls on a Form based on the value. I have used some functions to get the values needed for displaying in a text box (e.g. the display value is different than the value.
The DetailData is an object in my base form class. Initially I just got the record from the table as is and I was able to cast the DetailData to the tblDatabases and use reflection to get all of the values for the data and populate the controls on my form.
I am no longer able to cast the DetailData to my table because of the anonymous types.
I would like to be able to use reflection on the DetailData to get the values.
Thanks,
Brad
DetailData = (from db in priorityDataContext.tblDatabases
where db.DatabaseID == Id
select new
{
db.DatabaseID,
db.DatabaseName,
db.Purpose,
db.BackEnd,
db.FrontEnd,
db.Version,
db.ProducesReports,
db.MultiUser,
db.UserDescription,
Developer = priorityDataContext.func_get_employee_name(db.Developer),
DeptOwner = priorityDataContext.func_get_dept_name(db.DeptOwner),
db.Source_Code_Path,
db.Notes,
db.Active,
db.row_entry_time_stamp,
row_oper_name = priorityDataContext.func_get_employee_name(db.Developer),
db.row_last_chng_time_stamp,
row_last_chng_oper_name = priorityDataContext.func_get_employee_name(db.Developer)
}).SingleOrDefault();
protected virtual void PopulateDetailControlsA(List<Control> controlContainers, string srcDataTableName)
{
switch (srcDataTableName)
{
case "tblDatabase" :
break;
}
var database = (tblDatabase) DetailData;
var type = typeof(tblDatabase);
var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
foreach (var controlContainer in controlContainers)
{
foreach (var propertyInfo in properties)
{
if (!ControlExists(controlContainer, propertyInfo.Name)) continue;
var txtExtControl = controlContainer.Controls[propertyInfo.Name] as ExtendedTextBox;
if (txtExtControl != null)
{
try
{
var value = propertyInfo.GetValue(database, null).ToString();
txtExtControl.Text = value;
}
catch (NullReferenceException)
{
}
continue;
}
var lnklblControl = controlContainer.Controls[propertyInfo.Name] as ExtendedLinkLabel;
if (lnklblControl != null)
{
try
{
var value = propertyInfo.GetValue(database, null).ToString();
lnklblControl.Text = value;
}
catch (NullReferenceException)
{
}
continue;
}
var chkControl = controlContainer.Controls[propertyInfo.Name] as ExtendedCheckBox;
if (chkControl != null)
{
try
{
var value = propertyInfo.GetValue(database, null).ToString();
switch (value)
{
case "True":
chkControl.CheckState = CheckState.Checked;
break;
case "False":
chkControl.CheckState = CheckState.Unchecked;
break;
}
}
catch (NullReferenceException)
{
chkControl.CheckState = CheckState.Indeterminate;
}
continue;
}
var cmbControl = controlContainer.Controls[propertyInfo.Name] as ExtendedComboBox;
if (cmbControl != null)
{
try
{
var value = propertyInfo.GetValue(database, null).ToString();
cmbControl.ValueMember = value;
}
catch (Exception ex)
{
}
continue;
}
}
}
}
What technology are you using for your UI? If you could use binding you would not need to worry about reflection on the anonymous type and then could also use converters if you need to format/calculate values from this.
From your response can't you just use the connection to the linq and then bind this to the combo box?
private void Form1_Load(object sender, System.EventArgs e)
{
var item = new DataClassesDataContext();
var stuff = item.Entity.Where(c => c.Property.Contains("something"));
comboBox1.DataSource = stuff;
comboBox1.DisplayMember = "Name";
comboBox1.ValueMember = "PIN";
}