- PR -

XMLの内容を編集し、更新する手順について

1
投稿者投稿内容
RIZ
ベテラン
会議室デビュー日: 2003/11/05
投稿数: 61
投稿日時: 2003-11-11 18:38
よろしくお願い致します。

例えば以下のXMLがあるとします。
<?xml version="1.0" encoding="utf-8" ?>
<Books>
<Book ID="1">
<Name>AAA</Name>
<Author>BBB</Author>
<Price>1000</Price>
</Book>
<Book ID="2">
<Name>DDD</Name>
<Author>EEE</Author>
<Price>2000</Price>
</Book>
</Books>

例えば、Bookノードの「ID=1」の子のAuthorの値をBBB→CCCに変更したい
という時にどのように処理すれば良いのでしょうか?
自分でも調べました。
すると、XmlDocumentオブジェクトにReplaceChildという
ノードの置き換えにより変更できるというメソッドがありました。
これで下記のように処理しようと考えました。

1.置き換える古いノードと新しいノードを作成
XmlDocument doc = new XmlDocument();
doc.Load("XMLがあるパス");
XmlNode Old = doc.SelectSingleNode("XPath検索条件");
XmlNode New = doc.SelectSingleNode("XPath検索条件");
これで、古いノードと置き換える新しいノードを作成しました。

2.新しいノードのテキスト(Authorの値をBBB→CCC)を変更
ここでまず分からなかったのが、XPath検索条件によりノードの
取得は正常に行えます。取得したノードに子ノードがない場合は、
単に、New.Valueでノードの値が取れました。
値がとれたら、New.Value="CCC";というように更新しようと考えて
いました。

ただし、取得したノードに子ノードがある時に、単に
New.Valueでノードの値を取得しようとしてもNullが返ってきて
しまいます。ヘルプを見ると型によってはNullが返ってくると
書いていました。
上記XMLだと、検索条件でAuthorのノードを取得するとAuthorには
子ノードがないので問題ないのですが・・・
このような場合はどう対処すれば良いのでしょうか?


3.値を変更できたら、ReplaceChildメソッドに古いノードと新しいノードを
設定してXMLを更新させる


このような処理を考えています。
過去投稿を見ると、setNodeValueメソッドによるやり方もあると書いていましたが
これは調べましてもやり方がわからずで・・・

他にもっと効率が良いやり方があればそちらでも良いです
ご教授お願い致します。
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2003-11-12 00:14
こんにちわ。諸農です。

引用:

例えば、Bookノードの「ID=1」の子のAuthorの値をBBB→CCCに変更したい
という時にどのように処理すれば良いのでしょうか?



順に検索して探す等々でしょうか。

コード:
const string oldValue = "BBB";
const string newValue = "CCC";

XmlDocument xml = new XmlDocument();
xml.LoadXml("<?xml version=\"1.0\" encoding=\"SHIFT-JIS\" ?>"+ 
            "<Books>"+ 
            "<Book ID=\"1\">"+ 
            "<Name>AAA</Name>"+ 
            "<Author>BBB</Author>"+ 
            "<Price>1000</Price>"+ 
            "</Book>"+ 
            "<Book ID=\"2\">"+ 
            "<Name>DDD</Name>"+ 
            "<Author>EEE</Author>"+ 
            "<Price>2000</Price>"+ 
            "</Book>"+ 
            "</Books>");
XmlNodeList list = xml.GetElementsByTagName("Author");
foreach (XmlNode xn in list)
{
    if (xn.InnerText == oldValue)
    {
        xn.InnerText = newValue;    
    }
}
xml.Save(Path.ChangeExtension(Application.ExecutablePath,".xml"));



このコードをボタンクリックなどに記述して実行すると、
アプリケーションの横にXMLと言う拡張子のファイルが出来上がります。

ではでは(^^)/

_________________
諸農和岳
Powered by Turbo Delphi & Microsoft Visual Studio 2005

十兵衛@わんくま同盟
http://blogs.wankuma.com/jubei/
RIZ
ベテラン
会議室デビュー日: 2003/11/05
投稿数: 61
投稿日時: 2003-11-12 10:41
Jubeiさん、ありがとうございます。
早速試してみるとXMLファイルの更新をすることができました。

それで・・・
検索条件ですが、
下記のようなことを実現したいのですが
この場合はどうなるのでしょうか?
ソースを少し変更して試しているのですが
よく分からなくて・・・

例えば、下記XMLから
『BookのIDが2のAuthorをEEEに変更する』

:変更したソース
XmlDocument xml = new XmlDocument();
xml.Load(@"C:\Book.xml");
XmlNode node = xml.SelectSingleNode("/Books/Book[@ID='2']");
//検索して取得したノードからどうAuthorを探して更新すれば良いのかで悩んでいます
foreach (? xn in node)
{
if (xn.? == ?)
{
xn.value = "EEE";
}
}
xml.Save(Path.ChangeExtension(@"C:\","Book.xml"));


:対象となるXML
<?xml version="1.0" encoding="utf-8" ?>
<Books>
<Book ID="1">
<Name>AAA</Name>
<Author>BBB</Author>
<Price>1000</Price>
</Book>
<Book ID="2">
<Name>CCC</Name>
<Author>DDD</Author>
<Price>2000</Price>
</Book>
</Books>
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2003-11-12 11:26
こんにちわ。諸農です。

コード:
			const string oldValue = "BBB";
			const string newValue = "CCC";
			const string defValue = "EEE";
			const string targetNodeName = "Author";

			XmlDocument xml = new XmlDocument();
			xml.LoadXml("<?xml version=\"1.0\" encoding=\"SHIFT-JIS\" ?>"+
			"<Books>"+
			"<Book ID=\"1\">"+
			"<Name>AAA</Name>"+
			"<Author>BBB</Author>"+
			"<Price>1000</Price>"+
			"</Book>"+
			"<Book ID=\"2\">"+
			"<Name>DDD</Name>"+
			"<Author>EEE</Author>"+
			"<Price>2000</Price>"+
			"</Book>"+
			"</Books>");

			XmlNode node = xml.SelectSingleNode("/Books/Book[@ID='2']");
			foreach (XmlNode xn in node.ChildNodes)
			{
				if (xn.LocalName == targetNodeName){
					xn.InnerText = defValue;
				}
			}
			xml.Save(Path.ChangeExtension(Application.ExecutablePath,".xml"));



ではでは(^^)/
_________________
諸農和岳
Powered by Turbo Delphi & Microsoft Visual Studio 2005

十兵衛@わんくま同盟
http://blogs.wankuma.com/jubei/
RIZ
ベテラン
会議室デビュー日: 2003/11/05
投稿数: 61
投稿日時: 2003-11-12 14:24
ありがとうございます。
Xmlの読み込みをXmlファイルから読み込むように変更して、
記述してみました。理想通りの処理ができました。

それで、もう1つあるのですが・・・(すみません)
これだとテキストの変更はできました。
属性値の変更もしたいのですが、その場合はどのようになるのでしょうか?
対象となるXMLが下記として、BookのIDが2を条件として、Nameの属性Noを
005に変更するというような処理とすると・・・

foreach (XmlNode xn in node.ChildNodes)
によりノードは取得しているので、このノードの
プロパティに設定しておけばできるのかと考え、
xn変数のもつプロパティを見てみたのですが、
属性の取得はありました(Attributesプロパティ)が、設定が見当たらなかったので

XmlElement ele = xml.CreateElement("Author");
ele.SetAttribute("No","005");
のようにXmlElementクラスを利用すれば属性値を変えれるようですが、
これだとAuthorにより作成していますが、このAuthorがどのノードに属している
ものか分からないですし・・・多分このやり方は違うのだと思います
現にエラーはでなかったのですが、この処理を追加しても変更されていませんでした。

:対象となるXML
<?xml version="1.0" encoding="utf-8" ?>
<Books>
<Book ID="1">
<Name No="001">AAA</Name>
<Author>BBB</Author>
<Price>1000</Price>
</Book>
<Book ID="2">
<Name No="002">CCC</Name>
<Author>DDD</Author>
<Price>2000</Price>
</Book>
</Books>


それから、1つ疑問に思ったのが、
XmlDocument xml = new XmlDocument();
にてXmlDocumentクラスのインスタンスを作っています。
.NETでは、インスタンスを作った変数を解放するという
処理はしなくても良いのでしょうか?
ガベージコレクションにより使わなくなったら自動的に
解放してもらえるようですが
確かに、Disposeメソッドをサポートしているクラスもあり
ますが、XmlDocumentには解放するメソッドもなければ、変数を
Nothingすることもできないようでしたので(xn = Nothing;という)
Jubei
ぬし
会議室デビュー日: 2002/03/02
投稿数: 830
お住まい・勤務地: 関西
投稿日時: 2003-11-12 16:03
諸農です。

引用:

属性値の変更もしたいのですが、その場合はどのようになるのでしょうか?
対象となるXMLが下記として、BookのIDが2を条件として、Nameの属性Noを
005に変更するというような処理とすると・・・



コード:
ms-help://MS.NETFrameworkSDKv1.1.JA/cpguidenf/html/cpconXMLDocumentObjectModelDOM.htm

ms-help://MS.NETFrameworkSDKv1.1.JA/cpref/html/frlrfsystemxmlxmlattributecollectionclasstopic.htm



引用:

にてXmlDocumentクラスのインスタンスを作っています。
.NETでは、インスタンスを作った変数を解放するという
処理はしなくても良いのでしょうか?
ガベージコレクションにより使わなくなったら自動的に
解放してもらえるようですが
確かに、Disposeメソッドをサポートしているクラスもあり
ますが、XmlDocumentには解放するメソッドもなければ、変数を
Nothingすることもできないようでしたので(xn = Nothing;という)



どの言語を使われているかしりませんが。
http://www.atmarkit.co.jp/fdotnet/csharp_abc2/csabc2_003/cs2_003_01.html
http://www.atmarkit.co.jp/fdotnet/bookreview/beginner3/beginner3.html

ではでは(^^)/
_________________
諸農和岳
Powered by Turbo Delphi & Microsoft Visual Studio 2005

十兵衛@わんくま同盟
http://blogs.wankuma.com/jubei/
RIZ
ベテラン
会議室デビュー日: 2003/11/05
投稿数: 61
投稿日時: 2003-11-17 13:22
連絡遅れてすみません。

教えていただいたサイトを読んで、XmlAttributeCollection・XmlAttributeに
ついて調べました。
無事、属性値の変更を行うことができました。
また、XML構造についても今回で段々と理解できてきました。

オブジェクトの解放についても教えていだだいたページを読んでみました。
オブジェクト指向についてC#について始めたばかりでまだまだ勉強不足なので
こういうサイトとか書籍を見て勉強していきたいと思います。

今回はありがとうございました。
1

スキルアップ/キャリアアップ(JOB@IT)