2010-02-08 7 views
4

j'ai ce ServiceDefinition:WSDL généré automatiquement par WCF

[DataContract] 
public class Test 
{ 

    [DataMember(IsRequired = true)] 
    public TestArray[] array; 
} 

[DataContract] 
public class TestArray 
{ 
    public DateTime? field1; 
    public string field2; 
} 

qui OSEFW Metadataprovider (http://localhost/Test?wsdl) génère comme:

<xs:complexType name="ArrayOfTestArray"> 
    <xs:sequence> 
    <xs:element minOccurs="0" maxOccurs="unbounded" name="array" nillable="true" type="tns:TestArray"/> 
    </xs:sequence> 
</xs:complexType> 

<xs:complexType name="OpenBalanceInvoice"> 
    <xs:sequence> 
    <xs:element name="field1" nillable="true" type="xs:dateTime"/> 
    <xs:element name="field2" nillable="true" type="xs:string"/> 
    </xs:sequence> 
</xs:complexType> 

Le problème est (même si elle fonctionne quand svcutil.exe génère magiquement un client à partir de celui-ci) que le fournisseur Metadata crée réellement un nouvel objet (ArrayOfTestArray) qui n'existe pas dans le code où il a été généré

P roblem: Lorsque j'essaie de générer un JavaClient à partir de ce WSDL, il ne reconnaît pas que cet objet "ArrayOf" n'est pas un objet "réel" et la classe Java ressemble à quelque chose comme:

class Test 
{ 
    public ArrayOfTestArray array; 
} 

class ArrayOfTestArray 
{ 
    public TestArray[] array; 
} 
public class TestArray 
{ 
    public DateTime? field1; 
    public string field2; 
} 

Donc, je ne veux pas cette classe supplémentaire de cours ... des suggestions?

Merci!

+0

Je ne sais pas si cela est utile, mais je consomme actuellement un service Web J2EE et je vois beaucoup de! Classes ArrayOfXXXX dans le fichier wsdl. Peut-être que c'est la façon standard de faire ça? Pas certain. –

+0

Je ne suis pas une personne .NET donc je ne suis pas entièrement sûr de savoir comment le code est généré dans .NET mais il semble que la raison pour laquelle vous avez 'ArrayOfTestArray' est que vous avez déclaré 'TestArray' comme requis et le générateur de code génère exactement ce que vous lui avez demandé. Les classes Java sont générées à partir du fichier wsdl qui a ce type défini afin que les classes semblent être générées correctement. Je n'ai pas envoyé de réponse car je ne sais pas vraiment comment .NET génère du code pour les services Web. – ChadNC

+0

En demandant à certains de mes collègues, il est sorti que la construction ArrayOf est un comportement standard ... eh bien, aucune idée sur la question sur le côté java jusqu'à présent – David

Répondre

1

Ma suggestion est de masser le fichier XSD lui-même, car il n'y a probablement pas grand chose à faire sur le côté .NET des choses.

La XSLT suivante devrait fonctionner dans votre cas (à condition que l'élément et les types complexes sont dans le même fichier de schéma):

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 

    <xsl:template match="xsd:complexType[@name]"> 
     <!-- This templace filters out any complexTypes with a name starting with 'ArrayOf' --> 
     <xsl:if test="not(starts-with(@name, 'ArrayOf'))"> 
      <xsl:copy> 
       <xsl:apply-templates select="@*" /> 
       <xsl:apply-templates /> 
      </xsl:copy> 
     </xsl:if> 
    </xsl:template> 

    <xsl:template match="xsd:element[@type]"> 
     <!-- This templace inlines any elements referencing a type starting with 'ArrayOf' --> 
     <xsl:variable name="typeName"> 
      <xsl:choose> 
       <xsl:when test="contains(@type, ':')"> 
        <xsl:value-of select="substring-after(@type, ':')" /> 
       </xsl:when> 
       <xsl:otherwise> 
        <xsl:value-of select="@type" /> 
       </xsl:otherwise> 
      </xsl:choose> 
     </xsl:variable> 

     <xsl:choose><!-- Should we inline? --> 
      <xsl:when test="starts-with($typeName, 'ArrayOf')"> 
       <!-- Yep, inline it, but wrap in a sequence! --> 
       <xsl:apply-templates select="xsd:annotation" /> 
       <xsd:element> 
        <!-- copy over attributes such as name, minOccurs, maxOccurs, nillable --> 
        <xsl:copy-of select="@*[local-name(.) != 'type']" /> 
        <xsl:comment> 
         Inlined from <xsl:value-of select="@type" />): 
        </xsl:comment> 
        <xsd:complexType> 
         <xsl:apply-templates select="//xsd:complexType[@name=$typeName]/*" /> 
        </xsd:complexType> 
        <xsl:comment>End of inlined element</xsl:comment> 
       </xsd:element> 

       <xsl:apply-templates 
        select="xsd:attribute | xsd:attributeGroup | xsd:attributeGroup" /> 
      </xsl:when> 
      <xsl:otherwise> 
       <!-- Nah, just copy --> 
       <xsl:copy> 
        <xsl:apply-templates select="@*" /> 
        <xsl:apply-templates /> 
       </xsl:copy> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 

    <!-- General copy rule --> 
    <xsl:template match="@*|node()"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*" /> 
      <xsl:apply-templates /> 
     </xsl:copy> 
    </xsl:template> 
</xsl:stylesheet> 

Compte tenu de cette XSD d'entrée:

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="http://www.example.org/ExtensionFlattener" xmlns:tns="http://www.example.org/ExtensionFlattener" 
    elementFormDefault="qualified"> 

    <xs:element name="SomeElement"> 
     <xs:complexType> 
      <xs:sequence> 
       <xs:element name="First" type="xs:string" /> 
       <xs:element name="Second" minOccurs="0" type="tns:ArrayOfTestArray" nillable="true"/> 
       <xs:element name="Third" type="xs:string" /> 
      </xs:sequence> 
     </xs:complexType> 
    </xs:element> 

    <xs:complexType name="ArrayOfTestArray"> 
     <xs:sequence> 
      <xs:element minOccurs="0" maxOccurs="unbounded" name="array" 
       nillable="true" type="tns:TestArray" /> 
     </xs:sequence> 
    </xs:complexType> 

    <xs:complexType name="TestArray"> 
     <xs:sequence> 
      <xs:element name="field1" nillable="true" type="xs:dateTime" /> 
      <xs:element name="field2" nillable="true" type="xs:string" /> 
     </xs:sequence> 
    </xs:complexType> 

</xs:schema> 

il tournera il en:

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    xmlns:tns="http://www.example.org/ExtensionFlattener" targetNamespace="http://www.example.org/ExtensionFlattener" 
    elementFormDefault="qualified"> 

    <xs:element name="SomeElement"> 
     <xs:complexType> 
      <xs:sequence> 
       <xs:element name="First" type="xs:string" /> 
       <xsd:element xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
        name="Second" minOccurs="0" nillable="true"> 
        <!-- Inlined from tns:ArrayOfTestArray): --> 
        <xsd:complexType> 
         <xs:sequence> 
          <xs:element minOccurs="0" maxOccurs="unbounded" name="array" 
           nillable="true" type="tns:TestArray" /> 
         </xs:sequence> 
        </xsd:complexType> 
        <!--End of inlined element --> 
       </xsd:element> 
       <xs:element name="Third" type="xs:string" /> 
      </xs:sequence> 
     </xs:complexType> 
    </xs:element> 



    <xs:complexType name="TestArray"> 
     <xs:sequence> 
      <xs:element name="field1" nillable="true" type="xs:dateTime" /> 
      <xs:element name="field2" nillable="true" type="xs:string" /> 
     </xs:sequence> 
    </xs:complexType> 

</xs:schema> 

Ceci produit des classes Java plus jolies (bien qu'il vous donne encore un supplément, lo cal, type):

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlType(name = "", propOrder = { 
    "first", 
    "second", 
    "third" 
}) 
@XmlRootElement(name = "SomeElement") 
public class SomeElement { 

    @XmlElement(name = "First", required = true) 
    protected String first; 
    @XmlElementRef(name = "Second", namespace = "http://www.example.org/ExtensionFlattener", type = JAXBElement.class) 
    protected JAXBElement<SomeElement.Second> second; 
    @XmlElement(name = "Third", required = true) 
    protected String third; 

    // Plus getters and setters 

    @XmlAccessorType(XmlAccessType.FIELD) 
    @XmlType(name = "", propOrder = { 
     "array" 
    }) 
    public static class Second { 

     @XmlElement(nillable = true) 
     protected List<TestArray> array; 

     // plus getter 
    } 
} 

(plus the other class) 

J'espère que cela s'applique à votre problème (jeu de mots)

Questions connexes