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

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

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

Re[7]: XmlNode.ChildNodesをソートできますか?


(過去ログ 13 を表示中)

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

■3671 / inTopicNo.1)  XmlNode.ChildNodesをソートできますか?
  
□投稿者/ kirapa (11回)-(2007/05/18(Fri) 16:20:36)

分類:[C# (Windows)] 

環境:Visual C# 2005 Express Edition

XmlNode nodeParent;



foreach(XmlNode node in nodeParent.ChildNodes){
}

と記述したときに、nodeParent.ChildNodesをある規則でソートした順に
処理を行いたいのですが、どうすればよいのでしょうか?

比較する関数を用意して
Sort(nodeParent.ChildNodes, 比較関数)
のようなことはできるのでしょうか?

それともnodeParent.ChildNodesをソートした結果を index位置のテーブルで保持して
foreach(int i in array_index){
nodeParent[i];
}
のようにアクセスするべきでしょうか?

よろしくお願いします。
引用返信 編集キー/
■3672 / inTopicNo.2)  Re[1]: XmlNode.ChildNodesをソートできますか?
□投稿者/ kirapa (12回)-(2007/05/18(Fri) 16:59:50)
>それともnodeParent.ChildNodesをソートした結果を index位置のテーブルで保持して
これは↓の方法で実現できました。

public void SortNodes(XmlNode nodes)
{
SortedList<string, int> sorted = new SortedList<string, int>();

int index = 0;
foreach (XmlNode node in nodes)
{
int sufix = 0;
while(true)
{
try
{
string node_str; //nodeから生成した比較用の文字列
string str = (sufix++ == 0) ? "" : sufix.ToString();
sorted.Add(node_str + str, index++);
}
catch
{
//key が重複した時は、登録順にする
if (sufix > 100) { return; }
continue;
}
break;
}
}
foreach (KeyValuePair<string, int> kvp in sorted)
{
Console.WriteLine("Key = {0}, Value = {1}", kvp.Key, kvp.Value);
}
}


sorted を結果を元に nodes を並べかえることはできますか?

よろしくおねがします。
引用返信 編集キー/
■3674 / inTopicNo.3)  Re[2]: XmlNode.ChildNodesをソートできますか?
□投稿者/ kirapa (13回)-(2007/05/18(Fri) 17:58:03)
載せたソースに誤りがありました。修正しておきます。

修正前
try
{
string node_str; //nodeから生成した比較用の文字列
string str = (sufix++ == 0) ? "" : sufix.ToString();
sorted.Add(node_str + str, index++);
}

修正後
try
{
string node_str; //nodeから生成した比較用の文字列
string str = (sufix++ == 0) ? "" : sufix.ToString();
sorted.Add(node_str + str, index);
index++;
}
引用返信 編集キー/
■3679 / inTopicNo.4)  Re[1]: XmlNode.ChildNodesをソートできますか?
□投稿者/ επιστημη (518回)-(2007/05/18(Fri) 21:53:40)
επιστημη さんの Web サイト
> 比較する関数を用意して
> Sort(nodeParent.ChildNodes, 比較関数)
> のようなことはできるのでしょうか?

XmlNode[] children = (new List<XmlNode>(root.ChildNodes)).ToArray();
Array.Sort<XmlNode>(children, 比較delegate);

ではダメかしら?

引用返信 編集キー/
■3680 / inTopicNo.5)  Re[2]: XmlNode.ChildNodesをソートできますか?
□投稿者/ Hongliang (140回)-(2007/05/18(Fri) 22:19:26)
Hongliang さんの Web サイト
先生、ToArray する意味が見つかりません。List<T>.Sort があります。
と言うかそれ以前に XmlNodeList は IEnumerable<T> を実装しないので List<T> の初期化子に使えませぬ。
配列なり List<T> なりを先に作って for / foreach で一つずつ突っ込んでかないと。
// ArrayList なら、と思ったらこっちは ICollection が要求された。
引用返信 編集キー/
■3683 / inTopicNo.6)  Re[3]: XmlNode.ChildNodesをソートできますか?
□投稿者/ επιστημη (519回)-(2007/05/19(Sat) 00:14:44)
επιστημη さんの Web サイト
> と言うかそれ以前に XmlNodeList は IEnumerable<T> を実装しないので List<T> の初期化子に使えませぬ。

あらホント。失礼ぶっこきました。
引用返信 編集キー/
■3688 / inTopicNo.7)  Re[4]: XmlNode.ChildNodesをソートできますか?
□投稿者/ 中博俊 (1070回)-(2007/05/19(Sat) 11:08:05)
中博俊 さんの Web サイト
まぁべたに引っこ抜いてSortですね。
というかXMLではデータの並びにも意味があると考えるので、ソートはどちらかというとすべきではないと考えた方がいいでしょう。
引用返信 編集キー/
■3691 / inTopicNo.8)  Re[5]: XmlNode.ChildNodesをソートできますか?
□投稿者/ επιστημη (520回)-(2007/05/19(Sat) 19:19:24)
επιστημη さんの Web サイト
2007/05/19(Sat) 23:44:12 編集(投稿者)
> まぁべたに引っこ抜いてSortですね。

お詫びかたがた"べたに引っこ抜いてSortする"テスト。

using System;
using System.Xml;

namespace XMLsort {
  class Program {
   static void Main() {
     XmlDocument document = new XmlDocument();
     // XMLを読み込んで
     document.Load("trial.xml");
     // root要素の
     XmlElement root = document.DocumentElement;
     // 子供達を配列に転写し
     XmlElement[] children = new XmlElement[root.ChildNodes.Count];
     int i = 0;
     foreach ( XmlNode child in root.ChildNodes ) {
       children[i++] = (XmlElement)child;
     }
     // name属性の値でソートして
     Array.Sort(children, 
                delegate (XmlElement x, XmlElement y) {
                  return x.Attributes["name"].Value.CompareTo(y.Attributes["name"].Value);
                });
     // 書き出す。
     foreach ( XmlElement child in children ) {
       Console.WriteLine("{0} = {1}", child.Attributes["name"].Value, child.InnerText);
     }
   }
  }
}

↑コレに↓コレを食わせると:

<?xml version="1.0"?>
<root>
  <variable name="apple">りんご</variable>
  <variable name="orange">みかん</variable>
  <variable name="banana">ばなな</variable>
  <variable name="peach">もも</variable>
  <variable name="grape">ぶどう</variable>
</root>

↓コレが出ますた。Sortできてるポ。

apple = りんご
banana = ばなな
grape = ぶどう
orange = みかん
peach = もも



</pre></pre>

引用返信 編集キー/
■3706 / inTopicNo.9)  Re[6]: XmlNode.ChildNodesをソートできますか?
□投稿者/ kirapa (14回)-(2007/05/20(Sun) 00:09:32)
επιστημη さん
Sort のプログラム参考になりました。
C#を使い始めたばっかりなので(自分の中ではC++を一番使える)delegate の書き方にびっくりです。


Hongliang さん
>配列なり List<T> なりを先に作って for / foreach で一つずつ突っ込んでかないと。
中博俊さん
>まぁべたに引っこ抜いてSortですね。
XmlNodeList を Sort できないことがわかりました。
並べ替えた結果を取得するためには、配列やList に追加しなければならないので、
今回は、SortedList を利用して要素を追加後に Sort しないですむようにしたいと思います。

static void Main(string[] args)
{
string s = "<?xml version=\"1.0\"?>"
+ "<root>"
+ " <variable name=\"apple\">りんご</variable>"
+ " <variable name=\"orange\">みかん</variable>"
+ " <variable name=\"banana\">ばなな</variable>"
+ " <variable name=\"peach\">もも</variable>"
+ " <variable name=\"grape\">ぶどう</variable>"
+ "</root>"
;

XmlDocument document = new XmlDocument();
document.LoadXml(s);
XmlElement root = document.DocumentElement;
XmlElement[] children = new XmlElement[root.ChildNodes.Count];
int i = 0;
foreach(XmlNode child in root.ChildNodes)
{
children[i++] = (XmlElement)child;
}
Array.Sort(children, delegate(XmlElement x, XmlElement y)
{
return x.Attributes["name"].Value.CompareTo(y.Attributes["name"].Value);
});
Console.WriteLine("επιστημη さんのコード");
foreach(XmlElement child in children)
{
Console.WriteLine("{0} = {1}", child.Attributes["name"].Value, child.InnerText);
}


SortedList<string, XmlNode> sorted = new SortedList<string, XmlNode>();
foreach(XmlNode child in root.ChildNodes)
{
sorted.Add(child.Attributes["name"].Value, child);
}
Console.WriteLine("Kirapaのコード");
foreach(XmlNode child in sorted.Values)
{
Console.WriteLine("{0} = {1}", child.Attributes["name"].Value, child.InnerText);
}
}


とても勉強になりました。
ありがとうございました。

解決済み
引用返信 編集キー/
■3707 / inTopicNo.10)  Re[7]: XmlNode.ChildNodesをソートできますか?
□投稿者/ επιστημη (524回)-(2007/05/20(Sun) 00:50:04)
επιστημη さんの Web サイト
こちらこそ勉強になりますです。

>             foreach(XmlNode child in root.ChildNodes)
>             {
>                 sorted.Add(child.Attributes["name"].Value, child);
>             }

ほー、XmlNodeはAttributesプロパティ持ってんだー
AttributeってくらいだからXmlElementに限るとオモコしてたですだ ^^;
# てゆっか、どんな要素かわからんのがXmlNodeなわけで、
# そんなのにAttributeだのChildNodesだのあって委員会!? っておもふ…

解決済み
引用返信 編集キー/


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

このトピックに書きこむ

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

管理者用

- Child Tree -