Deserialize XML to object in C# using Windows Device Project - c#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.Schema;
using System.IO;
using System.Xml.XmlConfiguration;
using OATAssetTracking.Solution.Presenter;
namespace WindowsFormsApplication2
{
public class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
string path = "SearchDefinition.xml";
XmlSchemaSet schemas = new XmlSchemaSet();
schemas.Add(null, #"D:\searchDefinition.xsd");
Exception firstException = null;
var settings = new XmlReaderSettings
{
Schemas = schemas,
ValidationType = ValidationType.Schema,
ValidationFlags =
XmlSchemaValidationFlags.ProcessIdentityConstraints |
XmlSchemaValidationFlags.ReportValidationWarnings
};
settings.ValidationEventHandler +=
delegate(object sender, ValidationEventArgs args)
{
if (args.Severity == XmlSeverityType.Warning)
{
Console.WriteLine(args.Message);
}
else
{
if (firstException == null)
{
firstException = args.Exception;
}
Console.WriteLine(args.Exception.ToString());
}
};
Search result=null;
using (var input = new StreamReader(path))
{
using (XmlReader reader = XmlReader.Create(input, settings))
{
XmlSerializer ser = new XmlSerializer(typeof(Search));
result = (Search)ser.Deserialize(reader);
}
}
if (firstException != null)
{
throw firstException;
}
MessageBox.Show("Deserialization Done!!!!");
}
}
}
In this one,
Here Search is class name which is generated from XSD
result = (Search)ser.Deserialize(reader);
This above statement works fine in Windows forms Application, but fails to work with Windows Device Project " No errors but just hangs there not executing".

Actually, The problem in the above code was
result = (Search)ser.Deserialize(reader);
XML reader which has been created cannot be used while directly de-serializing it to an object. This kind of above code is supported only in the "Windows Forms Application" in VS2008 and its not getting supported in any kind of "Smart Device Projects".
So, Reader settings can be included and XML errors can be handled by any handlers like ValidationEventHandler.
So, Below code validates the XML against XSD and also de-serializes to the object initialized.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.Schema;
using System.IO;
using OATAssetTracking.Solution.Presenter;
namespace WindowsFormsApplication2
{
public class Program
{
static void Main()
{
string path2 = System.IO.Path.GetDirectoryName(
System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase) + "\\" + "SearchDefinition.xsd";
string path1 = System.IO.Path.GetDirectoryName(
System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase) + "\\" + "SearchDefinition.xml";
XmlSchema schema;
using (var schemaReader = XmlReader.Create(path2))
{
schema = XmlSchema.Read(schemaReader, ValidationEventHandler);
}
var schemas = new XmlSchemaSet();
schemas.Add(schema);
var settings = new XmlReaderSettings();
settings.ValidationType = ValidationType.Schema;
settings.Schemas = schemas;
settings.ValidationFlags =
XmlSchemaValidationFlags.ProcessIdentityConstraints |
XmlSchemaValidationFlags.ReportValidationWarnings;
settings.ValidationEventHandler += ValidationEventHandler;
using (var validationReader = XmlReader.Create(path1, settings))
{
while (validationReader.Read())
{
}
}
MessageBox.Show("XML verified Successfully....");
XmlSerializer ser = new XmlSerializer(typeof(Search));
Search result = ser.Deserialize(new FileStream(path1, FileMode.Open)) as Search;
MessageBox.Show("Deserilization Done Successfully!!!!");
}
private static void ValidationEventHandler(object sender, ValidationEventArgs args)
{
if (args.Severity == XmlSeverityType.Error)
{
throw args.Exception;
}
}
}
}

Related

How to replace text in Word document using Openxml

I have a simple word document with only a single word "$Hello$". I'm trying to change "$Hello$" to "Goodbye" but nothing happens and there's no errors. How can I get the code working? "$Hello$" is in a paragraph.
using System;
using System.IO;
using System.Text.RegularExpressions;
using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Wordprocessing;
namespace OpenXMLTests
{
class Program
{
static void Main(string[] args)
{
String document = "TestDoc.docx";
using (WordprocessingDocument doc = WordprocessingDocument.Open(document, true))
{
Body body = doc.MainDocumentPart.Document.Body;
foreach (Table t in body.Descendants<Table>())
{
String tableName = t.GetFirstChild<TableProperties>().TableCaption.Val;
Console.WriteLine(tableName);
}
string docText = null;
using (StreamReader sr = new StreamReader(doc.MainDocumentPart.GetStream())) //Reads file to string
{
docText = sr.ReadToEnd();
}
docText = docText.Replace("$Hello$", "Goodbye");
using (StreamWriter sw = new StreamWriter(doc.MainDocumentPart.GetStream(FileMode.Create)))
{
sw.Write(docText);
}
}
}
}
}
When I remove this table loop the code works. Not sure whats conflicting
Body body = doc.MainDocumentPart.Document.Body;
foreach (Table t in body.Descendants<Table>())
{
String tableName = t.GetFirstChild<TableProperties>().TableCaption.Val;
Console.WriteLine(tableName);
}
Try to disable AutoSave option.
using (WordprocessingDocument doc =
WordprocessingDocument.Open(document, true, new OpenSettings { AutoSave = false }))
{
...
}
Looks like when AutoSave is enabled and getter of doc.MainDocumentPart.Document.Body is called it causes that doc.MainDocumentPart is not saved properly or it's overriden with original document part.

Microsoft.Office.Word.Interop 2nd Document keeps opening as read-only

Here is my code so far:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Office.Interop.Word;
using Word = Microsoft.Office.Interop.Word;
namespace WordIterator
{
class LoadDocument
{
public static Document Default()
{
try
{
return AnyDoc(Filepath.Full());
}
catch
{
throw new Exception("Error loading default document.");
}
}
public static Document AnyDoc(string filepath)
{
try
{
object fileName = filepath;
Application wordApp = new Application { Visible = true };
Document aDoc = wordApp.Documents.Open(ref fileName, ReadOnly: false, Visible: true);
aDoc.Activate();
return (aDoc);
}
catch
{
throw new Exception("Error loading document " + filepath + "!");
}
}
}
}
//Main class
namespace WordIterator
{
class Program
{
static void Main(string[] args)
{
Document doc = LoadDocument.Default();
doc.SaveAs2(Filepath.Full().Replace(".docx", "_2.docx"));
Document doc2 =
LoadDocument.AnyDoc(#"C:\Users\netha\Documents\FSharpTest\FTEST\ftestdoc3_2.docx");
What i'm trying to do:
Open a word document(do some stuff with it)
Save it as _2.docx
Then open _2.docx(do some stuff with it)
However the second document keeps opening as read-only, I have it set as read-only false and I've even restarted my computer to make sure it shouldn't be read-only.
Does anyone know why this is opening as Read-Only?
Thank you for any assistance
It is opening as read-only as you do SaveAs "_2.docx" and then you are trying to open the save document again. I would recommend you to close the active tab and then open the document.
You could use the following code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Office.Interop.Word;
using Word = Microsoft.Office.Interop.Word;
using System.IO;
namespace WordIterator
{
class Program
{
static void Main(string[] args)
{
string FilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Test.docx");
Document doc = null;
Application wordApp1 =new Application();
Application wordApp2 = new Application();
string FilePath2 = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Test_2.docx");
try
{
object fileName = FilePath;
object fileName2 = FilePath2;
wordApp1 = new Application { Visible = true };
doc = wordApp1.Documents.Open(ref fileName, ReadOnly: false, Visible: true);
doc.SaveAs2(FilePath.Replace(".docx", "_2.docx"));
doc.Close();
Document doc2 = wordApp1.Documents.Open(ref fileName2, ReadOnly: false, Visible: true);
}
catch (Exception ex)
{
}
finally
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(doc);
System.Runtime.InteropServices.Marshal.ReleaseComObject(wordApp1);
}
}
}
}

How to convert GML string to XML?

I have a GML string:
<gml:LineString><gml:coordinates>1537544.53,452064.2 1537541.719999999,452062.3099999999 1537523.159999999,452044.55 1537544.53,452064.2</gml:coordinates></gml:LineString>
Now i want to convert it to xml document
var t = "<gml:LineString>....</gml:LineString>";
XmlDocument doc = new XmlDocument();
var nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("gml", "http://www.opengis.net/gml");
doc.Load(t);
But on doc.Load(t); got exception:
System.Xml.XmlException: "Prefix "gml" undeclared."
How to add namespace and read read line?
UPDATE
I'd fix code based on #jdweng answer:
XmlReaderSettings settings = new XmlReaderSettings { NameTable = new NameTable() };
var nsmgr = new XmlNamespaceManager(settings.NameTable);
nsmgr.AddNamespace("gml", "http://www.opengis.net/gml");
XmlParserContext context = new XmlParserContext(null, nsmgr, "", XmlSpace.Default);
XmlReader reader = XmlReader.Create(new StringReader(gmlString), settings, context);
if (gmlString.StartsWith("<gml:Polygon>"))
{
XmlSerializer serializer = new XmlSerializer(typeof(PolygonType));
return new tGeoLPT { Item = (PolygonType)serializer.Deserialize(reader)
};
}
Using xml linq :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
string coordinates = "1537544.53,452064.2 1537541.719999999,452062.3099999999 1537523.159999999,452044.55 1537544.53,452064.2";
string line = "<gml:LineString xmlns:gml=\"http://www.opengis.net/gml\"></gml:LineString>";
XElement xLine = XElement.Parse(line);
XNamespace ns = xLine.GetNamespaceOfPrefix("gml");
xLine.Add(new XElement(ns + "coordinates"), coordinates);
}
}
}

ObjectARX read/write .dwg files that are not currently opened in autocad

Im trying to modify a .dwg file and overwrite the .dwg file once done, all that without opening it in autocad. I've read about RealDWG but the goal here is not to be in a standalone mode. the autocad plugin runs from autocad and needs to modify and write to some .dwg files that are not opened in the current project. So far I create a Database object and Read the .dwg file into it but im having errors when I want to rewrite into it. Here is the code its in C#,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
namespace ModifyClosedDWG
{
public class DWGEditor
{
private static string filepath = #"E:\...\DrawingTest.dwg";
[CommandMethod("modifyDWG")]
public void addTextToDWG()
{
Database workingDB = HostApplicationServices.WorkingDatabase;
Editor ed = doc.Editor;
Database db = new Database(false, true);
try
{
db.ReadDwgFile(filepath, System.IO.FileShare.ReadWrite, false, "");
db.CloseInput(true);
HostApplicationServices.WorkingDatabase = db;
}
catch (Autodesk.AutoCAD.Runtime.Exception e)
{
ed.WriteMessage("\nUnable to read drawing file : " + e.StackTrace);
return;
}
using (BlockTable bt = db.BlockTableId.Open(OpenMode.ForRead) as BlockTable)
{
using (BlockTableRecord btr = bt[BlockTableRecord.ModelSpace].Open(OpenMode.ForWrite) as BlockTableRecord)
{
MText objText = new MText();
objText.SetDatabaseDefaults();
objText.Location = new Autodesk.AutoCAD.Geometry.Point3d(2, 2, 0);
objText.Contents = "added text in a closed .dwg file!";
objText.TextStyleId = db.Textstyle;
btr.AppendEntity(objText);
}
}
HostApplicationServices.WorkingDatabase = workingDB;
db.SaveAs(filepath, DwgVersion.Current);
}
}
}
the error output :
Autodesk.AutoCAD.Runtime.Exception: eWasOpenForWrite
at Autodesk.AutoCAD.DatabaseServices.Database.SaveAs(String fileName, DwgVersion version)
at ModifyClosedDWG.DWGEditor.addTextToDWG() in E:\PROJETS\ELI017\07 In Works documents\VisualC#Projects\ModifyClosedDWG\ModifyClosedDWG\DWGEditor.cs:line 64
at Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorker(MethodInfo mi, Object commandObject, Boolean bLispFunction)
at Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorkerWithExceptionFilter(MethodInfo mi, Object commandObject, Boolean bLispFunction)
at Autodesk.AutoCAD.Runtime.PerDocumentCommandClass.Invoke(MethodInfo mi, Boolean bLispFunction)
at Autodesk.AutoCAD.Runtime.CommandClass.CommandThunk.Invoke()
I found the solution so I'll put the new code here...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
namespace ModifyClosedDWG
{
public class DWGEditor
{
private static string filepath = #"E:\PROJETS\ELI017\07 In Works documents\dwg\DrawingTest.dwg";
[CommandMethod("modifyDWG")]
public void addTextToDWG()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
Database workingDB = HostApplicationServices.WorkingDatabase;
Database db = new Database(false, true);
try
{
db.ReadDwgFile(filepath, System.IO.FileShare.ReadWrite, false, "");
db.CloseInput(true);
HostApplicationServices.WorkingDatabase = db;
}
catch (Autodesk.AutoCAD.Runtime.Exception e)
{
ed.WriteMessage("\nUnable to open .dwg file : " + e.StackTrace);
return;
}
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
BlockTableRecord btr = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
MText objText = new MText();
objText.SetDatabaseDefaults();
objText.Location = new Autodesk.AutoCAD.Geometry.Point3d(2, 2, 0);
objText.Contents = "added text in a closed .dwg file!";
objText.TextStyleId = db.Textstyle;
btr.AppendEntity(objText);
tr.AddNewlyCreatedDBObject(objText, true);
tr.Commit();
}
HostApplicationServices.WorkingDatabase = workingDB;
db.SaveAs(filepath, DwgVersion.Current);
}
}
}

c# Oledb excel to txt, how to also recognize letters?

I have an application which uses open file dialog to open an excel file and then convert it to .txt and it works fine, almost. Currently it can only read tables with only numbers in them but I need to add a function so that it could also read letters. What should I change to make it able to read letters/words as well as numbers?
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : System.Windows.Window
{
public MainWindow()
{
InitializeComponent();
}
private void BtnFileOpen_Click(object sender, RoutedEventArgs e)
{
var fileDialog = new System.Windows.Forms.OpenFileDialog();
var result = fileDialog.ShowDialog();
switch (result)
{
case System.Windows.Forms.DialogResult.OK:
var file = fileDialog.FileName;
TxtFile.Text = file;
TxtFile.ToolTip = file;
break;
case System.Windows.Forms.DialogResult.Cancel:
default:
TxtFile.Text = null;
TxtFile.ToolTip = null;
break;
}
}
public void convert_Click(object sender, RoutedEventArgs e)
{
// Configure save file dialog box
Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
dlg.FileName = "Document"; // Default file name
dlg.DefaultExt = ".txt"; // Default file extension
dlg.Filter = "Text documents (.txt)|*.txt"; // Filter files by extension
// Show save file dialog box
Nullable<bool> result = dlg.ShowDialog();
// Process save file dialog box results
if (result == true)
{
// Save document
string filename = dlg.FileName;
exportExcelToTxt(TxtFile.Text, filename);
}
}
static void exportExcelToTxt(string excelFilePath, string outputTxtPath)
{
Dictionary<string, List<long>> values = new Dictionary<string, List<long>>();
using (OleDbConnection excelConnection = new OleDbConnection(string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 12.0 XML;HDR=YES\"", excelFilePath)))
{
excelConnection.Open();
string firstSheet = getFirstSheetName(excelConnection);
using (OleDbCommand cmd = excelConnection.CreateCommand())
{
cmd.CommandText = string.Format("SELECT * FROM [{0}]", firstSheet);
using (OleDbDataAdapter da = new OleDbDataAdapter(cmd))
{
using (DataTable dt = new DataTable())
{
da.Fill(dt); // Getting all the data in the sheet
foreach (DataRow item in dt.Rows)
{
List<long> toAdd = new List<long>();
string key = item[0] as string;
for (int i = 1; i < dt.Columns.Count; i++)
{
toAdd.Add(Convert.ToInt64(item[i]));
}
values.Add(key, toAdd); // Associating all the "numbers" to the "Name"
}
}
}
}
}
StringBuilder toWriteToTxt = new StringBuilder();
foreach (KeyValuePair<string, List<long>> item in values)
{
// Formatting the output
toWriteToTxt.Append(string.Format("{0}:", item.Key));
foreach (long val in item.Value.Distinct())
{
toWriteToTxt.AppendFormat("\t{0} * {1}\r\n", item.Value.Where(f => f == val).Count(), // Amount of occurrencies of each number
val);
}
}
// Writing the TXT
using (FileStream fs = new FileStream(outputTxtPath, FileMode.Create))
{
using (StreamWriter sw = new StreamWriter(fs))
{
sw.Write(toWriteToTxt.ToString());
}
}
}
static string getFirstSheetName(OleDbConnection excelConnection)
{
using (DataTable ExcelTables = excelConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new Object[] { null, null, null, "TABLE" }))
{
return ExcelTables.Rows[0]["TABLE_NAME"].ToString();
}
}
}
}
You should not convert the values to long in this line:
toAdd.Add(Convert.ToInt64(item[i]));
Also replace all List<long> with List<string>, this should cover pretty much the issue.

Categories