5

XMLとC#の練習を開始しましたが、「XMLドキュメント(3,2)にエラーがあります」というエラーメッセージが表示されます。ファイルを見た後、私はそれについて何も悪いことを見ることができません(気をつけてください、私は初心者なので、おそらく何かを逃しました)。現在、C#用のコンソールアプリケーションを使用しています。冒険者のリストを返そうとしていますが、補足として、GEAR要素はオプションです。これが私がこれまでに持っているものです:

XMLファイル-Test1

<?xml version="1.0" encoding="utf-8"?>
<Catalog>
    <Adventurer>
        <ID>001</ID>
        <Name>John Smith</Name>
        <Address>123 Fake Street</Address>
        <Phone>123-456-7890</Phone>
        <Gear>
            <Attack>
                <Item>
                    <IName>Sword</IName>
                    <IPrice>15.00</IPrice>
                </Item> 
                <Item>
                    <IName>Wand</IName>
                    <IPrice>20.00</IPrice>
                </Item>         
            </Attack>
            <Defense>
                <Item>
                    <IName>Shield</IName>
                    <IPrice>5.00</IPrice>
                </Item>
        </Defense>  
        </Gear>
    </Adventurer>
    <Adventurer>
        <ID>002</ID>
        <Name>Guy noone likes</Name>
        <Address>Some Big House</Address>
        <Phone>666-666-6666</Phone>
        <Gear></Gear>
    </Adventurer>
</Catalog>

C#クラス

public class Catalog
{
    List<Adventurer> Adventurers { get; set; }
}

public class Adventurer
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
    public string Phone { get; set; }
    public Gear Gear { get; set; }
}

public class Gear
{
    public List<Item> Attack { get; set; }
    public List<Item> Defense { get; set; }
}

public class Item
{
    public string IName { get; set; }
    public decimal IPrice { get; set; }
}

シリアル化機能-5行目で問題が発生する場所

Catalog obj = null;
string path = @"C:\Users\Blah\Desktop\test1.xml";
XmlSerializer serializer = new XmlSerializer(typeof(Catalog));
StreamReader reader = new StreamReader(path);
obj = (Catalog)serializer.Deserialize(reader);
reader.Close();

Console.ReadLine();
4

4 に答える 4

3

問題は、カタログ内の冒険者のリストです。

<?xml version="1.0" encoding="utf-8"?>
<Catalog>
    <Adventurers> <!-- you're missing this -->
        <Adventurer>
        </Adventurer>
        ...
        <Adventurer>
        </Adventurer>
    </Adventurers> <!-- and missing this -->
</Catalog>

Adventurersコレクションのラッピング要素がありません。

編集:ちなみに、XML構造を構築し、互換性があることを確認する最も簡単な方法は、C#でオブジェクトを作成し、組み込みを実行して、XmlSerializerそのXML出力をXMLの基礎として使用することです。手作業ではなく作成します。

于 2012-06-28T17:08:37.090 に答える
2

まず、「Adventurers」プロパティは公開されておらず、アクセスできません。エラーを見つける最善の方法は、オブジェクトをシリアル化してから、結果をxmlファイルと比較することだと思います。

于 2012-06-28T17:17:29.203 に答える
1

XMLがオブジェクトと完全に一致していません...つまり、これら2つ...

public string City { get; set; }

<Address>123 Fake Street</Address>

都市を住所に、またはその逆に変更すると、問題が解決するはずです。

編集:これをテストプロジェクトで機能させるために、すべての回答を組み合わせて...

後(および前)に<Adventurers>タグを追加し、変更します<Catalog></Adventurers></Catalog>

List<Adventurer> Adventurers { get; set; }

public List<Adventurer> Adventurers { get; set; }

そしてそれは私にとって適切に機能します。

于 2012-06-28T17:04:02.600 に答える
1

いくつかの小さな変更(つまり、Adventurerのパブリック修飾子)を使用して、xmlを逆シリアル化することができました。

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Xml.Serialization;

namespace TempSandbox
{
    [XmlRoot]
    public class Catalog
    {
        [XmlElement("Adventurer")]
        public List<Adventurer> Adventurers;

        private readonly static Type[] myTypes = new Type[] { typeof(Adventurer), typeof(Gear), typeof(Item) };
        private readonly static XmlSerializer mySerializer = new XmlSerializer(typeof(Catalog), myTypes);

        public static Catalog Deserialize(string xml)
        {
            return (Catalog)Utils.Deserialize(mySerializer, xml, Encoding.UTF8);
        }
    }

    [XmlRoot]
    public class Adventurer
    {
        public int ID;

        public string Name;

        public string Address;

        public string Phone;

        [XmlElement(IsNullable = true)]
        public Gear Gear;
    }

    [XmlRoot]
    public class Gear
    {
        public List<Item> Attack;

        public List<Item> Defense;
    }

    [XmlRoot]
    public class Item
    {
        public string IName;

        public decimal IPrice;
    }
}

xml要素名がクラスプロパティ名と完全に一致しないため、[XmlElement( "Adventurer")]を使用しています。

注:私はすでに手元にある一般的な逆シリアル化ユーティリティを使用しています。

于 2012-06-28T17:56:08.803 に答える