Cast TreeViewItem to XElement? - c#

I'm trying to iterate through the XElement of two collections so I can compare them, but I get the error :
System.InvalidCastException: 'Unable to cast object of type
'System.Windows.Controls.TreeViewItem' to type
'System.Xml.Linq.XElement'.'
My code is:
private void CompareTrees(ItemCollection xml,ItemCollection xsd )
{
bool isMatch = false;
string header = string.Empty;
foreach (XElement xexsd in xsd)
{
foreach (XElement xexml in xml)
{
if (xexsd.Name.LocalName + " - " + xexsd.Value == xexml.Name.LocalName + " - " + xexsd.Value)
{
CompareTrees(xml, xsd);
isMatch = true;
break;
}
}
if (isMatch == true)
{
continue;
}
else
{
var item = new ListBoxItem();
lbItems.Items.Add(item);
}
}
}

Apparently the ItemCollection contains TreeViewItems. Try this:
foreach (TreeViewItem tvi in xml.OfType<TreeViewItem>())
{
XElement xexsd = tvi.DataContext as XElement;
if (xexsd != null && xexsd.Name.LocalName + " - " + xexsd.Value == xexml.Name.LocalName + " - " + xexsd.Value)
{
CompareTrees(xml, xsd);
isMatch = true;
break;
}
}

Related

pass datatype of custom entity into function c#

I am having four different Datatypes, all as Lists:
List<DataRowTenant> tenantlist;
List<DataRowOwner> ownerlist;
List<DataRowCustomer> customerlist;
List<DataRowHWDevice> hwdevicelist;
List<DataRowHWCategory> hwcategorslist;
And i want to be able to export them into a CSV. Currently i copied my CSV-export Function five times, just with a different name and parameter definition. So, i was asking myself if i can somehow identify the Datatype of a variable and pass that also in the function?
i already tried the approaches in this Thread, but i couldn't get it to work.
my CSV-Export function is as follows:
public static void ExportOwnerCSV(List<DataRowOwner> list)
{
string columnNames = "";
string[] outputCsv = new string[list.Count + 1];
if (list.Count > 0)
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "CSV (*.csv)|*.csv";
sfd.FileName = "Output.csv";
bool fileError = false;
bool? result = sfd.ShowDialog();
if (result == true)
{
if (File.Exists(sfd.FileName))
{
try
{
File.Delete(sfd.FileName);
}
catch (IOException ex)
{
fileError = true;
MessageBox.Show("It wasn't possible to write the data to the disk." + ex.Message);
}
}
if (!fileError)
{
try
{
//var columnCount = DataRowOwner.GetType().GetFields();
var list_single = list[0];
var columnCount = list_single.GetType().GetProperties(BindingFlags.DeclaredOnly |
BindingFlags.Public |
BindingFlags.Instance);
//Header schreiben
foreach (PropertyInfo item in columnCount)
{
outputCsv[0] += "\"" + item.Name + "\"" + ",";
}
//Body schreiben
int row = 1;
foreach (var DataRowitem in list)
{
foreach (PropertyInfo item in columnCount)
{
outputCsv[row] += "\"" + item.GetValue(list[row - 1]) + "\"" + ",";
}
row++;
}
File.WriteAllLines(sfd.FileName, outputCsv, Encoding.UTF8);
MessageBox.Show("Data Exported Successfully!", "Info");
}
catch (Exception ex)
{
MessageBox.Show("Error :" + ex.Message);
}
}
}
}
else
{
MessageBox.Show("No Record To Export!", "Info");
}
}
thanks, any suggestions are appreciated.
You can declare the function as a generic function, where the type argument of the function is used as the type argument of the list parameter like so:
public static void ExportOwnerCSV<T>(IList<T> list)
{
...
}

SGML formating Issue

I have an requirement to read the SGML file and replace if the symbol like comma(,) or full stop (.) then I need to change the symbols and save with the same SGML file itself but I am facing the format issue after replacing the content.
Below is my code and my final output would be store with the same .sgm format.
The below code is working but after replacing the values the output format is differs. Can you suggest for this scenario
Main method:
string resultValue = HTMLToEntity(ReplaceSGML(sbContent.ToString()));
StringReader sr = new StringReader(resultValue.ToString());
SgmlReader reader = new SgmlReader();
reader.WhitespaceHandling = WhitespaceHandling.All;
reader.CaseFolding = Sgml.CaseFolding.ToLower;
reader.InputStream = sr;
StringWriter sw = new StringWriter();
XmlTextWriter w = new XmlTextWriter(sw);
w.Formatting = System.Xml.Formatting.Indented;
w.WriteStartDocument();
reader.Read();
while (!reader.EOF)
{
w.WriteNode(reader, true);
}
//File.WriteAllText(#"C:\Output\test.sgm", );
w.Flush();
w.Close();
Method : ReplaceSGML
private static string ReplaceSGML(string html)
{
XmlDocument xml = new XmlDocument();
xml.Load(_xmlEnglishPath);
XmlNodeList resources = xml.SelectNodes("root/data");
_htmlEnglishDictonaries = new Dictionary<string, string>();
_htmlEnglishDictonaries.Add(";", "{After1Space}"); // replacing semicolon into {After1space}
_htmlEnglishDictonaries.Add(":", "{Before1Space}"); // replacing colon into {Before1Space}
_htmlEnglishDictonaries.Add(".", "{Before1Space}"); // replacing . into {Before1Space}
string line = string.Empty;
StringReader reader = new StringReader(html);
while (reader.Peek() > -1)
{
line = reader.ReadLine();
foreach (var events in _htmlEnglishDictonaries)
{
if (line.Contains(events.Key))
{
// Rule should be implement
// <!-- Replacetext 1.{After1Space}, 2.{Before1Space}, 3.{NoSpace}, 4. {After1LetterCaps} -->
int idx;
if (events.Value.ToLower().Trim() == "{after1space}")
{
idx = line.IndexOf(events.Key) + events.Key.Length;
if (line[idx].ToString() != " ")
{
line = line.Replace(events.Key, events.Key + " ");
}
}
if (events.Value.ToLower().Trim() == "{before1space}")
{
idx = line.IndexOf(events.Key);
if (line[idx].ToString() != " ")
{
line = line.Replace(events.Key, " " + events.Key);
}
}
if (events.Value.ToLower().Trim() == "{before1space},{after1space}")
{
idx = line.IndexOf(events.Key);
if (line[idx].ToString() != " ")
{
line = line.Replace(events.Key, " " + events.Key + " ");
}
}
if (events.Value.ToLower().Trim() == "{nospace}")
{
idx = line.IndexOf(events.Key);
if (line[idx].ToString() != " ")
{
line = line.Replace(events.Key, " " + events.Key);
}
}
if (events.Value.ToLower().Trim() == "{after1lettercaps}")
{
idx = line.IndexOf(events.Key) + events.Key.Length;
if (line[idx].ToString() != " ")
{
if (line[idx + 1].ToString() != " ")
{
line = line.Replace(events.Key, " " + events.Key + line[idx + 1].ToString().ToUpper());
}
else
{
line = line.Replace(events.Key, " " + events.Key);
}
}
}
}
}
}
return line.ToString();
}
Thanks in advance

Get nunit (2.5.10) TestCases with parameters from dll

I got a compiled dll and I need to run every TestCase from this dll seperately with the nunit console tool, one test after the other. To run a TestCase I need to read the name and the parameters of the TestCase from the dll.
I tried reflection, but so far I ran into several problems. Is there a simple way to get the whole TestCase to run it with the nunit console? I heard of the --explore option of nunit3 to get all information of a dll, but unfortunately I have to use the version 2.5.10.
First of all I do not get the amount of methods defined when I try this:
List<MethodInfo> testMethods = new List<MethodInfo>(from type in
assembly.GetTypes()
from method in type.GetMethods()
where method.IsDefined(typeof(TestAttribute)) ||
method.IsDefined(typeof(TestCaseAttribute))
select method);
Afterwards I iterate over the items of the list and try to get the corresponding parameters with "CustomAttributeData.GetCustomAttributes(method)". But every TestCase has a different signature, so its difficult building the form nunit-console wants, like so: methodname(param1,...,paramN)
foreach (CustomAttributeData cad in attributes)
{
String test = method.Name + "(";
String attr = String.Empty;
foreach (CustomAttributeTypedArgument cata in cad.ConstructorArguments)
{
if (cata.Value.GetType() == typeof(ReadOnlyCollection<CustomAttributeTypedArgument>))
{
foreach (CustomAttributeTypedArgument cataElement in
(ReadOnlyCollection<CustomAttributeTypedArgument>)cata.Value)
{
if (cataElement.ArgumentType.Name == "String")
{
String elem = String.Empty;
if (cataElement.Value == null)
{
attr += "null" + ",";
}
else
{
elem = cataElement.Value.ToString().Replace(#"\", #"\\");
//escape quotation marks
attr += #"\" + "\"" + elem + #"\" + "\"" + ",";
}
}
else if (cataElement.ArgumentType.IsEnum)
{
var enumName = cataElement.ArgumentType.Name;
foreach (var fieldInfo in cataElement.ArgumentType.GetFields())
{
if (fieldInfo.FieldType.IsEnum)
{
var fName = fieldInfo.Name;
var fValue = fieldInfo.GetRawConstantValue();
if (cataElement.Value.ToString().Equals(fValue.ToString()))
{
attr += fName + ",";
}
}
}
}
else
{
attr += cataElement.Value + ",";
}
}
}
else if (cata.ArgumentType.IsEnum)
{
var enumName = cata.ArgumentType.Name;
foreach (var fieldInfo in cata.ArgumentType.GetFields())
{
if (fieldInfo.FieldType.IsEnum)
{
var fName = fieldInfo.Name;
var fValue = fieldInfo.GetRawConstantValue();
if (cata.Value.ToString().Equals(fValue.ToString()))
{
attr = fName;
}
}
}
}
else if (cata.Value.GetType() == typeof(String))
{
String elem = String.Empty;
if (cata.Value == null)
{
attr = "null";
}
else
{
elem = cata.Value.ToString().Replace(#"\", #"\\");
attr = #"\" + "\"" + elem + #"\" + "\"";
}
}
else
{
attr = cata.ToString();
}
//do stuff to get form of TestCase
Indeed it needs to be refactored, but I wonder if there is an easier way to get all TestCases and its Parameters.

Openxml in C# updating only the first MERGEFIELD in a paragraph

I have approximately 10 MERGEFIELD in a document that I'm trying to replace the Text with some value. Here's the code.
using (WordprocessingDocument document = WordprocessingDocument.Open(destinationFileName, true))
{
document.ChangeDocumentType(DocumentFormat.OpenXml.WordprocessingDocumentType.Document);
MainDocumentPart docPart = document.MainDocumentPart;
docPart.AddExternalRelationship("http://schemas.openxmlformats.org/officeDocument/2006/relationships/attachedTemplate", new Uri(destinationFileName, UriKind.RelativeOrAbsolute));
docPart.Document.Save();
IEnumerable<FieldChar> fldChars = document.MainDocumentPart.RootElement.Descendants<FieldChar>();
if (fldChars == null) { return; }
string fieldList = string.Empty;
FieldChar fldCharStart = null;
FieldChar fldCharEnd = null;
FieldChar fldCharSep = null;
FieldCode fldCode = null;
string fldContent = String.Empty;
int i = 1;
foreach(var fldChar in fldChars)
{
System.Diagnostics.Debug.WriteLine(i + ": " + fldChar);
i++;
string fldCharPart = fldChar.FieldCharType.ToString();
System.Diagnostics.Debug.WriteLine("Field Char Length: " + fldChar.Count());
System.Diagnostics.Debug.WriteLine("Field Char part: " + fldCharPart);
switch(fldCharPart)
{
case "begin": // start of the field
fldCharStart = fldChar;
System.Diagnostics.Debug.WriteLine("Field Char Start: " + fldCharStart);
// get the field code, which will be an instrText element
// either as sibling or as a child of the parent sibling
fldCode = fldCharStart.Parent.Descendants<FieldCode>().FirstOrDefault();
System.Diagnostics.Debug.WriteLine("Field Code: " + fldCode);
if (fldCode == null)
{
fldCode = fldCharStart.Parent.NextSibling<Run>().Descendants<FieldCode>().FirstOrDefault();
System.Diagnostics.Debug.WriteLine("New Field Code: " + fldCode);
}
if (fldCode != null && fldCode.InnerText.Contains("MERGEFIELD"))
{
fldContent = getFieldValue(query, prescriber, fldCode.InnerText);
fieldList += fldContent + "\n";
System.Diagnostics.Debug.WriteLine("Field content: " + fldContent);
}
break;
case "end": // end of the field
fldCharEnd = fldChar;
System.Diagnostics.Debug.WriteLine("Field char end: " + fldCharEnd);
break;
case "separate": // complex field with text result
fldCharSep = fldChar;
break;
default:
break;
}
if((fldCharStart != null) && (fldCharEnd != null))
{
if(fldCharSep != null)
{
Text elemText = (Text)fldCharSep.Parent.NextSibling().Descendants<Text>().FirstOrDefault();
elemText.Text = fldContent;
System.Diagnostics.Debug.WriteLine("Element text: " + elemText);
// Delete all field chas with their runs
DeleteFieldChar(fldCharStart);
DeleteFieldChar(fldCharEnd);
DeleteFieldChar(fldCharSep);
fldCode.Remove();
}
else
{
Text elemText = new Text(fldContent);
fldCode.Parent.Append(elemText);
fldCode.Remove();
System.Diagnostics.Debug.WriteLine("Element Text !sep: " + elemText);
DeleteFieldChar(fldCharStart);
DeleteFieldChar(fldCharEnd);
DeleteFieldChar(fldCharSep);
}
fldCharStart = null;
fldCharEnd = null;
fldCharSep = null;
fldCode = null;
fldContent = string.Empty;
}
}
System.Diagnostics.Debug.WriteLine("Field list: " + fieldList);
}
It works to some extent. The problem is when there are more than one field in a paragraph. I have about 4 merge fields in one paragraph in this document, and one field in each paragraph after that. Only the first merge field in the paragraph is being updated and the rest fields in the paragraphs is untouched. Then, it moves to the next paragraph and looks for the field. How can I fix this?
Looks like you are over complicating a simple Mailmerge replacement. Instead of looping through paragraphs you could rather get all mailmerge fields within a document and replace them.
private const string FieldDelimeter = " MERGEFIELD ";
foreach (FieldCode field in doc.MainDocumentPart.RootElement.Descendants<FieldCode>())
{
var fieldNameStart = field.Text.LastIndexOf(FieldDelimeter, System.StringComparison.Ordinal);
var fieldName = field.Text.Substring(fieldNameStart + FieldDelimeter.Length).Trim();
foreach (Run run in doc.MainDocumentPart.Document.Descendants<Run>())
{
foreach (Text txtFromRun in run.Descendants<Text>().Where(a => a.Text == "«" + fieldName + "»"))
{
txtFromRun.Text = "Replace what the merge field here";
}
}
}
doc.MainDocumentPart.Document.Save();
doc is of type WordprocessingDocument.
This will replace all merge fields regardless of the amount of fields in a paragraph.

C# Error Displaying The Xml Element in DataGridView

The purpose of the code is reading the xml elements and display every element under related column name in datagridview.
So, here I have my code:
IEnumerable<XElement> tables = xelement.Elements(df + "Table");
foreach (XElement table in tables)
{
//Get name from TableName node
XElement tableNameNode = table.Element(df + "TableName");
tbTableName.Text = tableNameNode.Value.ToString();
XElement numberRows = table.Element(df + "NumberOfRows");
tbNumRows.Text = numberRows.Value.ToString();
string tableName = tableNameNode.Value;
TableData td = new TableData(CurrentProject.CurrentSchema.FindTable(tableName));
td.PopulateFieldData();
// tableDataList.TryGetValue(tableName, out td);
tableDataList.Add(tableName, td);
//If you open the project after you save it or open it, exception throws: Already Added Key!
IEnumerable<XElement> fields = table.Elements(df + "Field");
foreach (XElement field in fields)
{
XElement fieldNameNode = field.Element(df + "Name");
string fieldName = fieldNameNode.Value;
FieldData fd = td.FieldList[fieldName];
IEnumerable<XElement> fieldProps = field.Descendants();
foreach (XElement fieldProp in fieldProps)
{
string fieldPropertyName = fieldProp.Name.ToString();
if (fieldPropertyName == "Name")
{
fd.Name = fieldProp.Value;
}
if (fieldPropertyName == "Type")
{
fd.DataType = fieldProp.Value;
}
if (fieldPropertyName == "Size")
{
int i = 0;
int.TryParse(fieldProp.Value.ToString(), out i);
fd.Size = i;
}
if (fieldPropertyName == "Nullable")
{
if (fieldProp.Value.ToString() == "True")
fd.Nullable = true;
else
fd.Nullable = false;
}
if (fieldPropertyName == "ContentSource")
{
fd.contentSource = fieldProp.Value;
}
if (fieldPropertyName == "ConstantValue")
{
fd.constantValue = fieldProp.Value;
}
if (fieldPropertyName == "RandomValue")
{
fd.averageSize = fieldProp.Value;
}
if (fieldPropertyName == "List")
{
fd.pickList = fieldProp.Value;
}
}
dataGridView1.Rows.Add(fd.Name, fd.DataType, fd.Size, fd.Nullable);
string ColumnName = dataGridView1.CurrentRow.Cells[0].Value.ToString();
this.tableDataList.TryGetValue(tbTableName.Text, out td);
if (td != null)
{
td.FieldList.TryGetValue(ColumnName, out fd);
}
foreach (var fdl in td.FieldList)
{
if (td != null && fd != null)
{
if (fd.contentSource == "Constant")
{
dataGridView1.CurrentRow.Cells[4].Value = fd.contentSource + "(" + "Value= " + fd.constantValue + ")";
}
if (fd.contentSource == "List")
{
dataGridView1.CurrentRow.Cells[4].Value = fd.contentSource + "(" + fd.pickList + ")";
}
if (fd.contentSource == "Random")
{
dataGridView1.CurrentRow.Cells[4].Value = fd.contentSource + "(" + fd.averageSize + ")";
}
}
}
}
}
Here is the Xml file I am reading:
<?xml version="1.0"?>
<GeneratorXml>
<SchemaPath>C:\Projects\CoreSchema.xml</SchemaPath>
<GroupName>Documents</GroupName>
-<Table>
<TableName>directory</TableName>
<NumberOfRows>33</NumberOfRows>
-<Field>
<Name>dir_id</Name>
<Type>number</Type>
<Size>10</Size>
<Nullable>False</Nullable>
<ContentSource>Random</ContentSource>
<ConstantValue> </ConstantValue>
<RandomValue>4</RandomValue>
<List> </List>
</Field>
-<Field>
<Name>directory_number</Name>
<Type>number</Type>
<Size>5</Size>
<Nullable>False</Nullable>
<ContentSource>List</ContentSource>
<ConstantValue> </ConstantValue>
<RandomValue> </RandomValue>
<List>Coffee</List>
</Field>
-<Field>
<Name>file_count</Name>
<Type>number</Type>
<Size>5</Size>
<Nullable>False</Nullable>
<ContentSource>Constant</ContentSource>
<ConstantValue>2</ConstantValue>
<RandomValue> </RandomValue>
<List> </List>
</Field>
+<Field>
</Table>
</GeneratorXml>
When I run the code, I only get this GridView:
I think my for loops got a problem, but I can't find it. Thanks in advance for every thoughts.

Categories