Bugfix? and add cmd options

Nov 23, 2011 at 3:42 PM

Hi,

First of all I love your generator!

I have a schema that xsd2code parses but the output has some errors (in my domain that is) when I try to parse a serialized xml file based on the generated classes. The problem seems to be when the schema has a <xs:choice> and in my schema there is a choice from 2 different items. xsd2code generates a Property for the choice element and names it to "Item" and the type is System.Object. So far it's all good. But the XmlElementAttribute gets ElementName:="Item" as shown below which is the name that will be used for the serialized xml element and that doesn't validates against my schema  Either I would like the ElementName:="Item" omitted or set to the same name as elementName parameter in XmlElementAttribute(). 

<System.Xml.Serialization.XmlElementAttribute("avtal", GetType(DocheaderArchiveMetadataAvtal), Order:=0, ElementName:="Item"), _
 System.Xml.Serialization.XmlElementAttribute("kundhand", GetType(DocheaderArchiveMetadataKundhand), Order:=0)> _
Public Property Item() As Object
	Get
		Return Me.itemField
	End Get
	Set(ByVal value As Object)
		Me.itemField = Value
	End Set
End Property

I've added some rules in CodeExtensions.cs->ProcessClass() method that checks if propertyname is named "item" and is of type "System.Object" and replaces it with the "real" element name as shown below.

//These changes are to ensure that the attributes have the correct camel case name reference in them.
CodeAttributeDeclaration xmlElAtt = null;
if (attrs.Any(att => att.Name == "System.Xml.Serialization.XmlElementAttribute"))
{
    xmlElAtt = attrs.First(att => att.Name == "System.Xml.Serialization.XmlElementAttribute");
                            
    //Make sure that the elementname doesn't get named to item if property is type object
    string memberPropertyName;
    if (codeMemberProperty.Name.ToLower() == "item" &&
        codeMemberProperty.Type.BaseType == "System.Object")
    {
        var xmlArgument = (CodePrimitiveExpression)xmlElAtt.Arguments[0].Value;
        memberPropertyName = xmlArgument.Value.ToString();
    }
    else
    {
        memberPropertyName = codeMemberProperty.Name;
    }

    xmlElAtt.Arguments.Add(new CodeAttributeArgument("ElementName",
                                                            new CodePrimitiveExpression(
                                                                memberPropertyName)));

    //This is almost certainly the wrong place to address this issue
    FixBadTypeMapping(type, codeMemberProperty, xmlElAtt);
}

The above code will generate the below property

<System.Xml.Serialization.XmlElementAttribute("avtal", GetType(DocheaderArchiveMetadataAvtal), Order:=0, ElementName:="avtal"), _
 System.Xml.Serialization.XmlElementAttribute("kundhand", GetType(DocheaderArchiveMetadataKundhand), Order:=0)> _
Public Property Item() As Object
	Get
		Return Me.itemField
	End Get
	Set(ByVal value As Object)
		Me.itemField = Value
	End Set
End Property
and be serialized to

<metadata>
	<avtal id="1234567"/>
</metadata>

Or

<metadata>
	<kundhand id="1234567"/>
</metadata>

instead of 

<metadata>
	<item id="1234567"/>
</metadata>

I'm not sure that the Basetype check is necessary but maybe if a schema has an element named "Item" I guess it should remain that way =)

And I also would like commandline parameters for PascalCase and OrderXmlAttributes.

case "/pc":
case "/pc+":
    generatorParams.PropertyParams.PascalCaseProperty = true;
    break;

case "/pc-":
    generatorParams.PropertyParams.PascalCaseProperty = false;
    break;

case "ox":
case "ox+":
    generatorParams.Serialization.GenerateOrderXmlAttributes = true;
    break;

case "ox-":
    generatorParams.Serialization.GenerateOrderXmlAttributes = false;
    break;

Thanks again for a great tool.

Regards 
Thomas Gyllencreutz 

 

 

 

 

Jan 31, 2012 at 2:01 AM

I would like to see the same feature. 

In addition, I get a serialization error on choice which generates the following code

      [System.Xml.Serialization.XmlElementAttribute("publicationItem", typeof(publicationItemType), Order = 0)] 
      [System.Xml.Serialization.XmlElementAttribute("publicationJob", typeof(publicationJobType), Order = 0)]       
               public basePublicationType Item       
               {  get, set }          
     
[System.Xml.Serialization.XmlArrayAttribute(Order = 1)]       
        [System.Xml.Serialization.XmlArrayItemAttribute("scheduleItem", IsNullable = false)]       
        public List<scheduleItemType> schedule        { ... }

Message=Inconsistent sequencing: if used on one of the class's members, the 'Order' property is required on all particle-like members, please explicitly set 'Order' using XmlElement, XmlAnyElement or XmlArray custom attribute on class member 'publicationItem'.

 

Jan 31, 2012 at 2:05 AM

PS: Had to turn on GenerateXmlAttributes to avoid a whole series of serialization errors of the same type message. This last one remains, which appears to be confused on two items with order=0.

Jan 31, 2012 at 3:04 AM

Fixed my ordering problem. Had added properties to a non-generated partial class which included the property publicationItem - which serialization clearly did not like.

Lesson learned - either inherit from or wrapper the generated partial classes - don't add additional methods and properties - particularly if using serialization.