質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

3回答

4201閲覧

C#でXMLの追記について教えてください。

picko

総合スコア52

XML

XMLは仕様の1つで、マークアップ言語群を構築するために使われています。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2018/04/13 02:16

編集2018/04/13 02:18

前提・実現したいこと

C#でXMLの追記について教えてください。

試したこと

下記のようなXMLをクラスにしました。

XML

1<?xml version="1.0" encoding="utf-8"?> 2 <People xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 3 <PeopleGroup> 4 <Person Name = "保坂" /> 5 <Person Name = "朝倉" /> 6 </PeopleGroup> 7 </People>

C#

1[System.SerializableAttribute()] 2[System.ComponentModel.DesignerCategoryAttribute("code")] 3[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://schemas.microsoft.com/developer/msbuild/2003")] 4[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://schemas.microsoft.com/developer/msbuild/2003", IsNullable = false)] 5public partial class People 6{ 7 8 private PeoplePerson[] peopleGroupField; 9 10 [System.Xml.Serialization.XmlArrayItemAttribute("Person", IsNullable = false)] 11 public PeoplePerson[] PeopleGroup { 12 get { 13 return this.peopleGroupField; 14 } 15 set { 16 this.peopleGroupField = value; 17 } 18 } 19} 20 21[System.SerializableAttribute()] 22[System.ComponentModel.DesignerCategoryAttribute("code")] 23[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://schemas.microsoft.com/developer/msbuild/2003")] 24public partial class PeoplePerson 25{ 26 private string nameField; 27 28 [System.Xml.Serialization.XmlAttributeAttribute()] 29 public string Name { 30 get { 31 return this.nameField; 32 } 33 set { 34 this.nameField = value; 35 } 36 } 37}

http://takachan.hatenablog.com/entry/2017/06/22/225341
を参考に読み書きのコードを構築しました。

C#

1 public void AddFile(string filepath) 2 { 3 var people = Deserialize<People>(filepath); 4 5 //追加。 6 //XmlElement element = person.CreateElement("Name", "木村");//<=ここがうまくいかない。 7 8 //出力 9 Serialize(filepath people); 10 } 11 12 13 public static T Deserialize<T>(string loadPath) 14 { 15 using (var sr = new StreamReader(loadPath)) 16 { 17 return (T)new XmlSerializer(typeof(T)).Deserialize(sr); 18 } 19 } 20 21 public static void Serialize<T>(string savePath, T graph) 22 { 23 using (var sw = new StreamWriter(savePath, false, Encoding.UTF8)) 24 { 25 var ns = new XmlSerializerNamespaces(); 26 ns.Add(string.Empty, string.Empty); 27 28 new XmlSerializer(typeof(T)).Serialize(sw, graph, ns); 29 } 30 }

発生している問題・エラーメッセージ

読み書きはできると思うのですが、読んで追加することができません。
アドバイスお願いします。

補足情報(FW/ツールのバージョンなど)

Visual Studio 2017 Community
Windows 10 64bit

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

y_waiwai

2018/04/13 03:31

読んで追加することが出来ないとは具体的にどうなるんでしょうか?エラーが出るなら、エラーメッセージも出してください
picko

2018/04/13 03:40

追加するエレメントをコード化できないでいる、ということです。people.CreateElementとすると、peopleにはCreateElementがない、とエラーです。
coco_bauer

2018/04/13 03:57

「XMLをクラスにしました」との事ですが、そのクラスを質問に追記してもらえませんか? 何が出来る/出来ないというのはクラス定義に依存しますが、肝心のクラスが判らないのでは検討のしようがありません。
picko

2018/04/13 03:58

クラス貼ってあります。
guest

回答3

0

ベストアンサー

質問のXMLのデータ構造から(とりあえずMethonの定義を後回しにして)クラスを作ると次のようになると思います。 xmlのタグとクラス名と一致させておくと対応付けが判り易いです。
(質問のC#のコードは、peopleとpeoplepersonの2階層になっていて、XMLに「Peopleの中にはPeopleGroupが必ず1個ある(0個とか2個以上は禁止)」という制約を前提にしないと無理があります。そのため失礼ですが「XMLをクラスに」したものとは思いませんでした)

Public class people{ private peoplegroup peoplegroups[]; } public class peoplegroup{ private person persons[]; } public class person{ private string Name; }

次に、どのようなメソッドを用意するかについてですが。
・personクラスは、Nameしかプロパティを持たないのでsetterとgetterだけ用意すれば十分です。
・peoplegroupクラスとpeopleクラスは、配列のプロパティを持っていますから、以下のようなメソッドを用意します。
a) 配列の大きさを取得する
b) 配列のn番目の要素の値を取得する
c) 配列のn番目の要素に代入する
d) 配列のn番目の要素を削除する(配列が小さくなります)
e) 配列のn番目の要素の後に値を挿入する(配列が大きくなります)
f) 配列を空にする
g) 配列を取得する
h) 配列に代入する
これだけあれば、何をするにも困らないと思います(a~eの組み合わせで、f~hは実現可能です)

== 気づいた点 ==
partial class(部分クラス)は、1つのクラスの定義を分けて書く場合に使います。
コードの中に"public partial class People"があれば、それ以外に1個以上の"public partial class People"があるはずです。そうでなければ、完全なクラスの定義になりません。

投稿2018/04/13 04:52

coco_bauer

総合スコア6915

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

XMLは関係ないのでは? 
Deserializeメソッドで何が返ってきて、Serializeメソッドに何を渡しているか理解してますか?

C#

1 public void AddFile(string filepath) 2 { 3 var people = Deserialize<People>(filepath); 4 5 var lst = people.PeopleGroup.ToList(); 6 lst.Add(new PeoplePerson() { Name = "木村" }); 7 people.PeopleGroup = lst.ToArray(); 8 9 //追加。 10 //XmlElement element = person.CreateElement("Name", "木村");//<=ここがうまくいかない。 11 12 //出力 13 Serialize(filepath, people); 14 }

投稿2018/04/13 04:08

ebiryo

総合スコア797

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

picko

2018/04/13 06:06

Deserializeで返ってきたものがなにであるかは、ブレークポイントでとめてみることができるのでわかります。 複雑なPeopleクラスです。 これにどう足したらよいのかが、わからないのです。
guest

0

peopleにPeoplePersonを追加するメソッドを追加すればいい

という話になります。
が、peopleのPeoplePersonは配列になってしまって簡単には追加ができない。

なら、そこは追加できるような配列に変えてしまいましょう

投稿2018/04/13 03:46

y_waiwai

総合スコア87747

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問