2013-03-14 6 views
6

単純なXML文書から要素値を読み込み、これらをオブジェクトにバインドしようとしていますが、私のXML文書と一緒に。私はそれを検証してきたし、文書自体は、しかし、ライン上の結果を拡張するに問題がない確認することができます。XMLからオブジェクトへのシリアル化解除の問題 - XML文書(0、0)にエラーがあります

var nodes = from xDoc in xml.Descendants("RewriteRule") 
       select xmlSerializer.Deserialize(xml.CreateReader()) as Url; 

ショー「XMLドキュメントに誤りがあり(0、0)」

内部例外の読み取り<RewriteRules xmlns=''> was not expected.

ここで間違っているのはわかりませんか?

私のXMLは以下の通りです:

<?xml version="1.0" encoding="utf-8" ?> 
<RewriteRules> 
    <RewriteRule> 
     <From>fromurl</From> 
     <To>tourl</To> 
     <Type>301</Type> 
    </RewriteRule> 
</RewriteRules> 

XMLファイルをロードし、それをデシリアライズしようとしたコード: -

public static UrlCollection GetRewriteXML(string fileName) 
{ 
    XDocument xml = XDocument.Load(HttpContext.Current.Server.MapPath(fileName)); 
    var xmlSerializer = new XmlSerializer(typeof(Url)); 

    var nodes = from xDoc in xml.Descendants("RewriteRule") 
       select xmlSerializer.Deserialize(xml.CreateReader()) as Url; 

    return nodes as UrlCollection; 
} 

私のURLオブジェクトのクラス: -

[Serializable] 
[XmlRoot("RewriteRule")] 
public class Url 
{ 
    [XmlElement("From")] 
    public string From { get; set; } 
    [XmlElement("To")] 
    public string To { get; set; } 
    [XmlElement("Type")] 
    public string StatusCode { get; set; } 

    public Url() 
    { 
    } 

    public Url(Url url) 
    { 
     url.From = this.From; 
     url.To = this.To; 
     url.StatusCode = this.StatusCode; 
    } 
} 

誰でも私がここで間違っているのを見ることができますか?

おかげ

+0

掘ることの原因となったベースの例外に。 – leppie

答えて

4

私はfrom select文を使用して、あまりにも慣れていないんだけど、それはあなただけでxmlに渡すようです全体がXDocumentXElementではなく、RewriteRuleです。そのため、RewriteRulesが不明であることを示すエラーメッセージが表示されます。XmlSerializerには、単一のRewriteRuleが必要です。

代わりにLINQを使用してコードを書き直すことができました(しかし、from selectステートメントから単一の要素を取得する方法が分かっていれば、同様にうまくいくはずです)。

これはあなたに正しい結果を与える必要があります - rrDescendantsから返されXElement次のとおりです。

public static IEnumerable<Url> GetRewriteXML() 
{ 
    XDocument xml = XDocument.Load(HttpContext.Current.Server.MapPath(fileName)); 

    var xmlSerializer = new XmlSerializer(typeof(Url)); 

    var nodes = xml.Descendants("RewriteRule") 
       .Select(rr => xmlSerializer.Deserialize(rr.CreateReader()) as Url); 

    return nodes; 
} 
+0

おそらく 'xDoc'ですか?だから 'select xmlSerializer.Deserialize(xDoc.CreateReader())'? – Default

+0

はい要素は 'xDoc'であり、要素自体にCreateReaderを試してみると思わなかったので、これを素早くテストします。 – DGibbs

+0

これは私が欠けていたものです。 'xml.CreateReader()'を 'xDoc.CreateReader()'に変更しました。ありがとう! – DGibbs

3

EDIT: 一致していない、あなたのURLクラスの名前。あなたはクラスのインスタンスに直接それをデシリアライズするとき、

[Serializable] 
[System.Xml.Serialization.XmlRoot("RewriteRule")] 
public class Url 
{ 
    [XmlElement("From")] 
    public string From { get; set; } 
    [XmlElement("To")] 
    public string To { get; set; } 
    [XmlElement("Type")] 
    public string StatusCode { get; set; } 

    public Url() 
    { 
    } 
    public Url(Url url) 
    { 
     url.From = this.From; 
     url.To = this.To; 
     url.StatusCode = this.StatusCode; 
    } 
} 
+0

こんにちは@Patrick、あなたの 'RewriteRules'クラスを追加し、私のメソッドを変更しようとしましたが、私はまだ同じエラーが表示されます。不思議なことに、 'Url'クラスの' XmlRoot'属性を 'RewriteRule'ではなく' RewriteRules'に変更すると、デシリアライザはエラーをスローしませんが、オブジェクトにバインドされた値はすべてnullです。奇妙なことが起こっている – DGibbs

+0

これは変です。私はテストをセットアップし、それが働いています(私は上記のコードをdeserialze呼び出しで使用しました)。あなたのエディタは正しいXMLファイルを提供していますか?私はメモ帳++を使用します。 xmlファイルが問題ではありません。 – Patrick

+0

私はVS経由でxml文書を作成し、w3c [validator](http://validator.w3.org)を使って確認しました – DGibbs

1

私のアプローチは、より使用されている:あなたは「のRewriteRule」に名前を変更したり、それをこのように定義する必要があります。

XDocumentを使いたい場合は、次のように記述します。私は自分のコードでXDocumentを使用しません。完全なxmlパッケージを非直列化する必要があるので、私はそれを直接ルートノードの逆直列化で行います。したがって、前の投稿の正しい場所にルートノードを提案しました。

XDocumentを使用すると、サブパートに直接アクセスできます。ここではあなたの目的のためのコードを働いているが、あなたはよりエレガントまで、このコードを設定することができます他の人があるかもしれません。

public static UrlCollection GetRewriteXML(string fileName) 
    { 
     XDocument xml = XDocument.Load(HttpContext.Current.Server.MapPath(fileName)); 
     var urls = from s in xml.Descendants("RewriteRule") 
        select new 
        { 
         From = (string)s.Element("From").Value, 
         To = (string)s.Element("To").Value, 
         StatusCode = (string)s.Element("Type").Value 
        }; 
     UrlCollection nodes = new UrlCollection(); 
     foreach (var url in urls) 
     { 
      nodes.Add(new Url(url.From, url.To, url.StatusCode)); 
     } 
     return nodes; 
    } 

[Serializable] 
public class Url 
{ 
    [XmlElement("From")] 
    public string From { get; set; } 
    [XmlElement("To")] 
    public string To { get; set; } 
    [XmlElement("Type")] 
    public string StatusCode { get; set; } 

    public Url() 
    { 
    } 

    public Url(string From, string To, string StatusCode) 
    { 
     this.From = From; 
     this.To = To; 
     this.StatusCode = StatusCode; 
    } 

    public Url(Url url) 
    { 
     url.From = this.From; 
     url.To = this.To; 
     url.StatusCode = this.StatusCode; 
    } 
} 
+0

これは、匿名型のバージョンを使用していたのに対し、プロパティのために。説明できますか? URLを反復する代わりに、私は 'UrlCollection'クラスの中で新しいコレクションを作成しました。これは動的なコレクションを取得し、そこから新しいURLを作成しました。 'public UrlCollection(IEnumerable urls){this.Items.Clear(); foreach(URL内の動的項目){URL url =新しいURL(item.From、item.To、item.StatusCode); this.Add(url); }} '。あなたはいつも既存の回答を編集することができます;) – DGibbs

+0

こんにちは、シリアライザはあなたのクラスのURLの名前を嫌うようです。 "RewriteRule"に名前を変更するか、次の行を追加する必要があります:[Serializable] [System.Xml.Serialization.XmlRoot( "RewriteRule")] public class Url – Patrick

関連する問題