Как получить массивы с именем, отличным от «Items», при создании кода C # из схемы XSD? - PullRequest
4 голосов
/ 19 марта 2009

Я работаю над проектом, который должен соединиться с некоторыми древними веб-сервисами, которые упаковывают некоторые иерархические данные для запросов и ответов в отдельные строки иерархического XML.

Я использую xsd.exe для генерации XSD-файлов из примеров XML-фрагментов запросов и ответов, изменяя их, где это необходимо, для лучшего определения, и снова используя xsd.exe для генерации объектов C #. Менеджеры, которые вызывают веб-сервисы, могут затем принимать эти строго типизированные объекты запроса в качестве параметров, сериализовать их в строки для выполнения вызовов, возвращать ответы в виде строк, десериализовать их в объекты ответа со строгой типизацией и возвращать их.

Если у меня есть, скажем, список строк, у меня может быть действительный XSD, который считает его сложным типом неограниченных элементов xs: choice элементов xs: string, а затем он просто десериализуется в массив строк, который приятно и просто иметь дело с Раздражающая проблема заключается в том, что по какой-то причине, кажется, нет никакого способа заставить его вызывать строковый массив как-нибудь иначе, чем " Items ". Неважно, что Я добавляю в схему, я не могу получить xsd.exe для записи любого другого имени.

Вот пример схемы XSD:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="AccountStatusRequest" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xs:element name="AccountStatusRequest">
        <xs:complexType>
            <xs:choice minOccurs="0" maxOccurs="unbounded" id="AccountRowIDs">
                <xs:element nillable="true" type="xs:string" id="AccountRowID" name="AccountRowID"/>
            </xs:choice>
        </xs:complexType>
    </xs:element>
</xs:schema>

И полученный класс:

public partial class AccountStatusRequest {

    private string[] itemsField;

    [System.Xml.Serialization.XmlElementAttribute("AccountRowID", Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=true)]
    public string[] Items {
        get {
            return this.itemsField;
        }
        set {
            this.itemsField = value;
        }
    }
}

Я попытался добавить почти все атрибуты msdata: в intellisense как к выбору, так и к внутреннему элементу, и ничто не имеет значения.

Просто ради аргумента я добавил пару дополнительных похожих вариантов к этому complexType, чтобы посмотреть, не заставит ли это использовать имя для строковых массивов, но вместо этого он дал мне Items , Items1 , Items2 ...

Я действительно не хочу, чтобы это был массив своего собственного типа, который содержит только строку, но я также не хочу оставлять его под названием " Items ", без xml комментарии (кто-нибудь знает, как добавить ЭТО в xsd?), когда у него должно быть более описательное имя. И я определенно не могу просто изменить его вручную в качестве нужного рабочего процесса всякий раз, когда меняются схемы веб-сервиса, состоящие в том, чтобы изменить XSD и затем заново сгенерировать из них классы.

Это похоже на еще одну из тех вещей, которые должен поддерживать xsd.exe. Я что-то упускаю? Должен ли я принять другой подход как-то? Или есть альтернативный инструмент, который я мог бы использовать для этого, но менее хромой?

Ответы [ 3 ]

7 голосов
/ 02 апреля 2009

Попробуйте изменить выбор на последовательность, и поставить min / max в элементе AccountRowID ...

0 голосов
/ 02 апреля 2009

Редактировать: извините, я как-то пропустил предыдущий ответ - он работал для меня - вот схема, которую я использовал, и результат. Мои оригинальные ответы также могут быть уместны.

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="AccountStatusRequest" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xs:element name="AccountStatusRequest" msdata:ColumnName="AccountList">
        <xs:complexType>
            <xs:sequence minOccurs="0" maxOccurs="unbounded" id="AccountRowIDs">
              <xs:element nillable="true" type="xs:string" id="AccountRowID" name="AccountRowID"/>
            </xs:sequence>
        </xs:complexType>
    </xs:element>  
</xs:schema>

public partial class AccountStatusRequest {

    private string[] accountRowIDField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("AccountRowID", Form=System.Xml.Schema.XmlSchemaForm.Unqualified, IsNullable=true)]
    public string[] AccountRowID {
        get {
            return this.accountRowIDField;
        }
        set {
            this.accountRowIDField = value;
        }
    }
}

Привет, я несколько изменил схему, заменив выбор списком, обернутым в simpleType, и атрибутом, который дал желаемый результат (именованный массив строк). Однако я не уверен, подходит ли измененная схема для того, что вы делаете?

Вот модифицированная схема:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema id="AccountStatusRequest" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
    <xs:element name="AccountStatusRequest" msdata:ColumnName="AccountList">
        <xs:complexType>
          <xs:attribute name="AccountRowIDs">
            <xs:simpleType id="AccountRowID"  >
              <xs:list itemType="xs:string">                
              </xs:list>
            </xs:simpleType>       
          </xs:attribute>
        </xs:complexType>
    </xs:element>  
</xs:schema>

.. и вывод после запуска его с xsd.exe:

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace="", IsNullable=false)]
public partial class AccountStatusRequest {

    private string[] accountRowIDsField;

    /// <remarks/>
    [System.Xml.Serialization.XmlAttributeAttribute()]
    public string[] AccountRowIDs {
        get {
            return this.accountRowIDsField;
        }
        set {
            this.accountRowIDsField = value;
        }
    }
}
0 голосов
/ 19 марта 2009

Я вполне уверен, что это ограничение xsd.exe; Вы можете получить пользовательские результаты в другом направлении (class => xml / xsd), но это вам мало поможет. К сожалению.

...