primitive class being ignore when serializing xsd generated class - c#

I used xsd.exe to generate a .cs class.
The xsd file as below
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="SendComments">
<xs:complexType>
<xs:sequence>
<xs:element name="Input">
<xs:complexType>
<xs:sequence>
<xs:element name="TransId" maxOccurs="1" minOccurs="0" type="xs:string"/>
<xs:element name="SampleId" minOccurs="0" maxOccurs="1" type="xs:long"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Output" type="xs:string" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
In my generated class, it has the correct field generated.
However, when I call the serializer. The SampleId field being ignored.
Serializer code segment:
var serializer = new XmlSerializer(typeof(SendComments));
using (StringWriter stringWriter = new StringWriter())
{
serializer.Serialize(stringWriter, SPCComment);
return stringWriter.ToString();
}
Result:
<?xml version="1.0" encoding="utf-16"?>
<SPCSendComments xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Input>
<TransId>-</TransId>
</Input>
</SPCSendComments>
I tried with other .xsd file, all the primitive type (bool, int, long) is being ignored when serializing.
I wonder what will be the cause that primitive type being ignored.

Your generated class has an extra field SampleIdSpecified that indicates if the field is null or not. Set that to true and the field will be serialized.
If you set TransId to null, that will also be ignored.
They're being ignored because they're optional fields in your schema. They have minOccurs = 0 which means that they don't need to be there for the XML to be valid.

Related

How to add the xmlElement from one xsd file within the xmlElement of another xsd file using XmlSampleGenerator?

I'm using XmlSampleGenerator to generate the xml file from xsd. I'm able to generate the xml file from single xsd file directly using bellow code.
using (var stream = new MemoryStream(File.ReadAllBytes("platform-container.xsd")))
{
var schema = XmlSchema.Read(XmlReader.Create(stream), null);
var gen = new XmlSampleGenerator(schema, new XmlQualifiedName("Document"));
gen.WriteXml(XmlWriter.Create(#"C:\SCIP\SCIP-Phase-1\SCIPAppPrj\XmlFiles\dossier.i6d"));
Console.WriteLine("Autogenerated file is here : C:\\SCIP\\SCIP-Phase-1\\SCIPAppPrj\\XmlFiles\\dossier.i6d");
}
But I'm facing the issue when I have to combine the elements from multiple xsd files and generate one single xml file.
For example my generated xml should look like below:
<?xml version="1.0" encoding="UTF-8"?>
<i6c:Document xmlns:i6c="http://iuclid6.echa.europa.eu/namespaces/platform-container/v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://iuclid6.echa.europa.eu/namespaces/platform-container/v1 container.xsd">
<i6c:PlatformMetadata xmlns:i6m="http://iuclid6.echa.europa.eu/namespaces/platform-metadata/v1" xsi:schemaLocation="http://iuclid6.echa.europa.eu/namespaces/platform-container/v1 container.xsd">
<i6m:iuclidVersion>1.0</i6m:iuclidVersion>
<i6m:documentKey>ABC</i6m:documentKey>
<i6m:documentType>DOSSIER</i6m:documentType>
</i6c:PlatformMetadata>
<i6c:Content>
<DOSSIER.SCIP xmlns="http://iuclid6.echa.europa.eu/namespaces/DOSSIER-SCIP/1.0" xmlns:i6="http://iuclid6.echa.europa.eu/namespaces/platform-fields/v1" />
</i6c:Content>
</i6c:Document>
I have main xsd called container.xsd, which has skeleton for my xml file. Also metaData.xsd and content.xsd which contains elements that should be included as a child under one of the element present in container.xsd.
container.xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns="http://iuclid6.echa.europa.eu/namespaces/platform-container/v1"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://iuclid6.echa.europa.eu/namespaces/platform-container/v1"
elementFormDefault="qualified" attributeFormDefault="qualified">
<xs:element name="Document">
<xs:complexType>
<xs:sequence>
<xs:element name="PlatformMetadata">
<xs:complexType>
<xs:sequence maxOccurs="unbounded">
<xs:any namespace="##other" processContents="lax" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="Content">
<xs:complexType>
<xs:sequence>
<xs:any namespace="##other" processContents="strict" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
metaData.xsd
<xs:schema xmlns="http://iuclid6.echa.europa.eu/namespaces/platform-metadata/v1"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://iuclid6.echa.europa.eu/namespaces/platform-metadata/v1"
elementFormDefault="qualified" attributeFormDefault="qualified">
<xs:element name="iuclidVersion" type="xs:string">
</xs:element>
<xs:element name="documentKey" type="xs:string">
</xs:element>
<xs:element name="documentType" type="xs:string">
</xs:element>
</xs:schema>
content.xsd
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://iuclid6.echa.europa.eu/namespaces/DOSSIER-SCIP/1.0" xmlns:ct="http://iuclid6.echa.europa.eu/namespaces/scip/v1" xmlns:i6="http://iuclid6.echa.europa.eu/namespaces/platform-fields/v1" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://iuclid6.echa.europa.eu/namespaces/DOSSIER-SCIP/1.0">
<xs:import namespace="http://iuclid6.echa.europa.eu/namespaces/platform-fields/v1" schemaLocation="platform-fields.xsd"/>
<xs:import namespace="http://iuclid6.echa.europa.eu/namespaces/scip/v1" schemaLocation="commonTypesScipV1.xsd"/>
<xs:element name="DOSSIER.SCIP">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" minOccurs="0" name="remarks" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Can anyone suggest me how to handle this using XmlSampleGenerator? How to read the elements from multiple xsd's and genrate single xml file ? How to append the data for each element ?

How to get inline xml schema?

this is my XML:
<?xml version="1.0" encoding="UTF-8"?>
<NewDataSet>
<xs:schema xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:xs="http://www.w3.org/2001/XMLSchema" id="NewDataSet">
<xs:element msdata:IsDataSet="true" msdata:UseCurrentLocale="true" name="NewDataSet">
<xs:complexType>
<xs:choice maxOccurs="unbounded" minOccurs="0">
<xs:element name="Table1">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" msdata:DateTimeMode="Unspecified" name="MAXTIME" type="xs:dateTime"/>
<xs:element minOccurs="0" name="X" type="xs:string"/>
<xs:element minOccurs="0" name="Y" type="xs:string"/>
<xs:element minOccurs="0" name="Z" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
<Table1>
<MAXTIME/>
<X>123</X>
<Y>DDo</Y>
<Z>Cri</Z>
</Table1>
</NewDataSet>
I want to get the xml schema from the above xml file, however when I use
XmlReader reader = XmlReader.Create(xmlPath);
XmlSchemaSet schemaSet = new XmlSchemaSet();
XmlSchemaInference schema = new XmlSchemaInference();
schemaSet = schema.InferSchema(reader);
it fails:
The supplied xml instance is a schema or contains an inline schema. This class cannot infer a schema for a schema.
so how should I get it to get the schema
Use this:
DataSet dset = new DataSet();
dset.ReadXml("xmlFile.xml",XmlReadMode.IgnoreSchema);
var _schema = dset.GetXmlSchema();

How to generate .NET 4.0 classes from xsd with more than 1 element to class?

I'm following the solution from this question How to generate .NET 4.0 classes from xsd? to generate C# classes. But somehow it only generates the first element. Is there any way that I can generate all elements at same time?
Xsd doc looks like below:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="advice_file">
</xs:element>
<xs:element name="vendorMerchID" type="xs:string">
</xs:element>
</xs:schema>
The reason you only get 1 element is because to be valid the xml must always have a single outer root node. What is suprising to me is that the second node was just ignored completely and no exception was thrown.
Your xsd represents the following xml
<advice_file/>
To have both elements, you need to write you xsd as follows:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="myRoot">
<xs:complexType>
<xs:sequence>
<xs:element name="advice_file" type="xs:string"/>
<xs:element name="vendorMerchID" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
for the xml structure as:
<myRoot>
<advice_file/>
<vendorMerchID/>
</myRoot>
Alternatively, if your xml is like this:
<advice_file>
<vendorMerchID/>
</advice_file>
Use the xsd:
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:element name="advice_file">
<xs:complexType>
<xs:sequence>
<xs:element name="vendorMerchID" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>

Error with type cast while deserializing XML using xsd.exe generated schema

I have a simple XML:
<?xml version="1.0" encoding="utf-8"?>
<room>
<item type="computer">
<x-coord>1</x-coord>
<y-coord>2</y-coord>
</item>
<item type="chair">
<x-coord>4</x-coord>
<y-coord>5</y-coord>
</item>
</room>
And I've generated XML Schema for it, as follows:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="room" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="room" msdata:IsDataSet="true" msdata:Locale="en-US">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="item">
<xs:complexType>
<xs:sequence>
<xs:element name="x-coord" type="xs:string" minOccurs="0" msdata:Ordinal="0" />
<xs:element name="y-coord" type="xs:string" minOccurs="0" msdata:Ordinal="1" />
</xs:sequence>
<xs:attribute name="type" type="xs:string" />
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>
Because I want my x-coord and y-coord fields to hold an Integer value, I've changed xs:string to xs:int, like this:
<xs:element name="x-coord" type="xs:int" minOccurs="0" msdata:Ordinal="0" />
<xs:element name="y-coord" type="xs:int" minOccurs="0" msdata:Ordinal="1" />
I've read somewhere that this should hold Int32 value, so I've changed my generated Room.cs to have:
[System.Xml.Serialization.XmlElementAttribute("y-coord", Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public System.Int32 ycoord
{
get {
return this.ycoordField;
}
set {
this.ycoordField = value;
}
}
for both x and y coordinate.
However, I still have an error with Strong Types and Cast Exception:
+ _x_coord '(new System.Linq.SystemCore_EnumerableDebugView<NA2.room.itemRow>(this.Items.tableitem)).Items[0]._x_coord' threw an exception of type 'System.Data.StrongTypingException' int {System.Data.StrongTypingException}
+ base {System.Data.StrongTypingException: The value for column 'x-coord' in table 'item' is DBNull. ---> System.InvalidCastException: Specified cast is not valid.
It only works with xs:string and public String ycoord. Only then the values are stored without any error but it is not what I want.
Do you know where is the problem here?
EDIT: When I generate the Room.cs from XSD where the type is int, I have the int fields and still get the cast error.

C# XML not correctly validating against Schema in XmlReaderSettings

I searched and did not find any questions addressing this problem.
I am attempting to validate various XML against a schema and it seems to be validating ALL well-formed XML, instead of just XML that conforms to the schema. I have posted the code I am using, the Schema, a sample valid XML and a sample invalid XML.
I have been struggling with this for awhile. I am in the dark on most of this. I've had to learn how to write an XSD, write the XSD, then learn how to parse XML in C#. None of which I have ever done before. I have used many tutorials and the microsoft website to come up with the following. I think this should work, but it doesn't.
What am I doing wrong?
private bool ValidateXmlAgainstSchema(string sourceXml, string schemaUri)
{
bool validated = false;
try
{
// REF:
// This should create a SCHEMA-VALIDATING XMLREADER
// http://msdn.microsoft.com/en-us/library/w5aahf2a(v=vs.110).aspx
XmlReaderSettings xmlSettings = new XmlReaderSettings();
xmlSettings.Schemas.Add("MySchema.xsd", schemaUri);
xmlSettings.ValidationType = ValidationType.Schema;
xmlSettings.ValidationFlags = XmlSchemaValidationFlags.None;
XmlReader xmlReader = XmlReader.Create(new StringReader(sourceXml), xmlSettings);
// parse the input (not sure this is needed)
while (xmlReader.Read()) ;
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(xmlReader);
validated = true;
}
catch (XmlException e)
{
// load or parse error in the XML
validated = false;
}
catch (XmlSchemaValidationException e)
{
// Validation failure in XML
validated = false;
}
catch (Exception e)
{
validated = false;
}
return validated;
}
The XSD / Schema. The intent is to accept XML that contains either an Incident or a PersonOfInterest.
<?xml version="1.0" encoding="utf-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="MySchema.xsd"
xmlns="MySchema.xsd"
elementFormDefault="qualified"
>
<xs:element name="Incident" type="IncidentType"/>
<xs:element name="PersonOfInterest" type="PersonOfInterestType"/>
<xs:complexType name="IncidentType">
<xs:sequence>
<xs:element name="Description" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="PersonOfInterest" type="PersonOfInterestType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PersonOfInterestType">
<xs:sequence>
<xs:element name="Name" type="xs:string" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
Here is a sample of valid XML
<?xml version="1.0" encoding="utf-8" ?>
<Incident
xmlns="MySchema.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.w3schools.com MySchema.xsd"
>
<Description>something happened</Description>
<PersonOfInterest>
<Name>Joe</Name>
</PersonOfInterest>
<PersonOfInterest>
<Name>Sue</Name>
</PersonOfInterest>
</Incident>
This is a sample of well-formed invalid XML which should throw an exception (I thought), but when I try it, the code returns true, indicating it is valid against the schema.
<ghost>Boo</ghost>
The reason your <ghost>Boo</ghost> validates is that the parser cannot find any schema matching the xml. If there is no schema then the parser assumed validity, providing the xml is well-formed. It's counter-intuitive I know, and will probably differ based on parser implementation.
This notwithstanding, there are several problems with your code:
Two Root Elements
This is a big no-no in xsd - you can only have a single root element. Some parsers will actually throw an exception, others tolerate it but will only use the first root element (in your case Incident) for any subsequent validation.
Use of schemaLocation attribute
This should take the value (namespace) (URI) where the namespace is the targetNamespace of the schema and the URI is the location of the schema. In your case you appear to be using the schema file name as your target namespace. Additionally, looking at your code, you are loading the schema into your xml reader so you don't actually need the schemaLocation attribute at all. This is an optional attribute and some parsers completely ignore it.
I would suggest the following changes:
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://MyMoreMeaningfulNamespace"
xmlns="http://MyMoreMeaningfulNamespace"
elementFormDefault="qualified"
>
<xs:element name="Root">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="Incident" type="IncidentType"/>
<xs:element maxOccurs="unbounded" name="PersonOfInterest" type="PersonOfInterestType"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="IncidentType">
<xs:sequence>
<xs:element name="Description" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
<xs:element name="PersonOfInterest" type="PersonOfInterestType" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="PersonOfInterestType">
<xs:sequence>
<xs:element name="Name" type="xs:string" minOccurs="1" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
Which validates this instance
<Root xmlns="http://MyMoreMeaningfulNamespace">
<Incident>
<Description>something happened</Description>
<PersonOfInterest>
<Name>Joe</Name>
</PersonOfInterest>
<PersonOfInterest>
<Name>Sue</Name>
</PersonOfInterest>
</Incident>
<Incident>
...
</Incident>
<PersonOfInterest>
<Name>Manny</Name>
</PersonOfInterest>
<PersonOfInterest>
...
</PersonOfInterest>
</Root>

Categories

Resources