1

オブジェクトを「再構築」(読み取り) するのに苦労しています。私の構造は非常に単純です:

groupName<--object  
name<--prop  
addres<--prop  
phone<--prop  

どうすれば同じ構造に再構築できますか?

これが私がxmlに書き込んでいる方法です

 public override void Save(PhoneBook pb)
{
    using (XmlWriter writer = XmlWriter.Create(path))
    {
        writer.WriteStartDocument();
        writer.WriteStartElement("Group");

        foreach (PhoneBookGroup group in pb.Items)
        {
            writer.WriteStartElement("GroupName");

            writer.WriteElementString("GroupName", group.GroupName.ToString());
            foreach (Contect contect in group.Items)
            {
                writer.WriteStartElement("Addres", contect.Addres.ToString());
                writer.WriteStartElement("Number", contect.Number.ToString());
                writer.WriteStartElement("Name", contect.Name.ToString());
            }

            writer.WriteEndElement();
        }

        writer.WriteEndElement();
        writer.WriteEndDocument();
    }
}
4

2 に答える 2

1

XmlSerializerコーディングは簡単なので、最初のバージョンには確かにを使用してください。上司がシリアル化バージョンがどれほど単純でエラーが発生しにくいかを確認した後、別の方法でそれを望んでいる場合は、そうでない場合は上司を説得する必要があります-作業の一部は、あなたが言ったことを実行するだけでなく、少なくとも正直なアドバイスを提供します。これが学習経験であると想定されていない限り、上司は間違っています-それは問題なく正常ですが、彼が言うように行う前に、少なくとも時間とお金を節約するように努めるべきです。彼は代替案に気付いていないかもしれません。

手動によるアプローチの問題は、コードサンプルにバグがあるという事実によって浮き彫りになります。おそらく、writer.WriteElementString("Number",...ではなく意図したものですWriteStartElement("Number",...。より構造化されたアプローチを使用する方がはるかに安全で簡単です。

本当に生のxmlを読み取る必要がある場合は、クラスを使用してドキュメントを読み取り、linqtoxmlを使用して関連するビットを抽出することをお勧めします。XDocumentXmlReaderこれは、手書きコードの完全な柔軟性を維持しながら、より単純XmlReaderです(少し遅くなります)。あなたがXmlReader解決策を主張する場合(これには技術的な理由がないことに注意してください)、最初にあなた自身を書いてみるべきです-あなたが試したことを私たちが見ることができるようにあなたの試みをあなたの質問に含めてください。

于 2013-02-11T11:05:51.857 に答える
1

あなたのxml出力を見て、Save関数の出力が非常に奇妙に構造化されたxmlを作成するため、スキーマの変更を真剣に検討します。これが、再構築に苦労している理由だと思います。現在の出力は次のようになります。

<?xml version="1.0" encoding="utf-8"?>
<Group>
  <GroupName>
    <GroupName>groupName</GroupName>
     <Addres xmlns="addy">
       <Number xmlns="0123456789">
        <Name xmlns="Henry">
          <Addres xmlns="address2">
            <Number xmlns="9876543210">
              <Name xmlns="Dave" />
              <GroupName>
                <GroupName>secondGroup</GroupName>
                <Addres xmlns="fleet">
                  <Number xmlns="0123456789">
                    <Name xmlns="Me" />
                  </Number>
                </Addres>
              </GroupName>
            </Number>
          </Addres>
        </Name>
      </Number>
    </Addres>
  </GroupName>
</Group>

結果のxmlは処理不能ではなく、以下のメソッドを使用してオブジェクトに読み戻すことができると述べました。Save コードから推測した唯一のことは、文字列から GroupName オブジェクトを取得する何らかの方法があるということです (ToString メソッドを使用して値を xml に取得しているため)。私のテストでは、以下に示すように、暗黙的な変換演算子を使用してオブジェクトを実装しました。

class GroupName
{
    public string Name { get; set; }

    public override string ToString()
    {
        return this.Name;
    }

    // Specific conversion from string to GroupName object
    public static implicit operator GroupName(string s)
    {
        return new GroupName() { Name = s };
    }
}

public PhoneBook Rebuild()
{
    using (XmlReader reader = XmlReader.Create(path))
    {
        // read to the start of the xml
        reader.MoveToContent();

        // create the return object
        PhoneBook returnObject = new PhoneBook();
        returnObject.Items = new List<PhoneBookGroup>();

        while (reader.Read())
        {
            if (reader.NodeType == XmlNodeType.Element)
            {
                // read each GroupName Node as a separate node collection
                if (reader.Name == "GroupName")
                {
                    // This is the root node of the groups
                    PhoneBookGroup grp = null;
                    Contact currentContact = null;

                    // loop the reader from this starting node
                    while (reader.Read())
                    {
                        if (reader.NodeType == XmlNodeType.Element)
                        {
                            switch (reader.Name)
                            {
                                case "GroupName":
                                    if (grp == null)
                                    {
                                        grp = new PhoneBookGroup();
                                        returnObject.Items.Add(grp);
                                        // must implement an implicit operator between string and GroupName object
                                        grp.Name = (GroupName)reader.ReadElementString();
                                    }
                                    else
                                    {
                                        // start of a new group, so null what we have so far and start again
                                        grp = null;
                                    }
                                    break;
                                case "Addres":
                                    // Address is the start node for a contact so create a new contact and start filling it
                                    currentContact = new Contact();
                                    if (grp.Items == null)
                                    {
                                        grp.Items = new List<Contact>();
                                    }
                                    grp.Items.Add(currentContact);
                                    // due to the way the xml is being written the value is held as the namespace !!!
                                    currentContact.Address = reader.NamespaceURI;
                                    break;
                                case "Number":
                                    // due to the way the xml is being written the value is held as the namespace !!!
                                    currentContact.Phone = reader.NamespaceURI;
                                    break;
                                case "Name":
                                    // due to the way the xml is being written the value is held as the namespace !!!
                                    currentContact.Name = reader.NamespaceURI;
                                    break;
                                default:
                                    break;
                            }
                        }
                    }
                }
            }
        }

        return returnObject;
}
于 2013-02-11T12:52:50.687 に答える