|
■No44421 (渋木宏明(ひどり) さん) に返信 > 値と、値が存在する/しないを表現したいなら、Nullable 使えばいいのでは。 >
Nullableの使い方をネットで調べましたが、Nullの場合は代用値を入れる 等の処理ができるようで、 使っていけそうですが、要素(ルート)自体がない場合には適用できなさそうですが、どうなんでしょうか?
で、今の自分で出来る方法として、あまり良い内容ではないのですが、 一旦、xmlnodeに取り込んで、それをDataTableに入れ直すという方法です。
<Time>タグは必ずありますので、それをキーにしてデータを整理する といった方法で格納しました。
---コード----------------------------------------------------------------------------- private const string nodeText = "[name()='Time' or name()='LatitudeDegrees' " + "or name()='LongitudeDegrees' or name()='AltitudeMeters '" + "or name()='DistanceMeters' or name()='Value']"; private XmlDocument doc;
public DataTable GetData() {
DialogResult ret = this.ofd.ShowDialog(); List<string> list = new List<string>(); List<string> time = new List<string>();
if ( ret == DialogResult.OK ) {
doc = new XmlDocument(); doc.PreserveWhitespace = false; doc.Load( ofd.FileName );
foreach ( XmlNode node in doc.SelectNodes( "//*[name()='Time']/text()|//@*[name()='Time']" ) ) { time.Add( node.Value ); }
foreach ( XmlNode node in doc.SelectNodes( "//*" + nodeText + "/text()|//@*" + nodeText ) ) { list.Add( node.Value ); } }
return GetTable( time.Count, list ); }
private DataTable GetTable( int number, List<string> data ) {
DataTable dt = new DataTable( "GPS" ); // Time, LatitudeDegrees, LongitudeDegrees, AltitudeMeters, DistanceMeters, Valueを格納 dt.Columns.Add( "Time", typeof( String ) ); dt.Columns.Add( "LatitudeDegrees", typeof( Double ) ); dt.Columns.Add( "LongitudeDegrees", typeof( Double ) ); dt.Columns.Add( "AltitudeMeters", typeof( Double ) ); dt.Columns.Add( "DistanceMeters", typeof( Double ) ); dt.Columns.Add( "Value", typeof( Double ) );
int inumber = 0;
for ( int i = 0; i < data.Count; i++ ) { if ( "Z" == data[ i ].Substring( data[ i ].Length - 1 ) ) { var row = dt.NewRow(); if ( i + dt.Rows.Count >= data.Count ) break;
row[0] = data[ i ];
i++; for ( int j = 1; j < dt.Columns.Count; j++ ) { if ( "Z" != data[ i ].Substring( data[ i ].Length - 1 ) ) { row[ j ] = data[ i ]; } else { row[ j ] = "0"; } i++; } dt.Rows.Add( row ); inumber++; } }
return dt;
} -------------こちらは2次元配列に格納する場合---------------------------------------------
//List<string>データをString[]に格納してList<String[]>に置き換える //はずが、どうもList list.Add(**)とするも後ろに追加ではなく、 //すべて書き換えになるので、しょうがないので2次元配列で対処 //DataTableに入れた方がいいかな。 private String[,] Change( int number, List<string> data ) {
// Time, LatitudeDegrees, LongitudeDegrees, AltitudeMeters, DistanceMeters, Valueを格納 int value = 6; string[] str = new string[ value ];
List<String[]> list = new List<string[]>(); String[ , ] strArray = new String[ number, value ];
int inumber = 0;
for ( int i = 0; i < data.Count; i++ ) { if ( "Z" == data[ i ].Substring( data[ i ].Length - 1 ) ) { if ( i + value >= data.Count ) break;
strArray[ inumber, 0 ] = data[ i ];
i++; for ( int j = 1; j < value; j++ ) { if ( "Z" != data[ i ].Substring( data[ i ].Length - 1 ) ) { strArray[ inumber, j ] = data[ i ]; } else { strArray[ inumber, j ] = "0"; } i++; } inumber++; } } return strArray; } --------------------------------------------------------------------------------------- 次にList<String[]>に格納しようとしたのですが、バグなのでしょうか List.Add(**)としてループでどんどん追加したのですが、なぜか格納されたすべてのデータが、 最後に格納したデータに書き換えられてしまいます。
例えば、 list.Add("1"); list.Add("2"); list.Add("3"); の中身は、 1 2 3 となると思うのですが、これが 3 3 3 となってしまうのです。それがずーっと解決できなかったもので、2次配列やDataTableに格納となった次第です。 ちなみにこちらがそのコードです。何がおかしいのでしょうか?
// IEnumerator<string> ie = motoData.GetEnumerator();
// while ( ie.MoveNext() ) {
// if ( "Z" == ie.Current.Substring( ie.Current.Length - 1 ) ) { // //Time情報から格納開始し、Valueデータ数あればそのまま格納 // //無ければ"0"で補完でしょうがないや。 // str[ 0 ] = ie.Current; // ie.MoveNext();
// for ( int i = 1; i < value; i++ ) { // if ( "Z" != ie.Current.Substring( ie.Current.Length - 1 ) ) { // str[ i ] = ie.Current; // ie.MoveNext(); // } else { // for ( int j = 0; j < value; j++ ) { // str[ j ] = "0"; // } // break; // } // } // list.Add( str ); // } // } --------------------------------------------------------------------------------- もっと効率の良い(取り込んでから、格納までの消費メモリーや時間が短い)方法はないでしょうか。 結構、処理に時間がかかります。
|