2009-03-18 3 views
4

Je travaille sur un projet qui doit se connecter à d'anciens webservices qui regroupent des données hiérarchiques pour des requêtes et des réponses dans des chaînes uniques de XML hiérarchique. J'ai utilisé xsd.exe pour générer des XSD à partir de fragments de requête et de réponse XML, en les modifiant si nécessaire pour obtenir la meilleure définition possible et en utilisant à nouveau xsd.exe pour générer des objets C#. Les gestionnaires qui appellent les services Web peuvent ensuite prendre ces objets de requête fortement typés en paramètres, les sérialiser en chaînes pour effectuer les appels, récupérer les réponses en tant que chaînes, les désérialiser dans les objets de réponse fortement typés et les renvoyer. Si j'ai, disons, une liste de chaînes, je peux avoir un XSD valide qui le considère comme un type complexe d'un xs: string non choisi: choix d'éléments xs: string, puis il le désérialisera simplement en un tableau de chaînes, ce qui est agréable et simple à traiter. Le problème ennuyeux est que, pour une raison ou pour une autre, il ne semble pas y avoir moyen d'appeler le tableau de chaînes autre que "Items". J'ajoute au schéma, je ne peux pas obtenir xsd.exe pour écrire un autre nom.Comment puis-je obtenir des tableaux avec un nom autre que "Items" lors de la génération de code C# à partir d'un schéma XSD?

Voici un exemple de schéma 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> 

Et la classe résultante:

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; 
     } 
    } 
} 

J'ai essayé d'ajouter à peu près tous les msdata: attribut dans IntelliSense à la fois le choix et l'élément interne et rien ne fait la différence.

juste pour le plaisir de la discussion, j'ai ajouté un couple supplémentaire des choix similaires à celui complexType, pour voir si cela serait-il forcer à utiliser un nom pour les tableaux de chaînes, mais il m'a donné Articles, postes1 , envois2 ...

Je ne veux vraiment pas avoir à être un tableau de son propre type qui ne peut contenir qu'une chaîne, mais je aussi ne veux vraiment pas le laisser appelé "Articles ", sans commentaires xml (quelqu'un sait-il comment ajouter THOSE à un xsd?), quand il devrait avoir un nom plus descriptif. Et je ne peux définitivement pas le changer manuellement en tant que flux de travail souhaité à chaque fois que les schémas de service web changent, c'est changer les XSD et ensuite générer de nouveau les classes à partir d'eux.

Cela semble être une autre chose que xsd.exe devrait prendre en charge. Y a-t-il quelque chose qui me manque? Devrais-je adopter une approche différente? Ou y a-t-il un autre outil que je peux utiliser à la place qui est moins boiteux?

Répondre

-1

Edit: désolé d'avoir manqué la réponse précédente en quelque sorte - cela a fonctionné pour moi - voici le schéma je et résultat. Mes réponses originales pourraient également être appropriées.

<?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; 
     } 
    } 
} 

Salut, j'ai changé le schéma quelque peu, en substituant le choix avec une liste enveloppée par un simpleType et un attribut, qui a produit la sortie désirée (un tableau de chaînes nommé). Cependant, je ne suis pas sûr si le schéma modifié est approprié pour ce que vous faites?

Voici le schéma modifié:

<?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> 

..et la sortie après l'exécution avec 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

Je suis assez sûr que c'est une limitation de xsd.exe; vous pouvez obtenir des résultats personnalisés dans l'autre sens (class => xml/xsd), mais cela ne vous aide pas beaucoup. Pardon.

7

Essayez de changer le choix à la séquence, et mettre le min/max se produit dans l'élément AccountRowID ...

+1

Désolé ne sais pas comment je raté cette réponse - ça a marché pour moi +1 – RobS

Questions connexes