I am new to programming in C#
I want to read the csv file and update the fields in elastic search. I already have this function made by someone else and I want to call this function and update fields.
public static bool UpdateDocumentFields(dynamic updatedFields, IHit<ClientDocuments> metaData)
{
var settings = (SystemWideSettings)SystemSettings.Instance;
if (settings == null)
throw new SettingsNotFoundException("System settings have not been initialized.");
if (ElasticSearch.Connect(settings.ElasticAddressString(), null, out ElasticClient elasticClient, out string status))
{
return ElasticSearch.UpdateDocumentFields(updatedFields, metaData, elasticClient);
}
return false;
}
what I have done myself so far is :
private void btnToEs_Click(object sender, EventArgs e)
{
var manager = new StateOne.FileProcessing.DocumentManager.DocumentManager();
var path = "C:/Temp/MissingElasticSearchRecords.csv";
var lines = File.ReadLines(path);
foreach (string line in lines)
{
var item = ClientDocuments.GetClientDocumentFromFilename(line);
if (item != null)
{
var output = new List<ClientDocuments>();
manager.TryGetClientDocuments(item.AccountNumber.ToString(), 100, out output);
if (output!= null && output.Count <= 0)
{
var docs = new List<ClientDocuments>();
//var doc = docs.Add();
// var doc = docs.Add();
//docs.Add(doc);
foreach (var doc in output)
{
if (!item.FileExists)
{
//insert in elastic search
manager.UpdateDocumentFields(output, );
}
else
{
//ignore
}
}
My problem here is manager.updateDocumentFields() is a function. I am calling it but what I need to pass as a parameter? Thanks in advance.
Related
I have asked this question yesterday and i didn't get good response. i am working on a resx file. I have read the file and load it on data-gridview. now i wanted to be able to edit from the file and save.I have tried many ways but i didn't come with the solution. yesterday i tried this code below. I don't know how i can edit. please help me.
private void btnSave_Click(object sender, EventArgs e)
{
foreach (DataGridViewRow _row in Gridview_Output.Rows)
{
DataRow dt1 = oDataTable.NewRow();
for (int i = 0; i < Gridview_Output.ColumnCount; i++)
{
Gridview_Input.SelectedRows[0].Cells[1].Value = oDataSet.Tables["data"].Rows[0][1].ToString();
Gridview_Input.SelectedRows[0].Cells[2].Value = oDataSet.Tables["data"].Rows[0][2].ToString();
Gridview_Input.SelectedRows[0].Cells[3].Value = oDataSet.Tables["data"].Rows[0][3].ToString();
Gridview_Input.SelectedRows[0].Cells[4].Value = oDataSet.Tables["data"].Rows[0][4].ToString();
oDataTable.Rows.Add(dt1);
}
oDataSet.Tables.Add(oDataTable);
oDataSet.WriteXml(PathSelection);
}
This will help you almost the way you want it.
Code snippet from Modifying .resx file in c#
public static void UpdateResourceFile(Hashtable data, String path)
{
Hashtable resourceEntries = new Hashtable();
//Get existing resources
ResXResourceReader reader = new ResXResourceReader(path);
if (reader != null)
{
IDictionaryEnumerator id = reader.GetEnumerator();
foreach (DictionaryEntry d in reader)
{
if (d.Value == null)
resourceEntries.Add(d.Key.ToString(), "");
else
resourceEntries.Add(d.Key.ToString(), d.Value.ToString());
}
reader.Close();
}
//Modify resources here...
foreach (String key in data.Keys)
{
if (!resourceEntries.ContainsKey(key))
{
String value = data[key].ToString();
if (value == null) value = "";
resourceEntries.Add(key, value);
}
}
//Write the combined resource file
ResXResourceWriter resourceWriter = new ResXResourceWriter(path);
foreach (String key in resourceEntries.Keys)
{
resourceWriter.AddResource(key, resourceEntries[key]);
}
resourceWriter.Generate();
resourceWriter.Close();
}
Here's my ICommand:
public ICommand ConfirmLotSavedCommand {
get
{
return new RelayCommand(ConfirmLotSaved);
}
}
The problem is I have deserialized data that I want to store into database after a user clicks confirm button. If the user does not click on confirm or the lot number already exists, then I don't want to save the deserialized string in db.
I had trouble calling a function with one parameter inside my ConfirmLotSaved() method because of scope.
So I created a set the deserialized lot as a field and put the code to save to db inside of ConfirmLotSaved(). However, the field is null for some strange reason... I'm not sure why.
Here's my attempt:
private LotInformation lot; //field that is supposed to contain all the deserialized info
private void ConfirmLotSaved()
{
using (var db = new DDataContext())
{
bool lotNumDbExists = db.LotInformation.Any(r => r.lot_number == DeserialLotNumber);
if (lotNumDbExists == false)
{
successWindow.Message = "Successfully Saved Lot";
dialogService.ShowDialog(successWindow.Message, successWindow);
LotInformation newLot = new LotInformation();
if (newLot != null)
{
newLot.Id = lot.Id;
newLot.lot_number = lot.lot_number;
newLot.exp_date = lot.exp_date;
LotNumber = Lot.lot_number;
ExpirationDate = Lot.exp_date.ToString();
foreach (Components comp in lot.Components)
{
newLot.Components.Add(comp);
}
ComponentsList = newLot.Components;
foreach (Families fam in lot.Families)
{
newLot.Families.Add(fam);
}
FamiliesList = newLot.Families;
try
{
db.LotInformation.Add(newLot);
db.SaveChanges();
//Grabs the lot_number column from db that is distinct
var lotNum = db.LotInformation.GroupBy(i => i.lot_number).Select(group => group.FirstOrDefault());
//Loops through the lot numbers column in db and converts to list
foreach (var item in lotNum)
{
Console.WriteLine(item.lot_number);
}
LotNumList = lotNum.ToList();
Console.WriteLine("successfully");
}
catch
{
//TODO: Add a Dialog Here
}
}
else if (lotNumDbExists == true)
{
// Inform user that the lot_number already exists
errorWindow.Message = LanguageResources.Resource.Lot_Exists_Already;
dialogService.ShowDialog(LanguageResources.Resource.Error, errorWindow);
logger.writeErrLog(LanguageResources.Resource.Lot_Exists_Already);
return;
}
}
}
}
Deserialization function to see where lot is grabbing data:
public void DeserializedStream(string filePath)
{
XmlRootAttribute xRoot = new XmlRootAttribute();
xRoot.ElementName = "lot_information";
xRoot.IsNullable = false;
// Create an instance of lotinformation class.
LotInformation lot = new LotInformation();
// Create an instance of stream writer.
TextReader txtReader = new StreamReader(filePath);
// Create and instance of XmlSerializer class.
XmlSerializer xmlSerializer = new XmlSerializer(typeof(LotInformation), xRoot);
// DeSerialize from the StreamReader
lot = (LotInformation)xmlSerializer.Deserialize(txtReader);
// Close the stream reader
txtReader.Close();
LotInformation newList = new LotInformation();
using (var db = new DDataContext())
{
bool isDuplicate = db.LotInformation.Any(r => r.lot_number == lot.lot_number);
if (newList != null && isDuplicate == false)
{
newList.Id = lot.Id;
newList.lot_number = lot.lot_number;
newList.exp_date = lot.exp_date;
DeserialLotNumber = newList.lot_number;
DeserialExpirationDate = newList.exp_date.ToString();
foreach (Component comp in lot.Components)
{
newList.Components.Add(comp);
}
DeserialComponentsList = newList.Components;
foreach (Families fam in lot.Families)
{
newList.Families.Add(fam);
}
DeserialFamiliesList = newList.Families;
}
else if (isDuplicate == true)
{
DeserialAnalytesList = null;
DeserialFamiliesList = null;
// Inform user that the lot_number already exists
errorWindow.Message = LanguageResources.Resource.Lot_Exists_Already;
dialogService.ShowDialog(LanguageResources.Resource.Error, errorWindow);
logger.writeErrLog(LanguageResources.Resource.Lot_Exists_Already);
return;
}
}
}
I figured out what was wrong:
After setting private LotInformation lot; field before constructor, I redeclared locally my mistake:
LotInformation lot = new LotInformation();
Changed it to:
lot = new LotInformation();
and it works.
I suggest you to use RelayCommand's generic edition http://www.kellydun.com/wpf-relaycommand-with-parameter/
It will allow you to pass lot to your command from view, all you need to store lot in current DataContext.
I have a a desktop application with a System.Windows.Form containing some TextBox controls. I need to validate the control values against restrictions of an xml schema.
For each TextBox I can retrieve the relevant XmlSchemaSimpleTypeRestriction from its type and then use a method as follows to validate its value:
public static bool Validate(XmlSchemaSimpleTypeRestriction restriction, string value)
{
bool isENum = false;
bool isValidEnum = false;
foreach (var item in restriction.Facets)
{
XmlSchemaLengthFacet lengthFacet = item as XmlSchemaLengthFacet;
if (lengthFacet != null)
{
int length = Int32.Parse(lengthFacet.Value);
if (!(value.Length == length))
return false;
}
XmlSchemaMinLengthFacet minLenghtFacet = item as XmlSchemaMinLengthFacet;
if (minLenghtFacet != null)
{
int length = Int32.Parse(minLenghtFacet.Value);
if (!(value.Length >= length))
return false;
}
XmlSchemaMaxLengthFacet maxLenghtFacet = item as XmlSchemaMaxLengthFacet;
if (maxLenghtFacet != null)
{
int length = Int32.Parse(maxLenghtFacet.Value);
if (!(value.Length <= length))
return false;
}
XmlSchemaPatternFacet patternFacet = item as XmlSchemaPatternFacet;
if (patternFacet != null)
{
Regex re = new Regex(patternFacet.Value);
if (!re.IsMatch(value))
return false;
}
XmlSchemaEnumerationFacet enumFacet = item as XmlSchemaEnumerationFacet;
if (patternFacet != null)
{
isENum = true;
if (StringComparer.InvariantCultureIgnoreCase.Compare(value, enumFacet.Value) == 0)
isValidEnum = true;
}
if (isENum && (!isValidEnum))
return false;
return true;
}
I am going to use this method in the Validating event of the controls. Is there any simpler way of doing this?
Ok, it's a little more complicated than I initially thought. Basically, you need create an XmlSchema that expects a single element with the provided restriction. Then you create an XML element with the provided value and validate it against the schema using an XmlReader:
public static bool Validate(XmlSchemaSimpleTypeRestriction restriction, string value)
{
var schema = new XmlSchema();
schema.Items.Add(new XmlSchemaElement
{
Name = "value",
SchemaType = new XmlSchemaSimpleType { Content = restriction }
});
var schemaSet = new XmlSchemaSet();
schemaSet.Add(schema);
var readerSettings = new XmlReaderSettings
{
ValidationType = ValidationType.Schema,
ValidationFlags = XmlSchemaValidationFlags.ReportValidationWarnings,
Schemas = schemaSet
};
string xml = new XElement("value", value).ToString();
try
{
var reader = XmlReader.Create(new StringReader(xml), readerSettings);
while (reader.Read()) ;
return true;
}
catch (XmlSchemaValidationException)
{
return false;
}
}
I tested it with this code:
static void Main(string[] args)
{
var restriction = new XmlSchemaSimpleTypeRestriction { BaseTypeName = new XmlQualifiedName("string", "http://www.w3.org/2001/XMLSchema") };
restriction.Facets.Add(new XmlSchemaMinLengthFacet { Value = "3" });
Console.WriteLine(Validate(restriction, "str"));
}
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
i need to extract the text of a specific page from a XPS document.
The extracted text should be written in a string. I need this to read out the extracted text using Microsofts SpeechLib.
Please examples only in C#.
Thanks
Add References to ReachFramework and WindowsBase and the following using statement:
using System.Windows.Xps.Packaging;
Then use this code:
XpsDocument _xpsDocument=new XpsDocument("/path",System.IO.FileAccess.Read);
IXpsFixedDocumentSequenceReader fixedDocSeqReader
=_xpsDocument.FixedDocumentSequenceReader;
IXpsFixedDocumentReader _document = fixedDocSeqReader.FixedDocuments[0];
IXpsFixedPageReader _page
= _document.FixedPages[documentViewerElement.MasterPageNumber];
StringBuilder _currentText = new StringBuilder();
System.Xml.XmlReader _pageContentReader = _page.XmlReader;
if (_pageContentReader != null)
{
while (_pageContentReader.Read())
{
if (_pageContentReader.Name == "Glyphs")
{
if (_pageContentReader.HasAttributes)
{
if (_pageContentReader.GetAttribute("UnicodeString") != null )
{
_currentText.
Append(_pageContentReader.
GetAttribute("UnicodeString"));
}
}
}
}
}
string _fullPageText = _currentText.ToString();
Text exists in Glyphs -> UnicodeString string attribute. You have to use XMLReader for fixed page.
Method that returns text from all pages (modified Amir:s code, hope that's ok):
/// <summary>
/// Get all text strings from an XPS file.
/// Returns a list of lists (one for each page) containing the text strings.
/// </summary>
private static List<List<string>> ExtractTextFromXps(string xpsFilePath)
{
var xpsDocument = new XpsDocument(xpsFilePath, FileAccess.Read);
var fixedDocSeqReader = xpsDocument.FixedDocumentSequenceReader;
if (fixedDocSeqReader == null)
return null;
const string UnicodeString = "UnicodeString";
const string GlyphsString = "Glyphs";
var textLists = new List<List<string>>();
foreach (IXpsFixedDocumentReader fixedDocumentReader in fixedDocSeqReader.FixedDocuments)
{
foreach (IXpsFixedPageReader pageReader in fixedDocumentReader.FixedPages)
{
var pageContentReader = pageReader.XmlReader;
if (pageContentReader == null)
continue;
var texts = new List<string>();
while (pageContentReader.Read())
{
if (pageContentReader.Name != GlyphsString)
continue;
if (!pageContentReader.HasAttributes)
continue;
if (pageContentReader.GetAttribute(UnicodeString) != null)
texts.Add(pageContentReader.GetAttribute(UnicodeString));
}
textLists.Add(texts);
}
}
xpsDocument.Close();
return textLists;
}
Usage:
var txtLists = ExtractTextFromXps(#"C:\myfile.xps");
int pageIdx = 0;
foreach (List<string> txtList in txtLists)
{
pageIdx++;
Console.WriteLine("== Page {0} ==", pageIdx);
foreach (string txt in txtList)
Console.WriteLine(" "+txt);
Console.WriteLine();
}
private string ReadXpsFile(string fileName)
{
XpsDocument _xpsDocument = new XpsDocument(fileName, System.IO.FileAccess.Read);
IXpsFixedDocumentSequenceReader fixedDocSeqReader
= _xpsDocument.FixedDocumentSequenceReader;
IXpsFixedDocumentReader _document = fixedDocSeqReader.FixedDocuments[0];
FixedDocumentSequence sequence = _xpsDocument.GetFixedDocumentSequence();
string _fullPageText="";
for (int pageCount = 0; pageCount < sequence.DocumentPaginator.PageCount; ++pageCount)
{
IXpsFixedPageReader _page
= _document.FixedPages[pageCount];
StringBuilder _currentText = new StringBuilder();
System.Xml.XmlReader _pageContentReader = _page.XmlReader;
if (_pageContentReader != null)
{
while (_pageContentReader.Read())
{
if (_pageContentReader.Name == "Glyphs")
{
if (_pageContentReader.HasAttributes)
{
if (_pageContentReader.GetAttribute("UnicodeString") != null)
{
_currentText.
Append(_pageContentReader.
GetAttribute("UnicodeString"));
}
}
}
}
}
_fullPageText += _currentText.ToString();
}
return _fullPageText;
}
Full Code of Class:
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Windows.Xps.Packaging;
namespace XPS_Data_Transfer
{
internal static class XpsDataReader
{
public static List<string> ReadXps(string address, int pageNumber)
{
var xpsDocument = new XpsDocument(address, System.IO.FileAccess.Read);
var fixedDocSeqReader = xpsDocument.FixedDocumentSequenceReader;
if (fixedDocSeqReader == null) return null;
const string uniStr = "UnicodeString";
const string glyphs = "Glyphs";
var document = fixedDocSeqReader.FixedDocuments[pageNumber - 1];
var page = document.FixedPages[0];
var currentText = new List<string>();
var pageContentReader = page.XmlReader;
if (pageContentReader == null) return null;
while (pageContentReader.Read())
{
if (pageContentReader.Name != glyphs) continue;
if (!pageContentReader.HasAttributes) continue;
if (pageContentReader.GetAttribute(uniStr) != null)
currentText.Add(Dashboard.CleanReversedPersianText(pageContentReader.GetAttribute(uniStr)));
}
return currentText;
}
}
}
that return a list of string data from custom page of custom file.
Is there a possibility to extract plain text from a PDF-File with PdfSharp?
I don't want to use iTextSharp because of its license.
Took Sergio's answer and made some extension methods. I also changed the accumulation of strings into an iterator.
public static class PdfSharpExtensions
{
public static IEnumerable<string> ExtractText(this PdfPage page)
{
var content = ContentReader.ReadContent(page);
var text = content.ExtractText();
return text;
}
public static IEnumerable<string> ExtractText(this CObject cObject)
{
if (cObject is COperator)
{
var cOperator = cObject as COperator;
if (cOperator.OpCode.Name== OpCodeName.Tj.ToString() ||
cOperator.OpCode.Name == OpCodeName.TJ.ToString())
{
foreach (var cOperand in cOperator.Operands)
foreach (var txt in ExtractText(cOperand))
yield return txt;
}
}
else if (cObject is CSequence)
{
var cSequence = cObject as CSequence;
foreach (var element in cSequence)
foreach (var txt in ExtractText(element))
yield return txt;
}
else if (cObject is CString)
{
var cString = cObject as CString;
yield return cString.Value;
}
}
}
I have implemented it somehow similar to how David did it.
Here is my code:
...
{
// ....
var page = document.Pages[1];
CObject content = ContentReader.ReadContent(page);
var extractedText = ExtractText(content);
// ...
}
private IEnumerable<string> ExtractText(CObject cObject)
{
var textList = new List<string>();
if (cObject is COperator)
{
var cOperator = cObject as COperator;
if (cOperator.OpCode.Name == OpCodeName.Tj.ToString() ||
cOperator.OpCode.Name == OpCodeName.TJ.ToString())
{
foreach (var cOperand in cOperator.Operands)
{
textList.AddRange(ExtractText(cOperand));
}
}
}
else if (cObject is CSequence)
{
var cSequence = cObject as CSequence;
foreach (var element in cSequence)
{
textList.AddRange(ExtractText(element));
}
}
else if (cObject is CString)
{
var cString = cObject as CString;
textList.Add(cString.Value);
}
return textList;
}
PDFSharp provides all the tools to extract the text from a PDF. Use the ContentReader class to access the commands within each page and extract the strings from TJ/Tj operators.
I've uploaded a simple implementation to github.