I have a base class with a few properties, and three deriving classes.
I want to serialize an object containing all three derived classes, but each derived class should expose a different set of properties from base class.
I want to do this dynamically with XmlAttributeOverrides and have tried a few differnt ways to do that, but nothing that really does it.
[Serializable]
public class A
{
public string Property1 { get; set; }
public string Property2 { get; set; }
}
[Serializable]
public class B : A
{
}
[Serializable]
public class C : A
{
}
[Serializable]
public class Container
{
public B B { get; set; }
public C C { get; set; }
}
class Program
{
static void Main(string[] args)
{
MemoryStream memoryStream = new MemoryStream();
StreamWriter encodingWriter = new StreamWriter(memoryStream, Encoding.Unicode);
var xmlWriter = XmlWriter.Create(encodingWriter, new XmlWriterSettings
{
Indent = false,
OmitXmlDeclaration = true,
});
XmlAttributeOverrides overrides = new XmlAttributeOverrides();
XmlAttributes attribute = new XmlAttributes();
attribute.XmlIgnore = true;
overrides.Add(typeof(B), "Property1", attribute);
overrides.Add(typeof(C), "Property2", attribute);
var container = new Container
{
B = new B {Property1 = "B property 1", Property2 = "B property 2"},
C = new C {Property1 = "C property 1", Property2 = "C property 2"}
};
var xmlSerializer = new XmlSerializer(typeof(Container), overrides);
xmlSerializer.Serialize(xmlWriter, container);
var result = Encoding.Unicode.GetString(memoryStream.ToArray());
}
}
In the above code, the result string will contain all the properties of A in B and C, but I really want it just to contain B Property2 and C Property1 (as I have set the XmlIgnore attributes for them).
How do I do this?
EDIT: The expected XML:
<Container xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><B><Property2>B property 2</Property2></B><C><Property1>C property 1</Property1></C></Container>
The actual XML:
<Container xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><B><Property1>B property 1</Property1><Property2>B property 2</Property2></B><C><Property1>C property 1</Property1><Property2>C property 2</Property2></C></Container>
EDIT 2: The above is an example to visualize the problem, but I will expand on why we have the need to do this.
We have a Container-class (like above) which contains different kinds of derived objects (like above).
When we expose data from the Container-class to others, we want to be able to expose just certain fields which are configurable at some other place (might be sensitive data or whatnot).
This we do with help of XmlAttributeOverrides to set XmlIgnore property for the exposed properties. This works well for most types of objects (which does not have inheritance), but now we have the need to serialize different derived objects in different ways (configurable).
So in the above example, some customer has made the decision to exclude Property1 from class B and Property2 from class C, and as such I want the XML to look like above.
This did not work with the above code though; it seems like XmlSerializer uses the settings for the properties from the base class A, instead of using it from the respective derived classes B and C.
It's hard to tell from your question exactly what XML output you're looking for, so I'll just throw out an example and you can modify it as you need to. (EDIT: Seems I lucked out; the sample implementations below match your edited desired XML result)
You can use the little known ShouldSerializePROPERTYNAME method to dynamically instruct the XmlSerializer to ignore properties. For example:
public class A
{
public string Property1 { get; set; }
public string Property2 { get; set; }
public virtual bool ShouldSerializeProperty1()
{
return true;
}
public virtual bool ShouldSerializeProperty2()
{
return true;
}
}
These methods can then be overridden by the subclasses to ignore those properties:
public class B : A
{
public override bool ShouldSerializeProperty1()
{
return false;
}
}
public class C : A
{
public override bool ShouldSerializeProperty2()
{
return false;
}
}
Similarly, you can control the return values of the methods via other properties which can be assigned by Container:
public class A
{
public string Property1 { get; set; }
public string Property2 { get; set; }
[XmlIgnore]
internal bool _ShouldSerializeProperty1 = true;
[XmlIgnore]
internal bool _ShouldSerializeProperty2 = true;
public bool ShouldSerializeProperty1()
{
return _ShouldSerializeProperty1;
}
public bool ShouldSerializeProperty2()
{
return _ShouldSerializeProperty2;
}
}
Then when assigning B and C to Container, you can set those flags:
public class Container
{
private B _B;
public B B
{
get
{
return _B;
}
set
{
if (value != null)
{
value._ShouldSerializeProperty1 = false;
value._ShouldSerializeProperty2 = true;
}
_B = value;
}
}
private C _C;
public C C
{
get
{
return _C;
}
set
{
if (value != null)
{
value._ShouldSerializeProperty1 = true;
value._ShouldSerializeProperty2 = false;
}
_C = value;
}
}
}
These are just some examples (and I don't claim to have used best practices here) to demonstrate how ShouldSerialize can be used. You'll probably want to adapt it however best to your particular usage.
EDIT: Given your updated post, there's another possibility but requires a bit of extra work defining your subclasses and some DRY violation (though for serialization, sometimes that's ok).
First define A's properties as virtual and override them in the subclasses as basic wrappers:
public class A
{
public virtual string Property1 { get; set; }
public virtual string Property2 { get; set; }
}
public class B : A
{
public override string Property1 { get { return base.Property1; } set { base.Property1 = value; } }
public override string Property2 { get { return base.Property2; } set { base.Property2 = value; } }
}
public class C : A
{
public override string Property1 { get { return base.Property1; } set { base.Property1 = value; } }
public override string Property2 { get { return base.Property2; } set { base.Property2 = value; } }
}
Then since (I'm assuming) you're managing/building your XmlSerializer serialization via those configurations, include XmlIgnore overrides for all of the base class's properties:
overrides.Add(typeof(A), "Property1", attribute);
overrides.Add(typeof(A), "Property2", attribute);
Then also include XmlIgnore overrides for the subclass properties that you wish to truly ignore:
overrides.Add(typeof(B), "Property2", attribute);
overrides.Add(typeof(C), "Property1", attribute);
This will produce your desired output.
Related
In order to make an export, I need to overload an object in order to add a property which will transform a property from master class :
public class A
{
public int MyProperty1 { get; set; };
public int MyProperty2 { get; set; };
/*...*/
public myType MyPropertyN { get; set; };
}
public class B : A
{
public override string MyProperty1
{
get :
{
return A.MyProperty1.ToString();
}
set :
{
a.MyProperty1 = int.parse(value);
}
}
}
The problem is my A objects are already instantiated because the model come from the database.
I'm looking for a solution where I can do something like this :
var List<A> myListOfA = PopulateFromSomewhere();
var List<B> myListOfB = myListOfA.Select(x => new B(x)).ToList();
Where A will be copied in B and after call B in my export. I don't want to copy manually all properties of A in the constructor of B. Some objects have more than 20 properties.
Most of the time changing the return-type from a class is a sign of a bad design. In particular it means that you should favour composition over inheritance.
Having said this what you actuall want is to map one class to another. You can do that yourself, e.g. like this:
class A
{
int MyProperty { get; set; }
}
class B
{
private readonly A a;
public B(A a) { this.a = a; }
}
Now you can easily implement your mapping:
class B
{
public string MyProperty
{
get => this.a.MyProperty.ToString();
set => { this.a.MyProperty = int.Parse(value); } // consider to check the value before conversion
}
}
This is just the basic idea. As your models can become huge and doing this mapping yourself therefor becomes pretty cumbersome, you'd best use some automatic mapper, e.g. AutoMapper for that.
I am running into an issue with field inheritance. First I will explain how I would like it to work, and then ask for suggestions on how I can change the syntax to do what I want.
Here's what I tried:
public abstract class A
{
public abstract D D1
{
get;
}
protected D _d2;
public virtual D D2
{
get { return _d2; }
set { _d2 = value; }
}
}
public abstract class B : A
{
protected D _d1;
public override D D1
{
get { return _d1; }
set
{
_d1 = value;
Update();
}
}
}
public abstract class C : A
{
public override D D1
{
get
{
return _d2.Find1();
}
}
public override D D2
{
get { return base.D2; }
set
{
base.D2 = value;
Update();
}
}
}
The problem is that A doesn't compile because it can't find an method to override with D1's set. This how I expected it to work:
A ab = new B();
print(ab.D1);
ab.D1 = 4; // I would expect a compiler error
((B)ab).D1 = 4; // I would expect a compiler error
A ac = new C();
print(ac.D1);
ac.D1 = 4; // I would expect a compiler error
((C)ac).D1 = 4; // **I would expect this to work**
One solution I can see would be to add "set;" to A1's D1 and throw a NotImplementedException if I try to use it in C, but that would prevent the issue from showing up in the compiler. Anyone know of a way around this issue? I would really like to keep them as fields so that I can display them using WPF.
Extending a property with a setter does not work with class inheritance; however, it works with interface implementation
public interface I
{
int Prop { get; }
}
public abstract class A : I
{
public abstract int Prop { get; protected set; }
public abstract int Prop2 { get; }
}
public class B : A
{
public override int Prop
{
get;
set; // ERROR: Cannot change accesibility here.
}
public override Prop2 { get; set; } // ERROR: Cannot add setter here.
}
public class C : I
{
public int Prop { get; set; } // OK: Adding a setter works here.
}
Your error is with class B. In class A you define D1 as public abstract D D1 { get; } However in B you are attempting to override D1 and add a setter -- which is not defined by the abstract class. You'll need to find another way to set the value in B. If other classes need to be able to set D1 then you may want to define D1 as public abstract D D1 { get; set; }
If B only need to be able to set the value, just have it directly set the member value.
I'm using System.Xaml.XamlServices.Save method to serialize an object which has properties with public getters/private setters and by design these properties are ignored. I tried to implement advice of how to override default XAML bindings and get private properties serialized, but it doesn't work for some reason - those properties are still ignored. Could anyone point out what's wrong:
public class CustomXamlSchemaContext : XamlSchemaContext
{
protected override XamlType GetXamlType(string xamlNamespace, string name, params XamlType[] typeArguments)
{
var type = base.GetXamlType(xamlNamespace, name, typeArguments);
return new CustomXamlType(type.UnderlyingType, type.SchemaContext, type.Invoker);
}
}
public class CustomXamlType : XamlType
{
public CustomXamlType(Type underlyingType, XamlSchemaContext schemaContext, XamlTypeInvoker invoker) : base(underlyingType, schemaContext, invoker)
{
}
protected override bool LookupIsConstructible()
{
return true;
}
protected override XamlMember LookupMember(string name, bool skipReadOnlyCheck)
{
var member = base.LookupMember(name, skipReadOnlyCheck);
return new CustomXamlMember(member.Name, member.DeclaringType, member.IsAttachable);
}
}
public class CustomXamlMember : XamlMember
{
public CustomXamlMember(string name, XamlType declaringType, bool isAttachable) : base(name, declaringType, isAttachable)
{
}
protected override bool LookupIsReadOnly()
{
return false;
}
}
public static string Save(object instance)
{
var stringWriter1 = new StringWriter(CultureInfo.CurrentCulture);
var stringWriter2 = stringWriter1;
var settings = new XmlWriterSettings { Indent = true, OmitXmlDeclaration = true };
using (var writer = XmlWriter.Create(stringWriter2, settings))
{
Save(writer, instance);
}
return stringWriter1.ToString();
}
public static void Save(XmlWriter writer, object instance)
{
if (writer == null)
throw new ArgumentNullException("writer");
using (var xamlXmlWriter = new XamlXmlWriter(writer, new CustomXamlSchemaContext()))
{
XamlServices.Save(xamlXmlWriter, instance);
}
}
Having above infrastructure code and a class
public class Class1
{
public string Property1 { get; private set; }
public string Property2 { get; set; }
public DateTime AddedProperty { get; set; }
}
and serializing an instance of this class with
var obj = new Class1 { Property1 = "value1", Property2 = "value2" };
var objString = Save(obj);
I get the result
<Class1 AddedProperty="0001-01-01" Property2="value2" xmlns="clr-namespace:TestNamespace;assembly=Tests" />
where there is no entry for Property1.
What's even more interesting, that none of the overloads are called during serialization.
It turned out couple tweaks to my initial code solves the problem. Here's final solution:
private class CustomXamlSchemaContext : XamlSchemaContext
{
public override XamlType GetXamlType(Type type)
{
var xamlType = base.GetXamlType(type);
return new CustomXamlType(xamlType.UnderlyingType, xamlType.SchemaContext, xamlType.Invoker);
}
}
private class CustomXamlType : XamlType
{
public CustomXamlType(Type underlyingType, XamlSchemaContext schemaContext, XamlTypeInvoker invoker)
: base(underlyingType, schemaContext, invoker)
{
}
protected override bool LookupIsConstructible()
{
return true;
}
protected override XamlMember LookupMember(string name, bool skipReadOnlyCheck)
{
var member = base.LookupMember(name, skipReadOnlyCheck);
return member == null ? null : new CustomXamlMember((PropertyInfo)member.UnderlyingMember, SchemaContext, member.Invoker);
}
protected override IEnumerable<XamlMember> LookupAllMembers()
{
foreach (var member in base.LookupAllMembers())
{
var value = new CustomXamlMember((PropertyInfo)member.UnderlyingMember, SchemaContext, member.Invoker);
yield return value;
}
}
protected override bool LookupIsPublic()
{
return true;
}
}
private class CustomXamlMember : XamlMember
{
public CustomXamlMember(PropertyInfo propertyInfo, XamlSchemaContext schemaContext, XamlMemberInvoker invoker)
: base(propertyInfo, schemaContext, invoker)
{
}
protected override bool LookupIsReadOnly()
{
return false;
}
protected override bool LookupIsWritePublic()
{
return true;
}
}
This customization allows to serialize/deserialize properties with public getter and public/internal/protected/private setters. It ignores all the other properties. It also serializes instances of internal classes.
The problem here is that you are attempting to write readonly and private properties.
According to the XAML standard the only readonly properties that are syntactically correct are for List, Dictionary and static members:
3.3.1.6. Only List, Dictionary, or Static Members may be Read-only
If neither [value type][is list] nor [value type][is dictionary], nor [is static] is True, [is read only] MUST be False.
Have a look here for MSDN syntax detail.
And the standard itself can be downloaded here.
You'll also note that only public properties have any relevance here (from msdn linked above):
In order to be set through attribute syntax, a property must be public and must be writeable. The value of the property in the backing type system must be a value type, or must be a reference type that can be instantiated or referenced by a XAML processor when accessing the relevant backing type.
For WPF XAML events, the event that is referenced as the attribute
name must be public and have a public delegate.
The property or event must be a member of the class or structure that
is instantiated by the containing object element.
and if you think about it you can see why.
The whole C# standard is really built around using classes that interact by using public properties and methods. By doing so other classes don't need to know what resides within a class beyond them. Each class can be treated as a black box where the public properties and methods are the class's interface to other code.
Here's an informative blog regarding XAML serialization.
Personally I would ask myself why I need to serialize/deserialize private member properties.
I'm not quite sure what is wrong with the above code, but if you like I can provide an alternative.
This is kind of a hacky way to do it, but it works (tested it). First, you can throw away all that custom XAML stuff. Then, just change your Class1 to be:
public class Class1
{
private string _Property1;
public string Property2 { get; set; }
public DateTime AddedProperty { get; set; }
public Class1()
{
}
public Class1(string prop1, string prop2)
{
_Property1 = prop1;
Property2 = prop2;
}
public string Property1
{
get { return _Property1; }
set { }
}
}
While the set accessor is accessible, it doesn't do anything so in effect this is the same as a public getter/private setter setup. Proper documentation will also help if someone else needs to use your Class1 and is wondering why the 'set' isn't working for Property1.
This could be a plan B in case no one posts a fix for your above code.
Update: If you need to deserialize the object as well, you could create another object that acts as a go-between for your Class1 and the serialization process. The whole setup would look like this:
public class Class1
{
public string Property1 { get; private set; }
public string Property2 { get; set; }
public DateTime AddedProperty { get; set; }
public Class1()
{
}
public Class1(string prop1, string prop2) : this()
{
Property1 = prop1;
Property2 = prop2;
}
public Class1(Class1DTO dto)
{
Property1 = dto.Property1;
}
public Class1DTO CreateDTO()
{
return new Class1DTO
{
AddedProperty = AddedProperty,
Property1 = Property1,
Property2 = Property2
};
}
}
public class Class1DTO
{
public string Property1 { get; set; }
public string Property2 { get; set; }
public DateTime AddedProperty { get; set; }
}
The whole serialization/deserialization process would be like this:
var obj = new Class1("value1", "value2");
var dto = obj.CreateDTO();
var objString = Save(dto);
using (var stringReader = new StringReader(objString))
{
using (var reader = new XamlXmlReader(stringReader))
{
var deserializedDTO = XamlServices.Load(reader);
var originalObj = new Class1(dto);
}
}
You can then change access modifiers to fine tune the amount of access other people would have on your whole setup (you could create static Serialize/Deserialize methods on your Class1 type and push the Class1DTO type into a private nested class so people can't access it etc.).
Here`s the question.
public abstract class A {}
public class B:A
{
public TypeF FieldB;
}
public class C:A
{
public TypeG FieldC;
}
public class TypeF:A { }
public class TypeG:A { }
I want to have interface ex: ITypeFG and to implement it in B and C BUT to have properties names FieldB and FieldC
interface ITypeFG
{
public A FieldFG; //But i want to have names TypeF in A and TypeG in B
}
Can this be done?
Thanks.
explicit interface implementation:
public class B : A, ITypeFG
{
public TypeF FieldB { get; set; } // please don't expose public fields...
A ITypeFG.FieldFG { get { return FieldB; } }
}
public class C : A, ITypeFG
{
public TypeG FieldC { get; set; }
A ITypeFG.FieldFG { get { return FieldC; } }
}
Note that if the interface has a setter, you'll need to cast:
public class B : A, ITypeFG
{
public TypeF FieldB { get; set; }
A ITypeFG.FieldFG { get { return FieldB; } set { FieldB = (TypeF)value; } }
}
public class C : A, ITypeFG
{
public TypeG FieldC { get; set; }
A ITypeFG.FieldFG { get { return FieldC; } set { FieldC = (TypeG)value; } }
}
Two points:
Interfaces in C# can't have fields, but they can have properties.
The desired feature isn't sensible: if clients would always have to know the "specific" name of the implemented interface-property to interact with an implementation, then it isn't much of an interface is it - it's little more than a marker.
As Marc Gravell suggests, a decent workaround is to use explicit implementations. If the client has a reference to the implementing object typed as the interface, they can use the "general" name of the property. If they have a specific reference (i.e. typed as the implementing type) , they can use the "specific" name (and won't be confused by the general name since they won't see it on IntelliSense, for example).
Sounds like you should treat the field names as data along with A. That way you can keep a common interface and only vary the content of what is returned:
class Data
{
public string Name {get;set;}
public A Value {get;set;}
}
interface ITypeFG
{
Data Field {get;}
}
class B : A, ITypeFG
{
public Data Field
{
get
{
return new Data {Name = "TypeF", Value = FieldB};
}
}
}
class C : A, ITypeFG
{
public Data Field
{
get
{
return new Data {Name = "TypeG", Value = FieldC};
}
}
}
Let's suppose I have this object:
[Serializable]
public class MyClass
{
public int Age { get; set; }
public int MyClassB { get; set; }
}
[Serializable]
public class MyClassB
{
public int RandomNumber { get; set; }
}
The XmlSerializer will serialize the object like that:
<MyClass>
<Age>0</age>
<MyClassB>
<RandomNumber>4234</RandomNumber>
</MyClassB>
</MyClass>
How can I made the property Age nullable? IE: to not serialize the property Age when it's under 0?
I tried with the Nullable, but it serialize my object like that:
<MyClass>
<Age d5p1:nil="true" />
<MyClassB>
<RandomNumber>4234</RandomNumber>
</MyClassB>
</MyClass>
By reading the MSDN documentation I found this:
You cannot apply the IsNullable property to a member typed as a value type because a value type cannot contain nullNothingnullptra null reference (Nothing in Visual Basic). Additionally, you cannot set this property to false for nullable value types. When such types are nullNothingnullptra null reference (Nothing in Visual Basic), they will be serialized by setting xsi:nil to true.
source: http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlelementattribute.isnullable.aspx
I understand a value type can't be set to null. A valuetype is always set to something. The serialization can't make the decision to serialize it or not based on it's current value.
I tried with the attributes, but it didn't work out. I tried creating an agecontainer object and manipulate it's serialization with attributes, but it didn't work out.
What I really want is:
<MyClass>
<MyClassB>
<RandomNumber>4234</RandomNumber>
</MyClassB>
</MyClass>
When the property Age is below 0 (zero).
Looks like you'll have to implement custom serialization.
Yeah, that's what I though too, but I'd like to get away without it.
In the application, the object is much more complex, and I would like to not handle the serialization myself.
I just discovered this. XmlSerialier looks for a XXXSpecified boolean property to determine if it should be included. This should solve the problem nicely.
[Serializable]
public class MyClass
{
public int Age { get; set; }
[XmlIgnore]
public bool AgeSpecified { get { return Age >= 0; } }
public int MyClassB { get; set; }
}
[Serializable]
public class MyClassB
{
public int RandomNumber { get; set; }
}
Proof:
static string Serialize<T>(T obj)
{
var serializer = new XmlSerializer(typeof(T));
var builder = new StringBuilder();
using (var writer = new StringWriter(builder))
{
serializer.Serialize(writer, obj);
return builder.ToString();
}
}
static void Main(string[] args)
{
var withoutAge = new MyClass() { Age = -1 };
var withAge = new MyClass() { Age = 20 };
Serialize(withoutAge); // = <MyClass><MyClassB>0</MyClassB></MyClass>
Serialize(withAge); // = <MyClass><Age>20</Age><MyClassB>0</MyClassB></MyClass>
}
Edit: Yes, it is a documented feature. See the MSDN entry for XmlSerializer
Another option is to use a special pattern to create a Boolean field recognized by the XmlSerializer, and to apply the XmlIgnoreAttribute to the field. The pattern is created in the form of propertyNameSpecified. For example, if there is a field named "MyFirstName" you would also create a field named "MyFirstNameSpecified" that instructs the XmlSerializer whether to generate the XML element named "MyFirstName".
Extending Samuel's answer and Greg Beech's comment to the case of a boolean property: if the property is of type bool then you can't write a simple test in the propertySpecified property.
A solution is to use a Nullable<bool> type, then the test in the propertySpecified property is simply property.HasValue. e.g.
using System.Xml.Serialization;
public class Person
{
public bool? Employed { get; set; }
[XmlIgnore]
public bool EmployedSpecified { get { return Employed.HasValue; } }
}
An alternative to using a nullable type for a numeric property (suggested by Greg Beech) is to set the value property to an invalid default value, such as -1, as follows:
using System.ComponentModel;
using System.Xml.Serialization;
public class Person
{
[DefaultValue(-1)]
public int Age { get; set; }
[XmlIgnore]
public bool AgeSpecified { get { return Age >= 0; } }
}
You can use XmlElementAttribute.IsNullable:
[Serializable]
public class MyClass
{
[XmlElement(IsNullable = true)]
public int? Age { get; set; }
public int MyClassB { get; set; }
}
This should help
Make Age int? and..
public bool ShouldSerializeAge() { return Age.HasValue; }
..it does mean adding the ShouldSerializeXXX methods to your class!
You need to do custom XML serialization; see IXmlSerializer.
public class MyClass : IXmlSerializable
{
public int Age { get; set; }
public MyClassB MyClassB { get; set; }
public System.Xml.Schema.XmlSchema GetSchema()
{
// http://msdn.microsoft.com/en-us/library/system.xml.serialization.ixmlserializable.aspx
return null;
}
public void ReadXml(XmlReader reader)
{
if (reader.IsStartElement("Age"))
Age = reader.ReadContentAsInt();
var serializer = new XmlSerializer(typeof(MyClassB));
MyClassB = (MyClassB)serializer.Deserialize(reader);
}
public void WriteXml(XmlWriter writer)
{
if (Age > 0)
{
writer.WriteStartElement("Age");
writer.WriteValue(Age);
writer.WriteEndElement();
}
var serializer = new XmlSerializer(typeof(MyClassB));
serializer.Serialize(writer, MyClassB);
}
}
Forget about Nullable ... ShouldSerializeXXX is a pretty solution.
Here Age will be serialized upon your condition.
[Serializable]
public class MyClass
{
public int Age { get; set; }
public int MyClassB { get; set; }
#region Conditional Serialization
public bool ShouldSerializeAge() { return age > 0; }
#endregion
}
[Serializable]
public class MyClassB
{
public int RandomNumber { get; set; }
}
xsd.exe will autogenerate the XXXSpecified property and accessors if you set the 'minoccurs' attribute as 'minoccurs="0"' for an element ... if you are using a schema to define your xml/class