C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[7]: XMLコードの要素に文字列のデータを設定する。


(過去ログ 71 を表示中)

[トピック内 8 記事 (1 - 8 表示)]  << 0 >>

■41662 / inTopicNo.1)  XMLコードの要素に文字列のデータを設定する。
  
□投稿者/ RT (149回)-(2009/09/27(Sun) 18:01:10)

分類:[.NET 全般] 

こんにちは。RTです。
たびたびお世話になります。
C#にてプログラミングを行っております。

質問なのですが、XMLコードの要素に文字列のデータを設定する時に、↓のコードを書いたのですが、

// 要素の文字列を変更する
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
doc.Load("INI.xml");
// Server要素を取得
System.Xml.XmlElement Server =
(System.Xml.XmlElement)doc.DocumentElement.FirstChild;
// Server要素の文字列を変更
Server.RemoveChild(Server.FirstChild);
Server.AppendChild(doc.CreateTextNode(textBox1.Text));

     // 書き出し
doc.Save("output.xml");
MessageBox.Show("ファイルに書き出しました", "実行結果");

this.Close(); //自分を閉じる。
this.Dispose();

予定では、タグの中身を書き換えるはずが、タグも消してしまう結果になります。
何か問題点があるでしょうか?アドバイスお願いします。


引用返信 編集キー/
■41670 / inTopicNo.2)  Re[1]: XMLコードの要素に文字列のデータを設定する。
□投稿者/ たくボン (212回)-(2009/09/27(Sun) 21:52:46)
No41662 (RT さん) に返信
> 質問なのですが、XMLコードの要素に文字列のデータを設定する時に、↓のコードを書いたのですが、
> 予定では、タグの中身を書き換えるはずが、タグも消してしまう結果になります。
> 何か問題点があるでしょうか?アドバイスお願いします。

どんなXMLを読み込んでますか?

<?xml version="1.0" standalone="yes"?>
<xmlroot>
<id>hoge</id>
</xmlroot>

こんな感じのXMLなら

<?xml version="1.0" standalone="yes"?>
<xmlroot>
<id>moge</id>
</xmlroot>

正しく変換されてます。

ただし、パスの指定が曖昧なので、c;\temp固定でしましたけど。
実行時にパスを指定しない場合、Application.ExecutablePathに出力されると思いますが、そのファイルを見て判断されていますか?

まずは問題の切り分けから行った方がいいかも。
引用返信 編集キー/
■41677 / inTopicNo.3)  Re[2]: XMLコードの要素に文字列のデータを設定する。
□投稿者/ RT (150回)-(2009/09/28(Mon) 10:27:12)
No41670 (たくボン さん) に返信

> どんなXMLを読み込んでますか?

<?xml version="1.0" encoding="shift_jis"?>
<SaveXMLClass>
<FTP>
<Server>サーバー名</Server>
<User>ユーザー名</User>
<PassWord>パスワード</PassWord>
</FTP>
<HELP>
<aa>あ</aa>
  <b>あ</b>
  <c>あ</c>
</HELP>
<ETC>
<SavePass>C:\download\indexhtml</SavePass>
<EditURL>http://www.xxx.net/</EditURL>
</ETC>
</SaveXMLClass>

こんな感じのXMLファイルを読み込んでいます。

standalone="yes"という設定にしても、結果は同じでした。
引用返信 編集キー/
■41678 / inTopicNo.4)  Re[3]: XMLコードの要素に文字列のデータを設定する。
□投稿者/ 魔界の仮面弁士 (1324回)-(2009/09/28(Mon) 10:45:23)
No41677 (RT さん) に返信
> <PassWord>パスワード</PassWord>
パスワードは "password" で一つの英単語なので、W は大文字にしない方が良いかも。
(まぁ、略称として PW などと書くことはあるようですが)

>    <aa>あ</aa>
>   <b>あ</b>
>   <c>あ</c>
aa の前にあるのは半角空白ですが、
b の前には全角空白が含まれています。
その点は大丈夫でしょうか。


> // Server要素を取得
> System.Xml.XmlElement Server = (System.Xml.XmlElement)doc.DocumentElement.FirstChild;
デバッグ時に、Server.OuterXml を確認してみましょう。

ここで .DocumentElement.FirstChild が指し示しているのは、
/SaveXMLClass/FTP/Server ではなく、
/SaveXMLClass/FTP ですよ。


> // Server要素の文字列を変更
> Server.RemoveChild(Server.FirstChild);
FTP 要素の最初の要素を削除していますから、
/SaveXMLClass/FTP/Server/text() のテキストではなく、
/SaveXMLClass/FTP/Server が要素ごと削除されることになります。


> Server.AppendChild(doc.CreateTextNode(textBox1.Text));
そしてこのコードにより、/SaveXMLClass/FTP の最後に
テキストが追加されます。

引用返信 編集キー/
■41680 / inTopicNo.5)  Re[4]: XMLコードの要素に文字列のデータを設定する。
□投稿者/ RT (151回)-(2009/09/28(Mon) 11:41:36)
No41678 (魔界の仮面弁士 さん) に返信

> ここで .DocumentElement.FirstChild が指し示しているのは、
> /SaveXMLClass/FTP/Server ではなく、
> /SaveXMLClass/FTP ですよ。

// Server要素を取得
System.Xml.XmlElement Server =
(System.Xml.XmlElement)doc.DocumentElement.FirstChild.FirstChild;

↑のようにする事でうまくいきました。

たくぼんさん、魔界の仮面弁士 さん、アドバイスありがとうございました。
またよろしくお願いします。
解決済み
引用返信 編集キー/
■41682 / inTopicNo.6)  Re[5]: XMLコードの要素に文字列のデータを設定する。
□投稿者/ RT (152回)-(2009/09/28(Mon) 12:05:41)
2009/09/28(Mon) 12:06:19 編集(投稿者)

// 要素の文字列を変更する
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
doc.Load("INI.xml");
// Server要素を取得
System.Xml.XmlElement Server =
(System.Xml.XmlElement)doc.DocumentElement.FirstChild.FirstChild;
// Server要素の文字列を変更
Server.RemoveChild(Server.FirstChild);
Server.AppendChild(doc.CreateTextNode(textBox1.Text));

// User要素を取得
System.Xml.XmlElement User =
(System.Xml.XmlElement)doc.DocumentElement.FirstChild.FirstChild;
// User要素の文字列を変更
User.RemoveChild(User.FirstChild);
User.AppendChild(doc.CreateTextNode(textBox2.Text));

// PassWord要素を取得
System.Xml.XmlElement PassWord =
(System.Xml.XmlElement)doc.DocumentElement.FirstChild.FirstChild;
// PassWord要素の文字列を変更
PassWord.RemoveChild(PassWord.FirstChild);
PassWord.AppendChild(doc.CreateTextNode(textBox3.Text));

// 書き出し
doc.Save("output.xml");
MessageBox.Show("ファイルに書き出しました", "実行結果");

this.Close(); //自分を閉じる。
this.Dispose();


 ↑のコードのように変更箇所を1つから、3つに増やしたのですが、1つ目のServerの要素しか変化が反映されません。同じ事をやっているのに、反映されない箇所があるのはどうしてでしょうか?
引用返信 編集キー/
■41684 / inTopicNo.7)  Re[6]: XMLコードの要素に文字列のデータを設定する。
□投稿者/ 魔界の仮面弁士 (1325回)-(2009/09/28(Mon) 13:25:08)
No41682 (RT さん) に返信
>             System.Xml.XmlElement Server =
>                 (System.Xml.XmlElement)doc.DocumentElement.FirstChild.FirstChild;
XML 中の空白・タブ・改行が意味を持つ場合もある事に注意してください。たとえば、Load 前に
 doc.PreserveWhitespace = true;  // 初期値は false
としていた場合、この doc.DocumentElement.FirstChild.FirstChild は、
テキスト(中身は改行文字)を返す事になるため、XmlElement へのキャストは失敗します。蛇足までに。


> // Server要素の文字列を変更
> Server.RemoveChild(Server.FirstChild);
> Server.AppendChild(doc.CreateTextNode(textBox1.Text));
そこまでせずとも、
 Server.InnerText = textBox1.Text;
でも十分かと思いますよ。

あるいは、XPath 式を用いた指定として
 doc.SelectSingleNode("/SaveXMLClass/FTP/Server/text()").Value = textBox1.Text;
とか
 doc.SelectSingleNode("/SaveXMLClass/FTP/Server").InnerText = textBox1.Text;
といった、SelectSingleNode(SelectNodes)メソッドを併用する手法もあります。


> 同じ事をやっているのに、反映されない箇所があるのはどうしてでしょうか?
同じ事をやっているからでしょう。
同じコードを書けば、同じノード(Server要素)が選択されるのは当然ですよね。

先ほども書きましたが、どのノードが取得されたのか、OuterXml でチェックしましょう。

たとえば、User 要素を拾う場合、その位置をどのように捉えるのかにもよりますが、
「Server の次のノード」という位置付なら、User = Server.NextSibling; で取得できますし、
「FTP 要素配下の 2 番目の要素」なら、User = doc.DocumentElement.FirstChild.ChildNodes[1]; と
書く事ができます。

引用返信 編集キー/
■41685 / inTopicNo.8)  Re[7]: XMLコードの要素に文字列のデータを設定する。
□投稿者/ RT (153回)-(2009/09/28(Mon) 13:40:11)
No41684 (魔界の仮面弁士 さん) に返信

詳しい説明ありがとうございました。

// 要素の文字列を変更する
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
doc.Load("INI.xml");
// Server要素を取得
System.Xml.XmlElement Server =
(System.Xml.XmlElement)doc.DocumentElement.FirstChild.FirstChild;

Server.InnerText = textBox1.Text;

Server.NextSibling.InnerText = textBox2.Text;

Server.NextSibling.NextSibling.InnerText = textBox3.Text;

// 書き出し
doc.Save("output.xml");
MessageBox.Show("ファイルに書き出しました", "実行結果");

this.Close(); //自分を閉じる。
this.Dispose();

↑のコードで、やりたいことが実現出来ました。

魔界の仮面弁士 さん、ありがとうございました。またアドバイスよろしくお願いします。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -