2010-01-27 13 views
2

J'ai essayé de désérialiser un fichier xml en C# avec des classes générées à partir des schémas de xsd.exe. Malheureusement, seule une partie du fichier est correctement désérialisée, le reste est retourné comme nul pour des raisons que je ne peux pas résoudre.xmlserializer ne déserialise pas correctement le schéma avec l'importation

Mon processus est le suivant: A partir du fichier myschema.xsd à partir de laquelle le code C# est généré:

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:mc="myschema:common" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ttl="http://www.myuri.org/myschema" targetNamespace="http://www.myuri.org/myschema" elementFormDefault="qualified" attributeFormDefault="unqualified"> 

et le fichier importé parentschema.xsd est ainsi:

<?xml version="1.0" encoding="UTF-8"?> 
<xs:schema xmlns:mc="myschema:common" xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="myschema:common" elementFormDefault="qualified" attributeFormDefault="unqualified"> 
<xs:element name="toplevel"> 
    <xs:complexType> 
    <xs:sequence> 
    <xs:element ref="mc:toplevel_header" minOccurs="0"/> 
    <xs:element ref="mc:body"/> 
    </xs:sequence> 
    </xs:complexType> 
</xs:element> 
<xs:element name="toplevel_header"> 
    <xs:complexType> 
    <xs:sequence> 
    <xs:element name="name" type="xs:anyURI"/> 
    </xs:sequence> 
    </xs:complexType> 
</xs:element> 
<xs:element name="body" type="mc:body" abstract="true"/> 
<xs:complexType name="body"> 
    <xs:attribute name="id" type="xs:ID" use="required"/> 
</xs:complexType> 
<xs:element name="Entity" type="mc:Entity" abstract="true"/> 
<xs:complexType name="Entity" abstract="true"> 
    <xs:attribute name="href" type="xs:anyURI" use="optional"/> 
</xs:complexType> 
</xs:schema> 

Je passe les deux fichiers de schéma ci-dessus pour XSD.exe:

>xsd.exe /c myschema.xsd parentschema.xsd 

qui génère un fichier myschema_parentschema.cs

Pour le tester, je suis en train de désérialiser un exemple de fichier xml:

<?xml version=\"1.0\" encoding="UTF-8"?> 
<toplevel version="2.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xlink="http://www.w3.org/1999/xlink" 
xmlns="myschema:common" 
xsi:schemaLocation="myschema:common http://www.myuri.org/parentschema.xsd"> 
<toplevel_header> 
    <name>MyName</name> 
    </toplevel_header> 
<body id="body_1" 
    xmlns="http://www.myuri.org/schema" 
    xmlns:mc="myschema:common" 
    xsi:schemaLocation="http://www.myuri.org/myschema http://www.myuri.org/myschema.xsd"> 
     <Foo href="http://www.google.com"> 
     </Foo> 
    </body> 
</toplevel> 

que je passe au code XmlSerializer suivant, où le lecteur est un XmlReader pour le fichier xml ci-dessus:

XmlSerializer xs = new XmlSerializer (typeof (toplevel)); 
object deserializedObject = xs.Deserialize(reader); 
toplevel fooBar = (toplevel)deserializedObject; 
Assert.AreEqual("MyName", fooBar.toplevel_header.name); //passes OK 
Assert.IsNotNull(fooBar.body); //<--------FAIL 

Pourquoi l'objet désérialisé ont une propriété corporelle nulle, et comment puis-je la désérialiser correctement l'élément Foo?

+0

croix posté à http://social.msdn.microsoft.com/Forums/en-US/asmxandxml/thread/256c43ab-5206-491f-b77e-42903b8c616a –

+0

Des problèmes similaires rencontrés dans cet article: [http: // richnewman.wordpress.com/2008/01/28/problems-with-using-xsdexe-to-generate-net-classes-from-the-fpml-xsd-schema-introduction-to-using-fpml-with-net- tools-part-4 /] –

+0

myschema.xsd semble incomplet ... – code4life

Répondre

0

Il y a une faute de frappe dans votre parentschema.xsd. Vous fermez la balise <xs:element> prématurément pour la balise body:

<xs:element name="body" type="mc:body" abstract="true"/> 

Vous définissent également le corps aussi abstrait que je pense est une erreur (si je lis le XML correctement).

La définition complète (en fonction de votre XML) devrait ressembler à:

<xs:element name="body" type="mc:body" abstract="true"> 
    <xs:complexType> 
     <xs:attribute name="id" type="xs:ID" use="required"/> 
     <xs:sequence> 
      <xs:element type="Foo" type="xs:anyURI" /> 
     </xs:sequence> 
    </xs:complexType> 
</xs:element> 
0

J'ai suivi les mêmes étapes que vous, et il semble que votre schéma et le fichier XML que vous désérialisation ne sont pas correspondant à. Voici ce que je l'ai fait:

static void Main(string[] args) 
{ 
    var xs = new XmlSerializer(typeof(toplevel)); 

    // test saving to xml first... 
    var tl = new toplevel(); 
    tl.toplevel_header = new toplevel_header(); 
    tl.toplevel_header.name = "MyName"; 

    tl.body = new body(); 
    tl.body.id = "body id..."; 

    // output to console first... 
    var cw = Console.OpenStandardOutput(); 
    xs.Serialize(cw, tl); 
    Console.WriteLine(); 
    Console.WriteLine(); 

    // save to file... 
    var fw = File.CreateText("test.xml"); 
    xs.Serialize(fw, tl); 
    fw.Close(); 

    // read file... 
    var fr = File.Open("test.xml", FileMode.Open, FileAccess.Read); 
    var obj = xs.Deserialize(fr); 
    var fooBar = (toplevel)obj; 

    Console.WriteLine(fooBar.toplevel_header.name); 
    Console.WriteLine(fooBar.body.id); 
    Console.ReadLine(); 
} 

Le XML que le sérialiseur généré était le suivant:

<?xml version="1.0" encoding="utf-8"?> 
<toplevel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
    xmlns="myschema:common"> 
    <toplevel_header> 
    <name>MyName</name> 
    </toplevel_header> 
    <body id="body id..." /> 
</toplevel> 

Le XML ne clairement correspond pas au fichier XML d'entrée que vous utilisez ... Espérons que cela vous aide dans votre façon!

0

Recherche Je remarquai votre échantillon xml une incohérence qui est la raison pour laquelle le XmlSerializer ne vient pas avec ce que vous attendez:

<toplevel version="2.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xlink="http://www.w3.org/1999/xlink" 
***xmlns="myschema:common"*** 
xsi:schemaLocation="myschema:common http://www.myuri.org/parentschema.xsd"> 
    <toplevel_header> 
     <name>MyName</name> 
    </toplevel_header> 
    <body id="body_1" 
      ***xmlns="http://www.myuri.org/schema"*** 
      ***xmlns:mc="myschema:common"*** 
      xsi:schemaLocation="http://www.myuri.org/myschema http://www.myuri.org/myschema.xsd"> 
     <Foo href="http://www.google.com"> 
     </Foo> 
    </body> 
</toplevel> 

Dans votre élément de premier niveau vous définissez xmlns = « mon_schema: commune » , et pourtant dans votre élément de corps vous définissez xmlns = "http://www.myuri.org/schema" et la ligne suivante est xmlns: mc = "myschema: common". Cela signifie que l'élément Foo à l'intérieur du corps est sous un espace de noms différent et que XmlSerializer ne trouvera pas l'élément. Lorsque je supprimé la déclaration xmlns dans l'élément de corps et a changé le xmlns: déclaration de mc à xmlns, comme suit:

<?xml version="1.0" encoding="UTF-8"?> 
<toplevel version="2.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:xlink="http://www.w3.org/1999/xlink" 
xmlns="myschema:common" 
xsi:schemaLocation="myschema:common http://www.myuri.org/parentschema.xsd"> 
    <toplevel_header> 
     <name>MyName</name> 
    </toplevel_header> 
    <body id="body_1" 
      xmlns="myschema:common" 
      xsi:schemaLocation="http://www.myuri.org/myschema http://www.myuri.org/myschema.xsd"> 
     <Foo href="http://www.google.com"> 
     </Foo> 
    </body> 
</toplevel> 

Après avoir ajusté le xml de l'échantillon, comme indiqué XmlSerializer a créé l'objet de premier niveau avec un corps non nulle à l'intérieur de cela.