1

I have an xsd that I want to look a certain way serialized. I can achieve what I want with the following but the problem is, xsd2code generates an extra class that's completely unused anywhere. Am I doing it wrong? Is there another trick I am missing?

<xsd:schema 
xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
elementFormDefault="qualified" >

    <xsd:element name="UITranslatorConfiguration" >
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element ref="Queries" minOccurs="0" />
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>

    <xsd:element name="Queries">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element ref="Query" minOccurs="0" maxOccurs="unbounded"/>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>

    <xsd:element name="Query">
        <xsd:complexType>
            <xsd:simpleContent>
                <xsd:extension base="xsd:string">
                    <xsd:attribute name="QueryID" type="xsd:string" />
                </xsd:extension>
            </xsd:simpleContent>
        </xsd:complexType>
    </xsd:element>

</xsd:schema>

xml output I want:

<UITranslatorConfiguration>
    <Queries>
        <Query QueryID="queryID1">someQueryText</Query>
        <Query QueryID="queryiq2">someQueryText2</Query>
        <Query QueryID="queryiq3">someQueryText3</Query>
    </Queries>
<UITranslatorConfiguration>

The code it generates:

this is fine:

[System.CodeDom.Compiler.GeneratedCodeAttribute("Xsd2Code", "3.4.0.38968")]
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class UITranslatorConfiguration {

    [EditorBrowsable(EditorBrowsableState.Never)]
    private List<Query> queriesField;

    private static System.Xml.Serialization.XmlSerializer serializer;

    public UITranslatorConfiguration() {
        this.queriesField = new List<Query>();
    }

    [System.Xml.Serialization.XmlArrayAttribute(Order=0)]
    [System.Xml.Serialization.XmlArrayItemAttribute("Query", IsNullable=false)]
    public List<Query> Queries {
        get {
            return this.queriesField;
        }
        set {
            this.queriesField = value;
        }
    }
}

this is fine:

[System.CodeDom.Compiler.GeneratedCodeAttribute("Xsd2Code", "3.4.0.38968")]
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class Query {

    [EditorBrowsable(EditorBrowsableState.Never)]
    private string queryIDField;

    [EditorBrowsable(EditorBrowsableState.Never)]
    private string valueField;

    private static System.Xml.Serialization.XmlSerializer serializer;

    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string QueryID {
        get {
            return this.queryIDField;
        }
        set {
            this.queryIDField = value;
        }
    }

    [System.Xml.Serialization.XmlTextAttribute()]
    public string Value {
        get {
            return this.valueField;
        }
        set {
            this.valueField = value;
        }
    }
}

This is not fine. Where did this come from and why? It's not used anywhere at all. How do I make xsd2code not generate this class.

[System.CodeDom.Compiler.GeneratedCodeAttribute("Xsd2Code", "3.4.0.38968")]
[System.SerializableAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class Queries {

    [EditorBrowsable(EditorBrowsableState.Never)]
    private List<Query> queryField;

    private static System.Xml.Serialization.XmlSerializer serializer;

    public Queries() {
        this.queryField = new List<Query>();
    }

    [System.Xml.Serialization.XmlElementAttribute("Query", Order=0)]
    public List<Query> Query {
        get {
            return this.queryField;
        }
        set {
            this.queryField = value;
        }
    }
}
EbbnFlow
  • 653
  • 1
  • 9
  • 17
  • @Mightymuke I have not. I ended up leaving the extra class in the object model. It is not hurting anything by being in there. I can live with unused code even though it bloats the file and goes against my desire for minimal code. – EbbnFlow Nov 19 '12 at 16:21
  • 1
    I had similar "issues" with the generated code (eg, field names, etc). I ended up creating nice and clean entity classes and used [AutoMapper](https://github.com/AutoMapper/AutoMapper) to copy the data. This meant that I then didn't have to deal with the generated classes, and it also provided an [anti corruption layer](http://www.markhneedham.com/blog/2009/07/07/domain-driven-design-anti-corruption-layer/). However I'll take a quick look at xsd2code and update if I find anything interesting. – Mightymuke Nov 19 '12 at 19:28

2 Answers2

0

I had similar "issues" with the generated code (eg, ugly field names, etc). I ended up creating nice and clean entity classes and used AutoMapper to initialise them from the data in the generated classes. This meant that I then didn't have to deal directly with the generated classes, and it also provided an anti corruption layer. This would be my recommendation even if the generated classes had the most beautiful code in the world, simply to protect your application from any unexpected changes in the schema's.

However, I've just tested this in my version of xsd2code (3.5.3 built directly from the source with some additional patches to fix various issues I was having), and have confirmed that this behaviour is still occurring. I suggest you open an issue at the xsd2code site, but unfortunately there doesn't seem to be much focus on fixing them (I've submitted several patches which haven't yet been implemented), so I wouldn't expect a fix anytime soon. Thankfully you have been able to work around it.

Mightymuke
  • 5,094
  • 2
  • 31
  • 42
0

Your schema contains the explicit "Queries" element. This causes the generation of the class. To achieve a code set without the "Queries" class just specify the type of the Queries element to be of type="Query".

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="XMLSchema1"
    targetNamespace="http://tempuri.org/XMLSchema1.xsd"
    elementFormDefault="qualified"
    xmlns="http://tempuri.org/XMLSchema1.xsd"
    xmlns:mstns="http://tempuri.org/XMLSchema1.xsd"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
>

  <xs:element name="UITranslatorConfiguration">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="Queries" type="Query" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

  <xs:complexType name="Query">
    <xs:simpleContent>
      <xs:extension base="xs:string">
        <xs:attribute name="QueryID" type="xs:string"/>
      </xs:extension>
    </xs:simpleContent>
  </xs:complexType>

</xs:schema>

This will produce the desired result as shown

namespace Schemas1
{
    using System;
    using System.Diagnostics;
    using System.Xml.Serialization;
    using System.Collections;
    using System.Xml.Schema;
    using System.ComponentModel;
    using System.Collections.Generic;


    public partial class UITranslatorConfiguration
    {

        private List<Query> queriesField;

        public UITranslatorConfiguration()
        {
            this.queriesField = new List<Query>();
        }

        public List<Query> Queries
        {
            get
            {
                return this.queriesField;
            }
            set
            {
                this.queriesField = value;
            }
        }
    }

    public partial class Query
    {

        private string queryIDField;

        private string valueField;

        public string QueryID
        {
            get
            {
                return this.queryIDField;
            }
            set
            {
                this.queryIDField = value;
            }
        }

        [System.Xml.Serialization.XmlTextAttribute()]
        public string Value
        {
            get
            {
                return this.valueField;
            }
            set
            {
                this.valueField = value;
            }
        }
    }
}

In my experience with converting xsd files to auto-generated classes (regardless of the tool) I have found it is better to avoid the use of "ref" when possible and instead use the type directly in these situations.

Hope this helps.

  • This removes the xml element as well and renames Query elements to Queries. This doesn't generate the desired output. – Bart Dec 10 '14 at 12:37