How to catch missing elements in xml validation with xsd from DataSet - c#

Ok, so I'm trying to validate a xml against a DataSet that represents properties for my project.
The schema addition is done like this:
dataSet d = new dataSet();
schema.add("http://tempuri.org/settings.xsd", XmlReader.Create(new StringReader(d.GetXmlSchema())));
Let's say my DataSet has two Columns "path" and "version". Then if I try to validate a xml:
<settings>
<paht>c:\</path>
</settings>
That will validate fine. And I don't want it to... I wan't to get an error since there is no "version" entry. So I have looked at what I get from the d.GetXmlSchema() and it looks like a xsd. And all entries contains a property: minOccurs="0"
I'm guessing that I wan't that to be ="1" but how do I set such an option to the DataSet?

Ok so this solves the problem, but it's not a nice solution...
So what we need is "minOccurs="1" but what we have is ...="0" so we just do a replace at the string we get from the xml and tada!
dataSet d = new dataSet();
schema.add("http://tempuri.org/settings.xsd", XmlReader.Create(new StringReader(d.GetXmlSchema().replace("minOccurs=\"0\"", "minOccurs=\"1\""))));
As I said, not that nice, if you have better suggestions please feel free to add in.

Related

C# Reading XML to dataset throwing error with nested element of same name

DataSet dset = new DataSet();
dset.ReadXml(FILENAME);
The error I got while Reading xml to dataset : Cannot add a SimpleContent column to a table containing element columns or nested relations.
I got to know what is causing the issue. My xml element that is causing issue looks something like below sample xml:(CreditCardDetail element is the one which is causing the issue as per my research on error. Also, this element data is not used later in our code so I need to somehow skip this element and load other elements data dynamically)
<PaymentData>
<Amount/>
<Change/>
<CreditCardDetail i:nil="true"/>
</PaymentData>
<PaymentData>
<Amount/>
<Change/>
<CreditCardDetail>
<CardNumber i:nil="true"/>
<Result i:nil="true"/>
</CreditCardDetail>
</PaymentData>
I am trying to read the xml(which is not in our control) to dataset and then access the datatable to save the data into sql tables. But since the nested element like above is causing error I am not sure how to go futher. Can somebody please guide me any alternative solution.
Problem is in CreditCardDetail. you have defined different structures for CreditCardDetail in the XML. It will fail for the second CreditCardDetail as it has already defined the SimpleContent for the XML. You can change the name of the second CreditCardDetail in your XML to something else.

How to read streamdata in xml when unknown stream type

I'm trying to build a plugin for a program that seems to save its dataSets in XML files. When I read the file back into a dataset in my plugin, I see the fields in the xml file, and one of them is "StreamData" which then has a long string of random characters: Bhl0bEVzdG....and so on. As I don't have the source code for the original program, I don't know what kind of object this is I need to try to read this data into to recreate the nice/normal looking dataTable from the program.
Here's the code to read in the xml file
DataSet dataSet = new DataSet();
dataSet.ReadXml(stream, XmlReadMode.InferSchema);
dataGridView1.DataSource = dataSet;
foreach (DataTable t in dataSet.Tables)
{
dataGridView1.DataMember = t.TableName;
}
This makes a table that looks like the xml file, but I want a table that looks like the table that made the xml file, if that makes sense.
Thanks
Try using System.Xml.Linq to read and process the XML.
You can read the file into an XDocument and access it's elements like this:
XDocument doc = XDocument.Load(stream)
var allDescendants = d.Descendants("StreamData").ToArray();
Once you get all the data you want from the XDocument you can manually place it into a DataTable.
Here is more specific information about System.Xml.Linq and DataTables.
http://msdn.microsoft.com/en-us/library/system.xml.linq%28v=vs.110%29.aspx
http://msdn.microsoft.com/en-us/library/system.data.datatable%28v=vs.110%29.aspx
Linq is very useful and I have found it solves many problems very elegantly.

Cannot add a nested relation or an element column to a table containing a SimpleContent column

Hi iam write this code
"
XmlTextReader read = new XmlTextReader("http://msdn.microsoft.com/rss.xml");
DataSet ds = new DataSet();
ds.ReadXml(read);
ListView1.DataSource = ds.Tables[4];
ListView1.DataBind(); "
and this error is happing
"Cannot add a nested relation or an element column to a table containing a SimpleContent column"
Your problem is you have the same element name with a different structure somewhere in the document.
So, for example, if you have
<Item>Bicycle</Item>
and later in the document you have
<Item Type="Sports"><Name>Bicycle</Name></Item>
The XSD will fail to generate a proper schema for the second Item attribute structure because it's already defined Item as a SimpleContent column based on the earlier declaration.
The solution is to (naturally) avoid using the same element name for different structures within your XML. Obviously in your case that's kind of inconvenient since Microsoft owns the XML in question (hypothetically, since the comment from Deni indicates this site no longer exists.) You'd have to use XMLWriter or some variant to swap out the name of the offending element for something unique.
It looks like your xml contains an element which has both text children (simple content) and other element children.
DataSet does not allow a table to have both simple content columns as well as element columns.
See http://msdn2.microsoft.com/en-us/library/zx8h06sz.aspx
In my case this error appeared on WCF client's side. On WCF server's side it was caused by missing SQL SELECT permission on a function -- System.Data.SqlClient.SqlException.
WCF client trying to deserialize a dataset, which was obviously not there, kept displaying "Cannot add a SimpleContent..." error. I would not call it a misleading message, but rather one that must be interpreted properly.
I think this error will display when you are trying to ReadXml from Responsetext from service calls. In this Case Just Fetch the necessary node attribute which you require in outerxml format . Those who are not neccessary skip that element.
E.g
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
XmlDocument doc = new XmlDocument();
DataSet ds = new DataSet();
doc.LoadXml(responseString);
foreach (XmlNode node in doc.SelectNodes("result/records"))
{
doc = new XmlDocument();
doc.LoadXml(node.OuterXml.ToString());
}
using (XmlReader reader = new XmlNodeReader(doc.DocumentElement))
{
ds.ReadXml(reader);
reader.Close();
}
In Above example I want only 'records' node in response stream . So that I am fetching only that & given to dataset for processing.
I hope it helps!!!!!!!!!!!!!!!!!!!!!!!!!!!

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.

Reading Xml into a datagrid in C#

Whats the best way to read Xml from either an XmlDocument or a String into a DataGrid?
Does the xml have to be in a particular format?
Do I have to use A DataSet as an intermediary?
I'm working on a client that consumes Xml sent over from a Server which is being developed by one of my colleagues, I can get him to change the format of the Xml to match what a DataGrid requires.
It depends on which version of .NET you are running on. If you can use Linq2Xml then it is easy. Just create an XDocument and select the child nodes as a list of an anonymous type.
If you can't use Linq2Xml then you have a few other options. Using a DataSet is one, this can work well, but it depends on the xml you are receiving. An other option is to create a class that describes the entity you will read from the xml and step through the xml nodes manually. A third option would be to use Xml serialization and deserialize the xml into a list of objects. This can work well as long as you have classes that are setup for it.
The easiest option will be either to create an XDocument or to create a DataSet as you suggest.
Obviously your XML needs to be valid :)
After that, define a dataset, define a datagrid. Use the readXML method on the dataset to fill the dataset with your XML, finish with a dataBind and you are good to go.
DataSet myDataSet = new DataSet();
myDataSet .ReadXml(myXMLString);
myDataGrid.DataSource = myDataSet ;
myDataGrid.DataBind();
You can simply use the XmlDatasource object as the grid's data source. That allows you to set the file and the XPath, in order to choose the XML that is the soure of your data. You can then use the <%# XPath="blah"%> function to write out your data explicitely, if you like.
We have a partial answer to get the data into a dataset but it reads it in as a set of tables with relational links.
DataSet ds = new DataSet();
XmlTextReader xmlreader = new XmlTextReader(xmlSource, XmlNodeType.Document, null);
ds.ReadXml(xmlreader);

Categories