2013-03-06 13 views
14

XMLは外部ソースから提供されているため、簡単に再フォーマットすることはできません。 XMLとエンティティのフォーマット方法を知っているlinqクエリを記述するのではなく、エンティティでXML属性を使用したいと思います。次に例を示します。XML配列を逆シリアル化します。ルートは配列であり、要素は規則に従いません。

<?xml version="1.0"?> 
<TERMS> 
    <TERM> 
     <ID>2013-2</ID> 
     <DESC>Spring 2013</DESC> 
    </TERM> 
    <TERM> 
     <ID>2013-3</ID> 
     <DESC>Summer 2013 Jun&amp;Jul</DESC> 
    </TERM> 
</TERMS> 

私はXmlSerializerをではなく、例えば用語のArrayOfTermを期待するが、私はこのようなXMLの属性を持つ別の要素名を使用するように私のエンティティを微調整することができます知っている:

public class TermData 
{ 
    [XmlArray("TERMS")] 
    [XmlArrayItem("TERM")] 
    public List<Term> terms; 
} 

public class Term 
{ 
    [XmlElement("ID")] 
    public string id; 

    [XmlElement("DESC")] 
    public string desc; 
} 

と、私はそうのようなデータをデシリアライズしています:

TermData data; 

XmlSerializer serializer = new XmlSerializer(typeof(TermData)); 
using (StringReader reader = new StringReader(xml)) 
{ 
    data = (TermData)serializer.Deserialize(reader); 
} 

return View(data.terms); 

私が直面しています問題は、条項がルートと配列そのものであるということです。 XMLが配列ではないルート要素を持つ場合、私はTermDataクラスを編集することができ、正しくデシリアライズする(すでにテスト済み)。

[XmlRoot("ROOT")] 
public class TermData 
{ 
    [XmlArray("TERMS")] 
    [XmlArrayItem("TERM")] 
    public List<Term> terms; 
} 

XMLRootとしてTERMSを使用すると機能しません。今、私のコードは、XMLが正しくフォーマットされていないことを信じて私につながる

InvalidOperationException: There is an error in XML document (2,2). 
InnerException: "<TERMS xmlns=" was not expected. 

この

を投げているが、私の理解から、私が与えた例では、完全に有効なXMLです。

ソースxmlを編集できるのであれば、これはすべて簡単ですが、このような数多くの応答がある可能性があり、私が得られるようにフレキシブルにする必要があります。私が確認しようとしているのは、XMLSerializerがこのタイプのXML構造をサポートできるかどうかです。私はすべてをテストしましたが、XMLを編集せずにデシリアライズすることはできません。リストを保持するためにラッパークラス(TermData)を定義する必要がなくても便利ですが、xmlがシリアライザ(ArrayOfTermなど)の命名規則に準拠する場合にのみ動作するようです。

+1

ファイルがどのくらいあるの?私は同様の問題(log4net XMLファイルを読み込もうとしました)に遭遇しました。私がしたことは、XMLにロードし、任意の適切なルートタグを挿入し、そこから移動しました。 –

+0

ルート要素を挿入することが解決策になります。私はそれについて実際に考えなかったので、提案に感謝します。このような問題は、そのような回避策がなくても解決されるはずです。 – pixelshaded

答えて

17

たぶん、あなたは試すことができます。これは役立つ

[XmlRoot("TERMS")] 
public class TermData 
{ 
    public TermData() 
    { 
     terms = new List<Term>(); 
    } 

    [XmlElement("TERM")] 
    public List<Term> terms{get;set;} 
} 

public class Term 
{ 
    [XmlElement("ID")] 
    public string id{get;set;} 

    [XmlElement("DESC")] 
    public string desc{get;set;} 
} 

ホープ

+0

これを試して、逆シリアル化しません。 TermData.termsの値は0です。 – pixelshaded

+0

@pixelshaded:リストを初期化するクラスのパブリックコンストラクタが追加されました。これは、 – jbl

+0

がまだ空のリストを取得するのに役立ちます。 – pixelshaded

関連する問題