1


XMLシリアライザーで奇妙な動作をします。
XMLを読み取り、それをオブジェクトに逆シリアル化した後、すべてのプロパティは、xmlファイルで宣言された値ではなく、デフォルト値に設定されます。
シリアライザーは例外をスローせず、正しく実行されます。xmlファイルは適切に形成され、クラス構造に適合します。
それがどのようになり得るのか、またはどうすれば問題の原因にたどり着くことができるのか、誰か考えていますか?
ありがとうございました

編集:私はあなたに全体の話をしませんでした。問題は、私が取得するXMLは別のコンポーネントからのものです。XMLファイルを逆シリアル化できたので、別の形式になりました。ファイルには約3000行あるため、コード全体を投稿することはできません。しかし、違いは次のとおりです。
逆シリアル化可能:

<?xml version="1.0" encoding="utf-8"?>
<rootElem xmlns:cfg="namespace1" xmlns:office="namespace2" xmlns="namespace3">
<Prop1 xmlns="">6</Prop1>
<Prop2 xmlns="">string</Prop2>
</rootElem>

逆シリアル化できません

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<rootElem xmlns:cfg="namespace1" xmlns:office="namespace2" xmlns="namespace3">
<Prop1>6</Prop1>
<Prop2>string</Prop2>
</rootElem>

要素内のxmlnsタグが原因で最初の例をアンマーシャリングできる理由と、2番目の例をアンマーシャリングできない理由がよくわかりません...

edit2:トップレベルの要素だけがこれらの奇妙なxmlns=""属性を持っていることに気づきました。しかし、C#クラス宣言は他のすべてのクラスと同じです...それは奇妙です。

C#クラスは次のようなものです。

using namespace1;

namespace namespace3
{
  [System.SerializableAttribute()]
  [System.ComponentModel.DesignerCategoryAttribute("code")]
  [System.Xml.Serialization.XmlTypeAttribute(Namespace="namespace3")]
  [System.Xml.Serialization.XmlRootAttribute(Namespace="namespace3", IsNullable=true)]
  public partial class rootElem: BaseObject
  {
    [System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public int Prop1
    {
      //...
    }
  }
}
4

2 に答える 2

1

具体的な例(両方のc#ad xml)は、ここでは非常に長い道のりを進みます。最も可能性の高いもの:

  • 名前は、xmlとc#の間で完全に(大文字と小文字が区別される)一致しません(属性などを介した名前のオーバーライドを可能にします)
  • xml属性/要素の間に取り違えがあります
  • xml名前空間に違いがあります(通常、xmlに存在し、c#にはありません)

編集すると、より明確になります。Xml名前空間は非常に重要です。<foo xmlns="abc"/><foo/>は完全に無関係です。さらに、xml名前空間は継承されるため、次のようになります。

<rootElem xmlns:cfg="namespace1" xmlns:office="namespace2" xmlns="namespace3">
<Prop1>6</Prop1>
<Prop2>string</Prop2>
</rootElem>

とが親から継承する名前空間Prop1Prop2ある場合です。namespace3それらを(空の名前空間ではなく)子名前空間に配置することをC#に完全に明確にするには、次のように伝えます

[Serializable]
[DesignerCategory("code")]
[XmlType(Namespace = Namespace3)]
[XmlRoot(Namespace = Namespace3, IsNullable = true)]
public partial class rootElem
{
    private const string Namespace3 = "namespace3"; // to avoid repetition

    [XmlElement(Namespace = Namespace3)]
    public int Prop1 { get; set; }
}
于 2012-07-26T07:08:32.527 に答える
0

さらに調査した結果、問題を見つけることができました。シリアライザーがなぜそのように動作するのか、私はまだ理解していません。これまでのところ、名前空間のデクレレーションは、デフォルトの名前空間(W3Schools)を設定するためにプレフィックスなしで「xmlns」属性を定義する必要があることを理解していました。私の質問で述べたように、それは(他の名前空間に加えて)定義されました:

<rootElem xmlns:cfg="namespace1" xmlns:office="namespace2" xmlns="namespace3">

ルート要素のすべての直接の子が(再び)xmlns属性を宣言しているので、私の解釈では、デフォルトの名前空間が見つかりませんでした。
したがって、私が行ったことは、ルート要素の名前空間を明示的に定義して、ルート要素が次のように生成されるようにすることでした。

<root:rootElem xmlns:cfg="namespace1" xmlns:office="namespace2" xmlns:root="namespace3">

そして出来上がり、xmlは適切に生成され(xmlns属性は直接の子から削除されました)、シリアライザーはデータを読み取ることができました。
しかし、まだいくつかの質問が残っています:

  • シリアライザーがデフォルトの名前空間でxmlを正しく生成しないのはなぜですか?
  • シリアライザーがデータを読み取ってインスタンスに入れることができない場合は、例外が発生することが予想されます(「空の」インスタンスを作成する理由)
于 2012-07-27T06:50:38.233 に答える