2017-02-20 9 views
0

私は外部XMLファイルから予約をインポートし、Umbracoサイトにノードとして保存するサイトを持っています。<xmlns='' >は期待できませんでした。しかし、XMLrootが変更されたときに定義することはできません。 C#

問題:

基本的に、私はそれがXMLと元のルートノードをエクスポートする方法を変更しましたから予約をエクスポートするシステム。

これは、このルートノードに関連する問題であると仮定しています。スタック上の多くの回答が、この件名のエラーに関してこれについて言及していますが、ダイナミックルートノードの処理方法については触れていません。私は、XMLファイルで持っていた何

:今

<Bookings> 
    <row id="1"> 
     <FirstBookingAttribute>.... 
    </row> 
</Bookings> 

は動的であり、のように見える終わることができます。

このため
<BookingsFebruary2017 company="CompanyNameHere"> 
    <row id="1"> 
     <firstBookingAttribute>.... 
    </row> 
</BookingsFebruary2017> 

私が設定する方法が全くわかりませんC#のXMLルートノード。

包みなさい、この問題は、ルートノードに関連していない、私は以下のerroringコードを貼り付けています

コントローラを予約

public class Bookings 
{ 
    [XmlElement("row")] 
    public List<Booking> StudentBookings { get; set; } 
} 

var reader = new StreamReader(tempFile); 
var deserializer = new XmlSerializer(typeof(Bookings)); 
var xml = deserializer.Deserialize(reader); 
var studentBookings = (Bookings) xml; 

モデルファイルありがとうございます

+2

あなたはこれを変更した人に押し戻し、彼らが有意義に行動する*誰* sの能力を破壊していることを指摘することはできませんこのデータはXMLをどのように使用するかではないため、自動化されています。 –

+0

私の場合、それは 'XmlSerializer'の間違った宣言のためです。だからそれもチェックしてください。 – Mangesh

答えて

1

XmlSerializerは、そのままの状態で動的ルート名を使用することはできません。予期されるルート名は固定されており、タイプ名、[XmlRoot]または[XmlType]属性の存在、場合によってはXmlSerializer constructor usedの存在によって定義されます。

したがって簡単な解決策は、XDocumentに予めロードXMLである、ルート名を変更し、デシリアライズ:

XDocument doc; 
using (var xmlReader = XmlReader.Create(tempFile)) 
{ 
    doc = XDocument.Load(xmlReader); 
} 

var rootName = doc.Root.Name; 
doc.Root.Name = "Bookings"; 
var deserializer = new XmlSerializer(typeof(Bookings)); 
Bookings bookings; 
using (var xmlReader = doc.CreateReader()) 
{ 
    bookings = (Bookings)deserializer.Deserialize(xmlReader); 
} 
bookings.RootName = rootName.LocalName; 

は、ロードされたXMLから直接デシリアライズするCreateReader()の使用に注意してください。その作成された各シリアライザは、重度のメモリを防ぐために、ハッシュテーブルにキャッシュされている必要があり

  • 別のオプションは、new XmlSerializer(typeof(Bookings), new XmlRootAttribute { ElementName = rootName })を使用して、各ファイルのカスタムXmlSerializerを作成することですが、これには2つの問題がありますthis answerと同様にthe documentationで説明されているように、リーク(動的に作成されたアセンブリの重複をロード)

  • あなたがこれを行う場合でも、あなたは多くの異なるルート名を持つ多くの異なるファイルを読んでいるなら、あなたのメモリ使用は、新しいユニーク動的に作成XmlSerializerアセンブリの一定の負荷を迅速かつ継続的に成長します。両方のソリューションは、あまりにも多くのメモリを必要とする場合は、サブクラス化XmlTextReaderを作成することを検討でき

    Bookings bookings = null; 
    using (var xmlReader = XmlReader.Create(tempFile)) 
    { 
        while (xmlReader.Read()) 
        { 
         if (xmlReader.NodeType == XmlNodeType.Element) 
         { 
          var rootName = xmlReader.LocalName; 
          var deserializer = new XmlSerializer(typeof(Bookings), new XmlRootAttribute { ElementName = rootName }); 
          bookings = (Bookings)deserializer.Deserialize(xmlReader); 
          bookings.RootName = rootName; 
          break; 
         } 
        } 
    } 
    

    :あなただけ1つのファイルをロードしなければならない場合

しかし、あなたはこのような何かを行うことができます読み込み中にそのルート要素の名前を変更することができます。

は両方のケースでは、私は次のように見てBookingsを修正:

public class Bookings 
{ 
    [XmlIgnore] 
    public string RootName { get; set; } 

    [XmlAttribute("company")] 
    public string Company { get; set; } 

    [XmlElement("row")] 
    public List<Booking> StudentBookings { get; set; } 
} 
+0

私は「ネームスペースを気にしないでください」というオプションがどこにないのか理解できませんでした。時間の名前空間の99%はちょうどノイズです。 –

+0

@ChristianSauer - はい、名前空間と同じです。 C#。ちょうどノイズ。競合の可能性を減らしたい場合や、同じ単一ファイル内の複数の独立したベンダードメインの特定言語を相互運用する必要がある場合もあります。 –

+0

@Damien_The_Unbeliever私は、ほとんどの場合、単一の名前空間を持つ単一のXML文書に対して取り組んでいます。これは、名前空間を使用することは、無益な単純な追加作業にすぎないケースです。 –

関連する問題