2

xsd.exe のスキーマから生成されたクラスを使用して、C# で xml ファイルを逆シリアル化しようとしています。残念ながら、ファイルの一部のみが適切に逆シリアル化されています。残りは、解決できない理由で null として返されます。

私のプロセスは次のとおりです。C# コードが生成される myschema.xsd ファイルから始めます。

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

インポートされたparentschema.xsdファイルは次のとおりです。

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

上記の 2 つのスキーマ ファイルを xsd.exe に渡します。

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

myschema_parentschema.cs ファイルを生成します

それをテストするために、サンプルの 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>

これを次の XmlSerializer コードに渡します。ここで、リーダーは上記の xml ファイルの XmlReader です。

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

逆シリアル化されたオブジェクトに null body プロパティがあるのはなぜですか? また、Foo 要素を適切に逆シリアル化するにはどうすればよいですか?

4

3 に答える 3

0

サンプルxmlを見ると、矛盾に気づきました。これが、XmlSerializerが期待どおりの結果を出さない理由です。

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

トップレベル要素でxmlns="myschema:common"を定義していますが、body要素でxmlns = "http://www.myuri.org/schema"を定義しており、次の行はxmlns:mc="myschemaです。 :一般"。これは、本体内のFoo要素が別の名前空間の下にあり、XmlSerializerが要素を検出しないことを意味します。body要素のxmlns宣言を削除し、xmlns:mc宣言を次のようにxmlnsに変更した場合:

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

示されているようにサンプルxmlを調整すると、XmlSerializerは、内部にnull以外のボディを持つトップレベルオブジェクトを作成しました。

于 2010-10-15T02:31:02.530 に答える
0

私はあなたと同じ手順を実行しましたが、スキーマと逆シリアル化するXMLファイルが一致していないようです。これが私がしたことです:

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

シリアライザーが生成したXMLは次のとおりです。

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

XMLは、使用している入力XMLファイルと明らかに一致していません...うまくいけば、これがあなたの道に役立つことを願っています!

于 2010-10-14T19:32:06.847 に答える
0

parentschema.xsd にタイプミスがあります。<xs:element>body タグのタグを時期尚早に閉じています。

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

また、本文を抽象として定義していますが、これは間違いだと思います (XML を適切に読んでいる場合)。

定義全体 (XML に基づく) は次のようになります。

<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>
于 2010-10-14T18:05:20.600 に答える