Generating XML Documents from XML Schemas - c#

I'm using this xml sample generator to create a sample of the following XSD files:
Main XSD:
<?xml version="1.0" ?>
<xs:schema xmlns:pur="http://NamespaceTest.com/Purchase"
xmlns:cmn="http://NamespaceTest.com/CommonTypes"
xmlns:cust="http://NamespaceTest.com/CustomerTypes"
targetNamespace="http://NamespaceTest.com/Purchase"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:import schemaLocation="test2.xsd"
namespace="http://NamespaceTest.com/CommonTypes" />
<xs:import schemaLocation="test.xsd"
namespace="http://NamespaceTest.com/CustomerTypes" />
<xs:element name="CustomerDetails" type="cust:CustomerType" />
</xs:schema>
Customer XSD:
<?xml version="1.0" ?>
<xs:schema xmlns:cmn="http://NamespaceTest.com/CommonTypes"
targetNamespace="http://NamespaceTest.com/CustomerTypes"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:import schemaLocation="test2.xsd"
namespace="http://NamespaceTest.com/CommonTypes" />
<xs:complexType name="CustomerType">
<xs:sequence>
<xs:element name="Name" type="xs:string" />
<xs:element name="DeliveryAddress" type="cmn:AddressType" />
<xs:element name="BillingAddress" type="cmn:AddressType" />
</xs:sequence>
</xs:complexType>
</xs:schema>
Common Types XSD:
<?xml version="1.0" ?>
<xs:schema targetNamespace="http://NamespaceTest.com/CommonTypes"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:complexType name="AddressType">
<xs:sequence>
<xs:element name="Line1" type="xs:string" />
<xs:element name="Line2" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:schema>
The result of the following commands is a xml with a namespace prefix I don't expected, namely xmlns="http://NamespaceTest.com/CustomerTypes instead of xmlns="http://NamespaceTest.com/CommenTypes for the delivery address and billing address:
StringBuilder builder = new StringBuilder();
XmlWriterSettings settings = new XmlWriterSettings { Indent = true };
XmlWriter writer = XmlWriter.Create(builder, settings);
XmlQualifiedName qname = new XmlQualifiedName("CustomerDetails", #"http://www.test.de");
XmlSampleGenerator generator = new XmlSampleGenerator(#"C:\Users\test.xsd", qname);
generator.WriteXml(writer);
Console.WriteLine(builder.ToString());
Result xml:
<?xml version="1.0" encoding="utf-16"?>
<CustomerDetails xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://NamespaceTest.com/Purchase">
<Name xmlns="http://NamespaceTest.com/CustomerTypes">Name1</Name>
<DeliveryAddress xmlns="http://NamespaceTest.com/CustomerTypes">
<Line1 xmlns="http://NamespaceTest.com/CommonTypes">Line11</Line1>
<Line2 xmlns="http://NamespaceTest.com/CommonTypes">Line21</Line2>
</DeliveryAddress>
<BillingAddress xmlns="http://NamespaceTest.com/CustomerTypes">
<Line1 xmlns="http://NamespaceTest.com/CommonTypes">Line11</Line1>
<Line2 xmlns="http://NamespaceTest.com/CommonTypes">Line21</Line2>
</BillingAddress>
</CustomerDetails>

Related

XML deserialization not binding list of strings

I am trying to deserialize xml into c# classes.
I followed some documentation and generated some c# classes using the commands xsd foo.xml & xsd foo.xsd /classes
one of the classess generated by commands. The only part that fails to bind is the getMLIstResult
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.3928.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
public partial class EnvelopeBodyGetMListResponse
{
private string[] getMListResultField;
/// <remarks/>
[System.Xml.Serialization.XmlArrayItemAttribute(IsNullable = false)]
public string[] GetMListResult
{
get
{
return this.getMListResultField;
}
set
{
this.getMListResultField = value;
}
}
}
the xml used to create the xsd
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetMListResponse xmlns="http://tempuri.org/">
<GetMListResult>
<string>string</string>
<string>string</string>
</GetListResult>
</GetListResponse>
</soap:Body>
</soap:Envelope>
xsd used to create the class
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="Envelope" targetNamespace="http://schemas.xmlsoap.org/soap/envelope/" xmlns:mstns="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" attributeFormDefault="qualified" elementFormDefault="qualified" xmlns:app1="http://tempuri.org/">
<xs:import namespace="http://tempuri.org/" schemaLocation="Envelope_app1.xsd" />
<xs:element name="Envelope" msdata:IsDataSet="true" msdata:UseCurrentLocale="true" msdata:Prefix="soap">
<xs:complexType>
<xs:sequence>
<xs:element name="Body" msdata:Prefix="soap">
<xs:complexType>
<xs:sequence>
<xs:element name="GetMListResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="GetMListResult">
<xs:complexType>
<xs:sequence>
<xs:element name="string" type="xs:string" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
a few things to note:
I am not able to change the way the xml is returned from an api I am trying to work with.
I also made a few changes to the xsd after it was generated.
serialization/deserialization works for the most part, but lists/arrays fail to bind

How to iterate/traverse XML file elements( which contains different namespaces) to convert it as Data table in C#

I have a sample to read a xml schema set for a xml file which contains different namespaces. For this i can get different schema for each namespace as i explained below.
Sample File:
<?xml version="1.0" encoding="utf-8"?>
<data xmlns:d="http://sampleschema/dataservices" xmlns:m="http://sampleschema/dataservices/metadata">
<content>
<m:properties>
<d:CustomerID>ALFKI</d:CustomerID>
<d:CompanyName>Alfreds Futterkiste</d:CompanyName>
</m:properties>
</content>
</data>
Sample Code to get XML Schema Set:
strFileName = #"C:\Sample\Sample.xml";
XmlReader reader = XmlReader.Create(strFileName);
XmlSchemaInference schema = new XmlSchemaInference();
XmlSchemaSet schemaSet = schema.InferSchema(reader);
It gives three different types of schemas while using the above code. But my requirement will be i need a single schema for the entire xml file which contain any number of namespaces in it. I have checked with possibilities of codes in msdn and stack overflow. I can't find any proper solution for this.
The expected schema output will be like below.
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="data">
<xs:complexType>
<xs:sequence>
<xs:element name="content">
<xs:complexType>
<xs:sequence>
<xs:element name="m:properties">
<xs:complexType>
<xs:sequence>
<xs:element name="d:CustomerID" type="xs:string"></xs:element>
<xs:element name="d:CompanyName" type="xs:string"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute name="xmlns:d" type="xs:string"></xs:attribute>
<xs:attribute name="xmlns:m" type="xs:string"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>
Any one can help to achieve this requirement.
Thanks in advance.
Try something like this :
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:m="http://www.w3.org/2001/XMLSchema" xmlns:d="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xs:element name="data">
<xs:complexType>
<xs:sequence>
<xs:element name="content">
<m:complexType>
<m:sequence>
<m:element name="properties">
<d:complexType>
<d:sequence>
<d:element name="CustomerID" type="xs:string"></d:element>
<d:element name="CompanyName" type="xs:string"></d:element>
</d:sequence>
</d:complexType>
</m:element>
</m:sequence>
</m:complexType>
</xs:element>
</xs:sequence>
<d:attribute name="xmlns_d" type="d:string"></d:attribute>
<m:attribute name="xmlns_m" type="d:string"></m:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

XmlSchemaException C#

I have to read an XML from file, which is:
<?xml version="1.0" encoding="UTF-16"?>
<KyactusProfileClass xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<username>sadasdsad</username>
<userid>0067AA87BF9AD466792E1A20F6AAB7F</userid>
<useDefaultFolder>false</useDefaultFolder>
<autoAcceptDownloads>false</autoAcceptDownloads>
<visible>false</visible>
</KyactusProfileClass>
I read it using following code:
using (var xmlReader = XmlReader.Create(pathXML))
{
Console.WriteLine(File.ReadAllText(pathXML));
schemas.Add(null, xmlReader);
}
But I get following error:
System.Xml.Schema.XmlSchemaException: 'The root element of W3C XML Schema must be < schema > and its namesapce must be 'http://www.w3.org/2001/XMLSchema'.'
I generated that XML using a XML serializer and XSD Schema validator:
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="kyactusprofile" type="kyactusprofile" />
<xs:complexType name="kyactusprofile" >
<xs:sequence>
<xs:element type="xs:string" name="username" maxOccurs="1" minOccurs="1"/>
<xs:element type="xs:string" name="userid" maxOccurs="1" minOccurs="1"/>
<xs:element type="xs:boolean" name="useDefaultFolder" maxOccurs="1" minOccurs="1"/>
<xs:element type="xs:string" name="defaultFolder" maxOccurs="1" minOccurs="1"/>
<xs:element type="xs:boolean" name="autoAcceptDownloads" maxOccurs="1" minOccurs="1"/>
<xs:element type="xs:boolean" name="visible" />
</xs:sequence>
</xs:complexType>
</xs:schema>
Hers is the stack trace:
System.Xml.Schema.XmlSchemaException
HResult=0x80131941
Message=L'elemento radice di W3C XML Schema deve essere <schema> e il suo spazio dei nomi deve essere 'http://www.w3.org/2001/XMLSchema'.
Source=System.Xml
StackTrace:
at System.Xml.Schema.XmlSchemaSet.InternalValidationCallback(Object sender, ValidationEventArgs e)
at System.Xml.Schema.XmlSchemaSet.SendValidationEvent(XmlSchemaException e, XmlSeverityType severity)
at System.Xml.Schema.XmlSchemaSet.ParseSchema(String targetNamespace, XmlReader reader)
at System.Xml.Schema.XmlSchemaSet.Add(String targetNamespace, XmlReader schemaDocument)
at Kyactus.XmlManager.GestoreXml.ValidateXmlWithXsd(String pathXML) in C:\Users\Cristiano\Documents\Visual Studio 2017\Projects\progetto-pds\visual-studio\Kyactus\Kyactus\XmlManager\GestoreXml.cs:line 249
at Kyactus.XmlManager.GestoreXml.UnmarshallProfile() in C:\Users\Cristiano\Documents\Visual Studio 2017\Projects\progetto-pds\visual-studio\Kyactus\Kyactus\XmlManager\GestoreXml.cs:line 178
at Kyactus.XmlManager.GestoreXml..ctor() in C:\Users\Cristiano\Documents\Visual Studio 2017\Projects\progetto-pds\visual-studio\Kyactus\Kyactus\XmlManager\GestoreXml.cs:line 64
at Kyactus.App..ctor() in C:\Users\Cristiano\Documents\Visual Studio 2017\Projects\progetto-pds\visual-studio\Kyactus\Kyactus\App.xaml.cs:line 21
at Kyactus.App.Main()
You are most likely reading the XML
<?xml version="1.0" encoding="UTF-16"?>
<KyactusProfileClass xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<username>sadasdsad</username>
<userid>0067AA87BF9AD466792E1A20F6AAB7F</userid>
<useDefaultFolder>false</useDefaultFolder>
<autoAcceptDownloads>false</autoAcceptDownloads>
<visible>false</visible>
</KyactusProfileClass>
with the XmlReader and try to add it as XmlSchema. That's the wrong approach, it's not a schema! You have to read your XSD, then no Exception will appear.

How to add a default namespace to an existing XSD file using C#

I have an existing XSD file and I want to add a namespace. How can I do this using C#?
Starting with something like this:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="BasicNoiseServiceRequest_201102" nillable="true" type="BasicNoiseServiceRequest_201102" />
<xs:complexType name="BasicNoiseServiceRequest_201102">
<xs:complexContent mixed="false">
<xs:extension base="CrmServiceRequest">
I want to end up with something like this where the xmlns and targetNamespace attributes have been added:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns="MyNamespace" targetNamespace="MyNamespace"
elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="BasicNoiseServiceRequest_201102" nillable="true" type="BasicNoiseServiceRequest_201102" />
<xs:complexType name="BasicNoiseServiceRequest_201102">
<xs:complexContent mixed="false">
<xs:extension base="CrmServiceRequest">
You can do it using XDocument for parsing and generating xml by generating a new XDocument from the loaded one.
// Parse a string or Load a file
var doc = XDocument.Parse(
#"<?xml version=""1.0"" encoding=""utf-8""?>
<xs:schema elementFormDefault=""qualified"" xmlns:xs=""http://www.w3.org/2001/XMLSchema"">
<xs:element name=""BasicNoiseServiceRequest_201102"" nillable=""true"" type=""BasicNoiseServiceRequest_201102"" />
<xs:complexType name=""BasicNoiseServiceRequest_201102"">
<xs:complexContent mixed=""false"">
<xs:extension base=""CrmServiceRequest"">
...
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:schema>
");
// Get the root of the document
var root = doc.Root;
// Create a new XDocument and add all the required attributes
// Keep all the existing xml file (declaration, child nodes, ...)
doc = new XDocument(doc.Declaration,
new XElement(root.Name, root.Elements(),
root.Attributes().Concat(new[]
{
new XAttribute("xmlns", "MyNamespace"),
new XAttribute("targetNamespace", "MyNamespace")
}))
);

How do I specify a list of required xml child elements that DONT need to be in sequence?

The following xml validates against the supplied xsd document. However when i start removing elements like from the xml it STILL validates!?
How do I write an xsd that forces the inclusion of elements?
<?xml version="1.0" encoding="UTF-8"?>
<Video>
<Title>
</Title>
<Description>
</Description>
<Contributor>
</Contributor>
<Subject>
</Subject>
</Video>
Then I have the xsd:
<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="UploadXSD"
targetNamespace="http://tempuri.org/UploadXSD.xsd"
elementFormDefault="qualified"
xmlns="http://tempuri.org/UploadXSD.xsd"
xmlns:mstns="http://tempuri.org/UploadXSD.xsd"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Video">
<xs:complexType>
<xs:sequence>
<xs:element name="Title" minOccurs="1" type="xs:string"></xs:element>
<xs:element name="Description" minOccurs="1" type="xs:string"></xs:element>
<xs:element name="Contributor" minOccurs="1" type="xs:string"></xs:element>
<xs:element name="Subject" minOccurs="1" type="xs:string"></xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
If you use xs:all as opposed to xs:sequence, the elements may appear in any order. There are some additional restrictions - for example, elements can not be specified multiple times using all (I'm not sure if you intend that usage, your schema would currently allow that.)
Your targetNamespace in the xsd should match the namespace of the xml you are trying to validate, i.e.
<Video xmlns="http://tempuri.org/UploadXSD.xsd">
<Title>
</Title>
<Description>
</Description>
<Contributor>
</Contributor>
<Subject>
</Subject>
</Video>

Categories