Deserialize an array of strings with DataContract - c#

I have an xml schema with a type defined like this:
<xs:complexType name="InteractiveWorkflowAddress">
<xs:sequence>
<xs:element name="endpointAddresses" nillable="true" type="q1:ArrayOfstring" xmlns:q1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" />
<xs:element name="instanceId" type="ser:guid" />
</xs:sequence>
</xs:complexType>
where the ArrayOfstring type is defined as
<xs:complexType name="ArrayOfstring">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="string" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:element name="ArrayOfstring" nillable="true" type="tns:ArrayOfstring" />
How can I deserialize the InteractiveWorkflowAddress type using the DataContract attribute? I tried the following
[DataContract(Namespace = Constants.Namespace)]
public class InteractiveWorkflowAddress {
[DataMember()]
public string[] EndpointAddresses;
[DataMember()]
public string InstanceId;
}
But while the InstanceId member is deserialized correctly, EndpointAddresses is always null.

The best way to figure out how something can be deserialized, is to first serialize. Serialize that InteractiveWorkflowAddress data structure and see the XML is creates. You might be able to List instead of string[] - and also you can control serialization with [XmlArray(...)] and [XmlArrayItem(...)] - which may help too.
The easist way is likely going to be doing some quick trial-and-error, by: making a change, serializing the class, seeing the output - then repeat. Hope that helps!

Related

XSD: Using Visual Studio xsd.exe not generating fixed/default values from base element set through restriction in the child element

What I want to achieve is have a base complex type which defines an Id and then have a child-specific value for that id along with each child having additional child-specific elements. I know this can't be achieved in one block so I defined the base type, then defined another type which sets the Id through restriction, and finally I have a type definition which extends the restricted type by adding some more elements.
The schema validates, but when I use the xsd.exe tool to generate the classes, the restricted class does not set the Id in the code at all, resulting in the Id value not being set in the extended class.
I have defined a base complex element in the following manner:
<xs:complexType name="BaseElem" abstract="true">
<xs:sequence>
<xs:element name="ElemId" type="xs:int"/>
</xs:sequence>
</xs:complexType>
Next, I added a child element which sets the ElemId value through restriction:
<xs:complexType name="BaseElemFoo">
<xs:complexContent>
<xs:restriction base="BaseElem">
<xs:sequence>
<xs:element name="ElemId" type="xs:int" final="1"/>
</xs:sequence>
</xs:restriction>
</xs:complexContent>
</xs:complexType>
Finally, I extend the BaseElemFoo to add some more elements and attributes:
<xs:complexType name="ElemFoo">
<xs:complexContent>
<xs:extension base="BaseElemFoo">
<xs:sequence>
<xs:element name="FirstElement" type="xs:string" />
<xs:element name="SecondElement" type="xs:string" />
</xs:sequence>
<xs:attribute name="FirstAttribute" type="xs:string"/>
<xs:attribute name="SecondAttribute" type="xs:string"/>
</xs:extension>
</xs:complexContent>
</xs:complexType>
After running xsd.exe (parameters /c and /n) to generate classes for the elements of this type, the ElemId is never set to 1 and the BaseElemFoo inherits from BaseElem, but is empty.
Is there a way to make xsd.exe generate the class from ElemFoo with ElemId value set to 1?

Modify xsd not to look for specific order of tags

I need to fix the error message below:
Error occured while validating xmlThe element 'UserFields' has invalid child element 'LastApproverID'. List of possible elements expected: 'FirtApproverID'.
Below is my xsd for validating the xml schema :
<xs:element name="UserFields" minOccurs="1" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="FirtApproverID" type="xs:string" minOccurs="1" />
<xs:element name="LastApproverID" type="xs:string" minOccurs="1" />
</xs:sequence>
</xs:complexType>
</xs:element>
The order of the firstapproverid and lastapproverid does not matter but the tag need to occur atleast once.
i.e it can appear
<UserFields>
<LastApproverID>123</LastApproverID>
<FirtApproverID>456</FirtApproverID>
</UserFields>
OR
<UserFields>
<FirtApproverID>456</FirtApproverID>
<LastApproverID>123</LastApproverID>
</UserFields>
The <xs:all> indicator can solve your problem.
See here for answer
Please, improve your Google skills.

XML auto generation issue

This is what my xsd looks like. Air and Car extend Segment.
<xs:element name="PNR" type="PNR" />
<xs:element minOccurs="0" maxOccurs="1" name="Segments" >
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="Segment" type="Segment"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="Air">
<xs:complexContent>
<xs:extension base="Segment">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="1" name="Departure" type="AirportInfo" />
<xs:element minOccurs="0" maxOccurs="1" name="Arrival" type="AirportInfo" />
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
<xs:complexType name="Car">
<xs:complexContent>
<xs:extension base="Segment">
<xs:sequence>
<xs:element name="PickUp" type="AddressInfo" minOccurs="0" maxOccurs="1"/>
<xs:element name="DropOff" type="AddressInfo" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
I want an output that looks like this:
<Segments>
<Segment xsi:type="Air">
<Departure></Departure>
<Arrival></Arrival>
</Segment>
<Segment xsi:type="Car">
<PickUp></PickUp>
<DropOff></DropOff>
</Segment>
</Segments>
But when I auto-generate XML from my XSD using a tool such as xmlspy or a .net library (or whatever), I get this (Air generated multi times w/o Car).
<Segments>
<Segment xsi:type="Air">
<Departure></Departure>
<Arrival></Arrival>
</Segment>
<Segment xsi:type="Air">
<Departure></Departure>
<Arrival></Arrival>
</Segment>
</Segments>
Is there something wrong with my XSD?
Here's a technique I once used to generate XML from a set of schemas. Although it doesn't look like the right class for the job, take a look at the XmlSchemaValidator class. The trick is that you can ask it what is valid for the document you're validating at that point in the validation. You can then generate the XML that is valid at that point in the document, and validate the same XML, in order to update the XmlSchemaValidator. You can then ask it again what is valid at that point in the document, etc.
When you get to an abstract type, you'll have to know to generate one of each possible derived type.

Returning array from webservice in Netbeans, .Net sees it as nullable array

So I've created a simple webservice in Netbeans to host on GlassFish. It goes a little something like this;
#WebMethod(operationName = "foo")
public double[] foo(#WebParam(name="bar") int bar)
{
//etc etc...
}
However, when I consume it in .Net(4.0), it is being shown as a double?[]. How do I stop it from being an array of nullable doubles? The xsd it contains the following for the response:
<xs:complexType name="BarResponse">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="return" nillable="true" type="xs:double" />
</xs:sequence>
</xs:complexType>
Note the nillable="true"

Deserializing XML to Objects defined in multiple schemas

I have an XML document containing types from 2 XML schemas. One (theirs.xsd) is a proprietary schema that I am integrating with (and cannot edit). To do this I am defining my own type (mine.xsd) that is an element within an 'any' element is the proprietary type.
I use Visual Studio's xsd.exe to generate C# classes from the schemas. However, the 'any' element in the proprietary type is generated as XmlElement[], and therefore my type doesn't get deserialized.
So I guess I can go one of two ways: either generate classes that will deserialize my type rather then keeping it as an XmlElement, or take the XmlElements and deserialize them individually. To deserialize I need an XmlReader, so I would need to go from an XmlElement to an XmlReader which I'm not sure how to do. Thanks.
Example:
File: theirs.xsd
<xs:element name="ProprietaryContainer">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
</xs:element>
File: mine.xsd
<xs:element name="MyPairType">
<xs:complexType>
<xs:sequence>
<xs:element name="key" type="xs:string"/>
<xs:element name="value" type="xs:long"/>
</xs:sequence>
</xs:complexType>
</xs:element>
File: message.xml
<their:ProprietaryContainer>
<their:name>pairContainer</their:name>
<mine:MyPairType>
<mine:key>abc</mine:key>
<mine:value>long</mine:value>
</mine:MyPairType>
</their:ProprietaryContainer>
From the question:
To deserialize I need an XmlReader, so I would need to go from an XmlElement to an XmlReader which I'm not sure how to do
using(XmlReader reader = new XmlNodeReader(element)) {
//... use reader
}

Categories

Resources