How do I bind XML to WPF, and have CRUD capability? - c#

I've got an XML document with about 450 items in it.
<Customers>
<Customer>
<Name>XYZ</Name
<Phone>1234567890</Phone>
</Customer>
<Customer>
<Name>ABC</Name>
<Phone>9012345678</Phone>
</Customer>
</Customers>
I need to bind this document to a form in WPF. That part I have figured out. I have the name bound to a ComboBox, and the phone (and other fields) bound to textblocks so that they display the info of whichever customer is selected in the combobox. This is done in XAML.
What I need to add, though, is the ability to add/update/delete customers from the existing list, and have them be added/updated/deleted in the XML file. What I'm thinking is that I can't do this just in XAML, and will need to somehow read the XML into a List with a class of Customer with all the properties that match the fields in the XML document. Is that correct? And if so, what is the simplest way to be able to do this? Right now I'm reading on LINQ to XML, trying to figure out how to do that, but before I go there, I'm wondering if that's the simplest way to do it.
The project I'm working on at the moment is for work, where development is just something I do occasionally, but to know how to do this would be handy for a Windows Phone application idea to update one of my apps.
Thanks in advance!

Launch the Visual Studio Command line and use the xsd.exe tool to create a strongly typed DataSet that implements INotifyPropertyChanged.
Here is an example command:
xsd.exe /d /l:cs ..\MYXml.xsd /edb /o:..\Data\ /n:MyApp.Data
/d: Creates the dataset.
/l:cs: C# language.
..\MyXml.xsd: Path to my xsd.
/edb: Create databound xsd, this will make the dataset implement INotifyPropertyChanged.
/o: Output directory.
/n: Namespace of class.
You can easily load and save the generated DataSet from your xml file.
public MyDataSet Load(string path)
{
MYXml ds = new MYXml();
ds.ReadXml(path);
return ds;
}
public void SaveChanges(MYXml ds, string path )
{
// ds.AcceptChanges();
ds.WriteXml(path);
}
MSDN: XML Schema Definition Tool (Xsd.exe).

Related

XML Data and Schemas

Ok, here is specific case scenario:
My application is going to receive some XML inputs. Then the application needs to render that XML input, as well as do some calculations after parsing data from that XML input.
The deal is, that the application is data agnostic. It's code cannot know details about XML data and format during design-time. So am making it the responsibility of calling client tool to send a schema associated with the XML data. Based on that schema, application will parse and understand XML data it will receive.
So, questions:
Can XML Schema specify any custom attributes that I may decide my application will need to parse data?
Will it be ok if corresponding node in XML data will not specify those attributes themselves?
While navigating in XML data, node by node, how can I using C# load corresponding attributes and values from XML schema?
Basically, I'll need such custom attributes in schema for various nodes - showInTable, isPrimary, graphable etc etc
Thanks for help.
The way around this I would say is to have a some fixed part of the schema, for data that will be there - even if it is nullable.
Then after that, get the XML to use some sort of <metadata> tags to allow you to capture any additional information. Like
<Customer>
<Name>Joe Bloggs</Name>
<Age>65</Age>
<Metadata key="Criminal History">Grand Theft Auto</Metadata>
<Metadata key="Favourite Colour">Blue</Metadata>
</Customer>
Metadata can be shared (if defined up front), with a minOccurs='0', maxOccurs='unbounded'.

Serialize object to XML based on existing XSD schema

I have to create an XML document that would be based on an certain XML Schema Document. Since my data is a DataSet, I need to find the best way to start off.
I have couple of different ideas how to start:
manually create nodes, elements, attributes that would match XSD
transform DataSet into a class that would match the schema document and serialize it
something else?
Is this a right way to get a XML output from DataSet to match XSD schema?
May be you should give XMLBeans a try... It's a diverse framework for playing around with compiled XSD schemas. Compiled in this context means, you create JAVA classes from your XSD-files.
Compilation example (as can be seen here) scomp -out purchaseorder.jar purchaseorder.xsd
With this jar in your classpath you could create new a priori valid instances of your schema with something like:
public PurchaseOrderDocument createPO() {
PurchaseOrderDocument newPODoc = PurchaseOrderDocument.Factory.newInstance();
PurchaseOrder newPO = newPODoc.addNewPurchaseOrder();
Customer newCustomer = newPO.addNewCustomer();
newCustomer.setName("Doris Kravitz");
newCustomer.setAddress("Bellflower, CA");
return newPODoc;
}
You can find the whole example at: XMLBeans Tutorial under the heading "Creating New XML Instances from Schema".

SOAP Response to DataTable in C#

I have been searching and trying in many forms to pass an XML Response to a simple DataTable in the same way Excel does.
The XML is like:
<?xml version="1.0" standalone="no"?>
<SOAP-ENV:Envelope xmlns:SOAPSDK1="http://www.w3.org/2001/XMLSchema" xmlns:SOAPSDK2="http://www.w3.org/2001/XMLSchema-instance" xmlns:SOAPSDK3="http://schemas.xmlsoap.org/soap/encoding/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAPSDK4:Function xmlns:SOAPSDK4="http://www.externalwebservice.com/message/">
<Lists>
<ListCode>12345</ListCode>
<ListGroups>
<ListGroup>
<CodeGroup>ASDF</CodeGroup>
<DescriptionGroup>Example</DescriptionGroup>
</ListGroup>
</ListGroups>
<List>
<CodeList>ABC</CodeList>
<DescriptionList>Example List</DescriptionList>
<ListCategories>
<ListCategory>Type1</ListCategory>
<ListCategory>Type2</ListCategory>
</ListCategories>
<ListKinds>
<Kind>
<KindType>A</KindType>
<KindTarget>1</KindTarget>
<KindAttributes>
<KindAttribute1>A</KindAttribute1>
<KindAttribute2>B</KindAttribute2>
</KindAttributes>
</Kind>
</ListKinds>
</List>
</Lists>
</SOAPSDK4:Function>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
What Excel does could help me in what I need and that is to fill 4 tables with this data and its relations.
I have tried using DataSet.ReadXML but the problem with it is that for some reason this method generates 14 tables with the data being of no use because there is no relation at all.
Later I tried with DataTable.ReadXML but it gave me the problem "DataTable does not support schema inference from Xml." then tried to use DataTable.ReadXmlSchema(XML) and it gave an error with no root document, then I created an XSD with the command prompt and the two generated gave an error, finally I used Visual Studio to generate the XSD, it generated 4 XSD with no errors but no columns where created and no data was added with none of them.
I am out of ideas now. Any suggestions? Maybe not a DataTable with no normalized data (what Excel does) but another approach going directly with the XML?
Thank you.
My suggestion would be Linq.XML technique in C# 3. LINQ to XML provides an in-memory XML programming interface that leverages the .NET Language-Integrated Query (LINQ) Framework. LINQ to XML uses the latest .NET Framework language capabilities and is comparable to an updated, redesigned Document Object Model (DOM) XML programming interface.
There are few interesting quick relevant examples are available at http://www.hookedonlinq.com/LINQtoXML5MinuteOverview.ashx

Converting an XML String into Code in C#

I have a reporting module in an ASP.NET webforms app (C#) that uses dynamic controls for the parameters for each report.
These dynamic controls are built from an XML column in a SQL Server 2008 DB.
XML structure:
<Report Parameters>
<Parameter>
<Name>CustomerId</Name>
<Control />
</Parameter>
<Parameter>
<Name>Start Date</Name>
<Control>DDL</Control>
</Parameter>
</Report Parameters>
I've left out a lot of the elements for readability.
If the <Control> element is not empty (as in the case of the Start Date parameter in the XML example) then a C# based XSLT tranformation creates the appropriate control on my form .
If the <Control> element is empty (as in the case of the CustomerId) then I want to use an existing c# property with the same name (i.e. I have a CustomerId defined in my c# code).
These parameter values (CustomerId and Start Date) are then passed to a stored procedure used to generate the report data.
I use the XPathNavigator and associated classes in my C# code to yank out the <Name> element of any <Control> element that is empty.
The problem is that the <Name> element is in the form of a string and I really want it to be in C# code form (sorry can't think of a better way to describe this!) i.e. I want this.CustomerId (added the this to show it's code not a string) not "CustomerId".
As I don't know how many reports this system will have over time I don't really want to build up an enum or switch statement if "CustomerId" then this.CustomerId etc. as it seems to negate the point of dynamic code.
I realise that reflection will probably be needed and I have little knowledge of this so any advice or advice on a different approach to this problem would be welcome.
Thanks,
Rich.
What you are looking for is a Code generator. While I haven't implemented one myself, I have used templates created by others before and it works like a charm. You can get started here.
You want to dynamically generate a class and it's properties based on the xml contents?
And you want it without having to generate code and recompile i'm sure too.
I have tried that too once and i never managed to get it working.
I don't see any solution, sorry.
This should do it:
this.GetType().GetProperty("CustomerId").SetValue("YourValue");

Can't import xml to dataset if xmlnode has attribute?

I am using the following codes to read xml file to a datagridview in c#:
newDataSet.ReadXml(filepath);
dataGridView3.DataSource = newDataSet;
dataGridView3.DataMember = "aaa";
And my xml file looks like this:
<root>
<aaa>
<Param_1>1</Param_1>
<Param_1>2</Param_1>
<Param_1>3</Param_1>
</aaa>
</root>
I can read the xml to dataset without any problems. Then I added some
attributes to the <Param> nodes so it becomes
<Param_1 size="2">1</Param_1>
The dataset can't show any xml data, does anyone knows why?
Also if I change my xml file to something like:
<root>
<Data_1>
<Name>aaa</Name>
<Params>
<Param_1>1</Param_1>
<Param_1>2</Param_1>
<Param_1>3</Param_1>
</Params>
</Data_1>
</root>
Is there still possible to use DataSet method to read them into a datagridview or I have to use something like linq?
If I have to, can someone show me how to do that using linq?
I suggest you to read data to xml document and bind to it using XmlDataSource, and not DataSet. And verify that structure is correct for binding. Looking at your comment (not at the edit by John, but rather at the comment under you question, there is no / symbol which should be in the closing tag: </Data_1>.
Or change structure to any that you wish, provided that it suits you for binding. After that you can read data:
DataSet ds = new DataSet();
ds.ReadXml("XMLFile1.xml", XmlReadMode.InferSchema);
Regarding Linq: you can start from reading Getting Started with LINQ in C#. But anyway you should not create complex xml structure - making it complex adds you a lot of work to deal with it.
DataSets are not a general-purpose mechanism for using XML. If the DataSet would not have produced the XML, then you cannot import that XML.

Categories