xmlを逆シリアル化する方法に関するいくつかの投稿と記事をすでに読んでいますが、ニーズに合わせてコードを記述する方法がまだわかりません。したがって、xmlの逆シリアル化に関する別の質問をお詫びします))
デシリアライズする必要のある大きな(50 MB)xmlファイルがあります。xsd.exeを使用してドキュメントのxsdスキーマを取得し、プロジェクトに配置したc#クラスファイルを自動生成します。このxmlファイルからいくつかの(すべてではない)データを取得して、それをsqlデータベースに入れたいと思います。
ファイルの階層は次のとおりです(簡略化すると、xsdは非常に大きくなります)。
public class yml_catalog
{
public yml_catalogShop[] shop { /*realization*/ }
}
public class yml_catalogShop
{
public yml_catalogShopOffersOffer[][] offers { /*realization*/ }
}
public class yml_catalogShopOffersOffer
{
// here goes all the data (properties) I want to obtain ))
}
そしてここに私のコードがあります:
最初のアプローチ:
yml_catalogShopOffersOffer catalog;
var serializer = new XmlSerializer(typeof(yml_catalogShopOffersOffer));
var reader = new StreamReader(@"C:\div_kid.xml");
catalog = (yml_catalogShopOffersOffer) serializer.Deserialize(reader);//exception occures
reader.Close();
InvalidOperationExceptionが発生します:XML(3,2)ドキュメントにエラーがあります
2番目のアプローチ:
XmlSerializer ser = new XmlSerializer(typeof(yml_catalogShopOffersOffer));
yml_catalogShopOffersOffer result;
using (XmlReader reader = XmlReader.Create(@"C:\div_kid.xml"))
{
result = (yml_catalogShopOffersOffer)ser.Deserialize(reader); // exception occures
}
InvalidOperationException:XML(0,0)ドキュメントにエラーがあります
3番目:ファイル全体を逆シリアル化しようとしました:
XmlSerializer ser = new XmlSerializer(typeof(yml_catalog)); // exception occures
yml_catalog result;
using (XmlReader reader = XmlReader.Create(@"C:\div_kid.xml"))
{
result = (yml_catalog)ser.Deserialize(reader);
}
そして、私は次のようになります:
error CS0030: The convertion of type "yml_catalogShopOffersOffer[]" into "yml_catalogShopOffersOffer" is not possible.
error CS0029: The implicit convertion of type "yml_catalogShopOffersOffer" into "yml_catalogShopOffersOffer[]" is not possible.
では、例外を取得しないようにコードを修正(または上書き)する方法は?
編集:私が書くときも:
XDocument doc = XDocument.Parse(@"C:\div_kid.xml");
XmlExceptionが発生します:ルートレベル、文字列1、位置1の許可されていないデータ。
xmlファイルの最初の文字列は次のとおりです。
<?xml version="1.0" encoding="windows-1251"?>
編集2: xmlファイルの短い例:
<?xml version="1.0" encoding="windows-1251"?>
<!DOCTYPE yml_catalog SYSTEM "shops.dtd">
<yml_catalog date="2012-11-01 23:29">
<shop>
<name>OZON.ru</name>
<company>?????? "???????????????? ??????????????"</company>
<url>http://www.ozon.ru/</url>
<currencies>
<currency id="RUR" rate="1" />
</currencies>
<categories>
<category id=""1126233>base category</category>
<category id="1127479" parentId="1126233">bla bla bla</category>
// here goes all the categories
</categories>
<offers>
<offer>
<price></price>
<picture></picture>
</offer>
// other offers
</offers>
</shop>
</yml_catalog>
PS
私はすでに答えを受け入れました(それは完璧です)。ただし、categoryIdを使用して、各オファーの「基本カテゴリ」を見つける必要があります。データは階層的であり、基本カテゴリは「parentId」属性を持たないカテゴリです。そこで、「基本カテゴリ」を見つけるための再帰的なメソッドを作成しましたが、それが終了することはありません。algorythmはそれほど速くないようです))これ
が私のコードです:( main()メソッド内)
var doc = XDocument.Load(@"C:\div_kid.xml");
var offers = doc.Descendants("shop").Elements("offers").Elements("offer");
foreach (var offer in offers.Take(2))
{
var category = GetCategory(categoryId, doc);
// here goes other code
}
ヘルパーメソッド:
public static string GetCategory(int categoryId, XDocument document)
{
var tempId = categoryId;
var categories = document.Descendants("shop").Elements("categories").Elements("category");
foreach (var category in categories)
{
if (category.Attribute("id").ToString() == categoryId.ToString())
{
if (category.Attributes().Count() == 1)
{
return category.ToString();
}
tempId = Convert.ToInt32(category.Attribute("parentId"));
}
}
return GetCategory(tempId, document);
}
このような状況で再帰を使用できますか?そうでない場合、他にどのようにして「基本カテゴリ」を見つけることができますか?