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>
I have a scenario where i have xml schema with same element name with same type at two different positions. Some xml will have the element in first position and few other xml are having the element in the second position.
<xs:element minOccurs="0" maxOccurs="1" name="DisplayUnit" type="DisplayUnit" />
<xs:element minOccurs="0" maxOccurs="1" name="Serial" type="Serial" />
<xs:element minOccurs="0" maxOccurs="1" name="DisplayUnit" type="DisplayUnit"/>
In my xml some time DisplayUnit comes above serial and some time after that. How i handle this scenario?
I have one more clarification. In this below scenario the element is not a type but a property. The position can be either above or below output element, but occurs only once like the first scenario.
<xs:element minOccurs="0" maxOccurs="0" name="MaxA" nillable="true" type="xs:unsignedInt" />
<xs:element minOccurs="0" maxOccurs="0" name="Output" type="Output" />
<xs:element minOccurs="0" maxOccurs="1" name="MaxA" nillable="true" type="xs:unsignedInt" />
I searched a lot but i didn't get any solution.
Any immediate help in this regard is appreciated.
Your question has two parts: the XSD part and the parser part.
XSD
Your XSD does not fit for the result you want to achieve. As it is written, it is possible that the DisplayUnit element occurrs twice in your document. There are two ways to resolve this, depending on your scenario.
If the DisplayUnit and Serial elements are the only elements in the sequence or the entire sequence can be in any order, you can use <xs:all> instead of <xs:sequence>. <xs:all> allows the elements to be in any order:
<xs:all>
<xs:element minOccurs="0" maxOccurs="1" name="DisplayUnit" type="DisplayUnit" />
<xs:element minOccurs="0" maxOccurs="1" name="Serial" type="Serial" />
</xs:all>
If this is not an option for you, because the other elements are expected to be in sequence, you can replace that part of the sequence by an <xs:choice>:
<xs:choice>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" name="DisplayUnit" type="DisplayUnit" />
<xs:element minOccurs="0" maxOccurs="1" name="Serial" type="Serial" />
</xs:sequence>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" name="Serial" type="Serial" />
<xs:element minOccurs="0" maxOccurs="1" name="DisplayUnit" type="DisplayUnit" />
</xs:sequence>
</xs:choice>
Parsing in C#
Once you have fixed your XSD and you have validated your document, you know that there is exactly zero or one occurrence of the DisplayUnit and Serial tags. Then you can simply load the XML into an XDocument or XmlDocument (if you didn't do that already) and simply access the elements by their name (regardles of order):
//Assuming there is an XElement named parentElement
XElement displayUnitElement = parentElement.Element("DisplayUnit");
if (displayUnitElement != null) {
//...
}
XElement serialElement = parentElement.Element("Serial");
if (serialElement != null) {
//...
}
On more complex XML you can also use XPath. Once your document validates against the XSD, you can be sure about its structure.
I've been given a number of XSD files - they are HUGE - for an insurance pricing engine, so as you can imagine, contain lots of nested complex types. Person, Address, Vehicles, Car Alarm, Speeding Convictions etc etc. Here's a subset containing a single complex type:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
<xs:complexType name="Vehicle">
<xs:choice maxOccurs="unbounded">
<xs:element name="ABICode" type="ABICode" minOccurs="0"/>
<xs:element name="ABSBrakes" type="ABSBrakes" minOccurs="0"/>
<xs:element name="AgedOver" type="AgedOver" minOccurs="0"/>
<xs:element name="AlarmSecurityFitted" type="AlarmSecurityFitted" minOccurs="0"/>
<xs:element name="AlarmSecurityMake" type="AlarmSecurityMake" minOccurs="0"/>
<xs:element name="AudioValue" type="AudioValue" minOccurs="0"/>
<xs:element name="CarPhoneValue" type="CarPhoneValue" minOccurs="0"/>
<xs:element name="Colour" type="Colour" minOccurs="0"/>
<xs:element name="CountryOfManufacture" type="CountryOfManufacture" minOccurs="0"/>
<xs:element name="CoverType" type="CoverType" minOccurs="0"/>
<xs:element name="CurrentMileage" type="CurrentMileage" minOccurs="0"/>
<xs:element name="Doors" type="Doors" minOccurs="0"/>
<xs:element name="EngineSize" type="EngineSize" minOccurs="0"/>
<xs:element name="EstimatedValue" type="EstimatedValue" minOccurs="0"/>
<xs:element name="Finish" type="Finish" minOccurs="0"/>
<xs:element name="FuelType" type="FuelType" minOccurs="0"/>
<xs:element name="HasSecurity" type="HasSecurity" minOccurs="0"/>
<xs:element name="ImmobSecurityFitted" type="ImmobSecurityFitted" minOccurs="0"/>
<xs:element name="ImmobSecurityMake" type="ImmobSecurityMake" minOccurs="0"/>
<xs:element name="Keeper" type="Keeper" minOccurs="0"/>
<xs:element name="Lhd" type="Lhd" minOccurs="0"/>
<xs:element name="Modified" type="Modified" minOccurs="0"/>
<xs:element name="NCBCountry" type="NCBCountry" minOccurs="0"/>
<xs:element name="NCBProtected" type="NCBProtected" minOccurs="0"/>
<xs:element name="NCBType" type="NCBType" minOccurs="0"/>
<xs:element name="NCBYears" type="NCBYears" minOccurs="0"/>
<xs:element name="NightLocation" type="NightLocation" minOccurs="0"/>
<xs:element name="Owner" type="Owner" minOccurs="0"/>
<xs:element name="OvernightPostCode" type="OvernightPostCode" minOccurs="0"/>
<xs:element name="PermittedDrivers" type="PermittedDrivers" minOccurs="0"/>
<xs:element name="PricePaid" type="PricePaid" minOccurs="0"/>
<xs:element name="PurchaseDate" type="PurchaseDate" minOccurs="0"/>
<xs:element name="Registration" type="Registration" minOccurs="0"/>
<xs:element name="Seats" type="Seats" minOccurs="0"/>
<xs:element name="TrackerSecurityFitted" type="TrackerSecurityFitted" minOccurs="0"/>
<xs:element name="TrackerSecurityMake" type="TrackerSecurityMake" minOccurs="0"/>
<xs:element name="Transmission" type="Transmission" minOccurs="0"/>
<xs:element name="Type" type="Type" minOccurs="0"/>
<xs:element name="Windscreen" type="Windscreen" minOccurs="0"/>
<xs:element name="YearManufacture" type="YearManufacture" minOccurs="0"/>
<xs:element name="Modification" type="Modification" minOccurs="0" maxOccurs="5"/>
</xs:choice>
</xs:complexType>
</xs:schema>
I've successfully used xsd.exe and xsd2code to generate classes based on the schema definiitions, however, the classes that have been produced are not strongly typed, and contain arrays of Objects such as this:
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.6.1064.2")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
public partial class Vehicle
{
private object[] _items;
private ItemsChoiceType4[] _itemsElementName;
[System.Xml.Serialization.XmlElementAttribute("ABICode", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("ABSBrakes", typeof(ABSBrakes))]
[System.Xml.Serialization.XmlElementAttribute("AgedOver", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("AlarmSecurityFitted", typeof(AlarmSecurityFitted))]
[System.Xml.Serialization.XmlElementAttribute("AlarmSecurityMake", typeof(AlarmSecurityMake))]
[System.Xml.Serialization.XmlElementAttribute("AudioValue", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("CarPhoneValue", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("Colour", typeof(Colour))]
[System.Xml.Serialization.XmlElementAttribute("CountryOfManufacture", typeof(CountryOfManufacture))]
[System.Xml.Serialization.XmlElementAttribute("CoverType", typeof(CoverType))]
[System.Xml.Serialization.XmlElementAttribute("CurrentMileage", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("Doors", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("EngineSize", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("EstimatedValue", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("Finish", typeof(Finish))]
[System.Xml.Serialization.XmlElementAttribute("FuelType", typeof(FuelType))]
[System.Xml.Serialization.XmlElementAttribute("HasSecurity", typeof(HasSecurity))]
[System.Xml.Serialization.XmlElementAttribute("ImmobSecurityFitted", typeof(ImmobSecurityFitted))]
[System.Xml.Serialization.XmlElementAttribute("ImmobSecurityMake", typeof(ImmobSecurityMake))]
[System.Xml.Serialization.XmlElementAttribute("Keeper", typeof(Keeper))]
[System.Xml.Serialization.XmlElementAttribute("Lhd", typeof(Lhd))]
[System.Xml.Serialization.XmlElementAttribute("Modification", typeof(Modification))]
[System.Xml.Serialization.XmlElementAttribute("Modified", typeof(Modified))]
[System.Xml.Serialization.XmlElementAttribute("NCBCountry", typeof(NCBCountry))]
[System.Xml.Serialization.XmlElementAttribute("NCBProtected", typeof(NCBProtected))]
[System.Xml.Serialization.XmlElementAttribute("NCBType", typeof(NCBType))]
[System.Xml.Serialization.XmlElementAttribute("NCBYears", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("NightLocation", typeof(NightLocation))]
[System.Xml.Serialization.XmlElementAttribute("OvernightPostCode", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("Owner", typeof(Owner))]
[System.Xml.Serialization.XmlElementAttribute("PermittedDrivers", typeof(PermittedDrivers))]
[System.Xml.Serialization.XmlElementAttribute("PricePaid", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("PurchaseDate", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("Registration", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("Seats", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("TrackerSecurityFitted", typeof(TrackerSecurityFitted))]
[System.Xml.Serialization.XmlElementAttribute("TrackerSecurityMake", typeof(TrackerSecurityMake))]
[System.Xml.Serialization.XmlElementAttribute("Transmission", typeof(Transmission))]
[System.Xml.Serialization.XmlElementAttribute("Type", typeof(string))]
[System.Xml.Serialization.XmlElementAttribute("Windscreen", typeof(Windscreen))]
[System.Xml.Serialization.XmlElementAttribute("YearManufacture", typeof(string))]
[System.Xml.Serialization.XmlChoiceIdentifierAttribute("ItemsElementName")]
public object[] Items
{
get
{
return this._items;
}
set
{
this._items = value;
}
}
Ideally I would like the Vehicle class to have a number of properties which are instances of other classes so that I can use automapper to map from my domain model to the request object, serialize to XML and send the request.
But the way these types have been created, I have lost any information about the structure of the request object I need to build. Everything will need to be mapped explicitly property by property. And yet despite fiddling with all the settings in xsd2code and switches of xsd.exe I can't seem to get it to generate anything like what I want.
Is there a way to do what I want, or do I need to change my approach?
I've done similar work and used xsd.exe, but in this case I believe the problem is the way the schema is laid out. The Vehicle node is an unbounded list of elements that could be any one of 40 different types of objects (ABSBrakes, AgedOver ... YearManufacture). The creator of the schema hasn't left you any options other than to map them property by property.
I realize it's not what you want to hear, but when you come across windscreen data, create a Windscreen object and add it to Vehicle.Items and continue for each property. When you serialize this, it should create valid XML matching the given schema.
I hope I am correctly phrasing my problem. When we run the xsd tool on our xsd to create classes, the code is not exactly representing the xsd on one section. It is like this:
XSD: 'BaliseGroups' => Collection of 'BaliseGroup' => Collection of 'Balise'
Code: 'BaliseGroups' => Collection of type 'Balise' named 'BaliseGroup'...
<xs:element name="BaliseGroups">
<xs:annotation>
<xs:documentation>Een verzameling balisegroepen</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="BaliseGroup" type="tBaliseGroup"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="tBaliseGroup">
<xs:annotation>
<xs:documentation>Een balisegroep, </xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="Balise" type="tBalise" minOccurs="1" maxOccurs="8"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="tBalise">
<xs:annotation>
<xs:documentation>Type voor een balise</xs:documentation>
</xs:annotation>
<xs:complexContent>
<xs:extension base="tTrackAsset"/>
</xs:complexContent>
</xs:complexType>
Code
public partial class BaliseGroups
{
private tBalise[] baliseGroupField;
/// <remarks/>
[System.Xml.Serialization.XmlArrayItemAttribute("Balise", IsNullable = false)]
public tBalise[] BaliseGroup
{
get
{
return this.baliseGroupField;
}
set
{
this.baliseGroupField = value;
}
}
}
As you can see in the generated C# code block it creates a Property BaliseGroup of type Balise[]. This should be of type tBaliseGroup[].
I have a conjecture that there is something wrong with the xsd, but I cannot figure out what..
I have solved my problem. By annotating in the xsd that 'BaliseGroup' has a maxOccurs of 'unbounded' it creates the collection of 'BaliseGroup' in 'BaliseGroups'. Here is the change:
<xs:element name="BaliseGroups">
<xs:annotation>
<xs:documentation>Een verzameling balisegroepen</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="BaliseGroup" type="tBaliseGroup" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
Looking for an easy way to parse a list of strings (or 2d array[string1,string2])
where string 1 is the name and string 2 is the content.
The result should be an .xml containing only the data of string 2 filled in in all the places where the names of the xml schema are the same as string1.
<xs:include schemaLocation="common.xsd"/>
<xs:complexType name="part1Type">
<xs:all>
<xs:element name="noteCadre1" type="string5000Type" minOccurs="0"/>
<xs:element name="noteCadre2" type="string5000Type" minOccurs="0"/>
<xs:element name="noteCadre3" type="string5000Type" minOccurs="0"/>
<xs:element name="noteCadre4" type="string5000Type" minOccurs="0"/>
<xs:element name="noteCadre5" type="string5000Type" minOccurs="0"/>
<xs:element name="noteCadre6" type="string5000Type" minOccurs="0"/>
<xs:element name="noteCadre7" type="string5000Type" minOccurs="0"/>
<xs:element name="noteCadre8" type="string5000Type" minOccurs="0"/>
<xs:element name="noteCadre9" type="string5000Type" minOccurs="0"/>
<xs:element name="noteCadre10" type="string5000Type" minOccurs="0"/>
<xs:element name="noteCadre11" type="string5000Type" minOccurs="0"/>
<xs:element name="noteCadre12" type="string5000Type" minOccurs="0"/>
<xs:element name="infoResidence" type="home2Type" minOccurs="0"/>
<xs:complexType name="homeType">
<xs:sequence>
<xs:element name="lieu" type="string150Type"/>
<xs:element name="dateDebut" type="xs:date" minOccurs="0"/>
<xs:element name="dateFin" type="xs:date" minOccurs="0"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="home2Type">
<xs:sequence>
<xs:element name="item" type="homeType" maxOccurs="2"/>
</xs:sequence>
</xs:complexType>
The List<String> looks like this:
LIST 1 : {noteCadre1, noteCadre2, .... , infoResidence.lieu.1 , infoResidence.dateDebut.1 ,
infoResidence.dateFin.1 , infoResidence.lieu.2 , infoResidence.dateDebut.2 , ...
LIST 2 : {dataCadre1, dataCadre2, .... , Street 100, 01/01/20005, 25/03/2005, ..... }
Any help would be appreciated; browsed the web for a couple of days without any succes..
You can't do that using only XML Schema: XML Schema is about validating XML documents and not about parsing.
To do this kind of things you need to add a first step that transforms your input document (the list of strings) into your target XML representation.
This seems quite easy to achieve using any programming language (including XSLT 2.0) but this is clearly out of the scope of XML schema languages.