How to generate xsd from xml in code behind - c#

What I want to do is generating xsd file from xml which will be passed as string.
Sample:
Let's say we have that kind of xml passed in string:
<?xml version="1.0" encoding="utf-8"?>
<Sample>
<SampleId>41111111124</AnimalId>
<SampleName>string</SampleKind>
</Sample>
I would like to generate from this above xsd file from code behind:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Sample">
<xs:complexType>
<xs:sequence>
<xs:element name="SampleId" type="xs:unsignedLong" />
<xs:element name="SampleName" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
On msdn couldn't find such thing.
Is it even possible to make it in c# code behind?

Ok I found solution for this:
XmlSchemaInference is what I needed.

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 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>

Xsd import doesn't work

I'm trying to use an xsd defined in http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd#. I saved that definition as one xsd file to my disk and change the import in a different xsd to use it but the visual studio doesn't detected or give me any clue by intellsense. i also set the visual studio menu option xml >menu > schemas and select the file, but doesn't work.
My xsd
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified"
targetNamespace="http://x/y/z/w/"
xmlns="http://x/y/z/w/"
xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
<!--<xs:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd#"/>-->
<xs:import namespace="http://www.w3.org/2000/09/xmldsig#" schemaLocation="file:/B:/Test.xsd" id="ds"></xs:import>
<xs:element name="elementX">
<xs:complexType>
<xs:sequence>
<xs:element ref="ds:Signature"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
The import i want to use is allocated in http://www.w3.org/TR/2002/REC-xmldsig-core-20020212/xmldsig-core-schema.xsd#
my question: is there any way to change the definition in order to appears in the intellsense.
Thanks in advance

How do you generate xsd namespace prefixes in the resulting output file?

I've gone over multiple topics and solutions that talk specifically about this issue. None have worked or I fail to understand what I am doing wrong.
I would like for the namespace prefixes to accompany the element names in the resulting xml output file.
I'm am using the XSD command with Visual Studio 2008 from the VS Command Prompt
Here's my xsd schema for Trial.xsd
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="Junk"
targetNamespace="http://www.opengis.net/kml/2.2"
xmlns="http://www.opengis.net/kml/2.2"
xmlns:gx="http://www.google.com/kml/ext/2.2"
xmlns:kml="http://www.opengis.net/kml/2.2"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:import namespace="http://www.google.com/kml/ext/2.2" schemaLocation="TestSchema.xsd" />
<!-- Start LookType -->
<xs:complexType name="LookType">
<xs:sequence>
<xs:element ref="gx:TimeSpan" minOccurs="0" />
<xs:element name="longitude" type="xs:string" />
</xs:sequence>
</xs:complexType>
<!-- End LookType -->
<xs:element name="Te" type="LookType" />
</xs:schema>
Here's my xsd schema for TestSchema.xsd
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="TestSchema"
targetNamespace="http://www.google.com/kml/ext/2.2"
xmlns="http://www.google.com/kml/ext/2.2"
xmlns:gx="http://www.google.com/kml/ext/2.2"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:element name="TimeSpan" type="gx:GXTimeSpanType" />
<!-- Start GXTimeSpanType -->
<xs:complexType name="GXTimeSpanType">
<xs:sequence>
<xs:element name="begin" type="xs:string" />
<xs:element name="end" type="xs:string" />
</xs:sequence>
</xs:complexType>
<!-- End GXTimeSpanType -->
</xs:schema>
I´m generating the resulting class file Trial.cs by using xsd TestSchema.xsd ./Trial.xsd /c /l:cs /n:T
In a program I assign these junk values and write them to file using XmlDocument, XmlSerializer and FileStream
T.LookType te = new T.LookType();
te.longitude = "34.444";
te.TimeSpan = new T.GXTimeSpanType();
te.TimeSpan.begin = "2010-02-26T20:22:00Z";
te.TimeSpan.end = "2010-02-26T20:23:42Z";
I've excluded the method that saves out the file using XmlDocument, XmlSerializer and FileStream as it is a little thicker then I'd like to post unless that is part of the problem.
This is what I get in the resulting file
<?xml version="1.0" encoding="utf-16"?>
<Te xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.opengis.net/kml/2.2">
<TimeSpan xmlns="http://www.google.com/kml/ext/2.2">
<begin>2010-02-26T20:22:00Z</begin>
<end>2010-02-26T20:23:42Z</end>
</TimeSpan>
<longitude>34.444</longitude>
</Te>
This is what I want in the resulting file. Notice the gx:TimeSpan element and the xmlns:gx namespace definition being added to the main Te element.
<?xml version="1.0" encoding="utf-16"?>
<Te xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns="http://www.opengis.net/kml/2.2"
xmlns:gx="http://www.google.com/kml/ext/2.2">
<gx:TimeSpan>
<begin>2010-02-26T20:22:00Z</begin>
<end>2010-02-26T20:23:42Z</end>
</gx:TimeSpan>
<longitude>34.444</longitude>
</Te>
It doesn't matter on which element the prefixes are declared on, as long as they're declared before they are used. Any code that doesn't like this is broken.
Perhaps because it doesn't matter, XML Schema has no way to influence on which element the prefixes are declared, or which prefix is used.

Exception when loading partial xml data into xsd dataset

I have the following .xsd code:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" id="MyDataSet">
<xs:element name="Row">
<xs:complexType>
<xs:sequence>
<xs:element name="Number" type="xs:int"/>
<xs:element name="Item" type="xs:string"/>
<xs:element name="Comment" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
And the following .xml file:
<?xml version="1.0" standalone="yes"?>
<MyDataSet>
<Row>
<Number>1</Number>
<Item>first</Item>
</Row>
</MyDataSet>
Since the "Comment" tag is missing in the xml file, I get an exception when running:
MyDataSet myDataSet = new MyDataSet();
myDataSet.ReadXml(xmlFilePath);
The exception is: "Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints."
How can I define the .xsd to be able to receive partial xml data and fill null or any default value when a tag is missing?
Got it... I needed to add the attribute "Nillable" with the value of "true" to the fields that may not arrive in the xml.

Categories

Resources