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

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

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

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

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

C#

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

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

Q&A

解決済

3回答

1062閲覧

C# .netframework , CSVファイルの読み込み XMLファイルに設定された区切り文字を指定

WHdfghjk

総合スコア12

XML

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

CSV

CSV(Comma-Separated Values)はコンマで区切られた明白なテキスト値のリストです。もしくは、そのフォーマットでひとつ以上のリストを含むファイルを指します。

C#

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

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

0グッド

0クリップ

投稿2023/04/20 03:50

実現したいこと

C# .netframework 4.6.1
TextFieldParserクラスを使用して、CSVファイルを読み込みたい
区切り文字の文字列の設定を設定ファイル(XML)から指定する。
カンマ区切りについては再現できたが、タブやスペースなどの設定ができないので
できるようにしたい。

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

現在、以下XMLファイルから2つの項目を取得する処理ができております。
両方ともConfigModelクラスのstring型のフィールドに格納してます。

それを引数として、以下のソースコードReadCsvFileメソッドを実行します。
20行目で区切り文字の設定を行なっております。
XMLファイルの設定値は、¥tを設定しており、これをパラメータとしてReadCsvFileメソッド実行すると、
23行目で区切られた形式で取得することができませんでした。

20行目を以下のようにハードコーディングすると問題なく動きます。
parser.SetDelimiters("¥t");

XMLファイルから取得した値を使用して区切り文字に対して可変となるようにしたいです。

該当のソースコード

C#

1using System; 2using Microsoft.VisualBasic.FileIO; 3using System.Data; 4using System.Linq; 5using System.Text; 6 7namespace csv 8{ 9 10    public class Csvreader 11    { 12  13        public DataTable ReadCsvFile(string filePath, string delimiter) 14        { 15            var dt = new DataTable(); 16            Encoding encoding = Encoding.GetEncoding("utf-8"); 17            using (var parser = new TextFieldParser(filePath, encoding)) 18            { 19                parser.TextFieldType = FieldType.Delimited; 20                parser.SetDelimiters(delimiter); 21 22                    //ヘッダー取得処理 23                    string[] headerFields = parser.ReadFields(); 24                    for (int i = 0; i < 10; i++) 25                    { 26                        dt.Columns.Add(headerFields[i]); 27                    } 28 29 30                //データ行の取得コード 31     .....省略 32 33            return dt; 34        } 35    } 36}

XML

1<?xml version="1.0" encoding="utf-8"?> 2<ConfigModel> 3<Csv> 4<filePath></filePath> 5<Delimiter>¥t</Delimiter> 6</Csv> 7</ConfigModel>

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

.net framework 4.6.1

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

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

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

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

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

episteme

2023/04/20 04:12 編集

> 20行目を以下のようにハードコーディングすると問題なく動きます。 > parser.SetDelimiters("¥t"); だったらXMLから tab が読み取れていないのでしょう。 XML中に \t と置けば tab になるんですか? &#9; とかじゃなくて?
Zuishin

2023/04/20 04:44

\t は XML ではタブではなく、C♯ でも文字列リテラルとしてコンパイルを通さないとタブにはなりません。 episteme さんの書かれた &♯9; が XML でタブを表す直接的な表記なので、それでうまくいくはずですが、人間による読み書きを重視するのであれば、\t や tab といった文字列から、読み取った後に一度自前の変換処理を挟むのもありでしょう。
退会済みユーザー

退会済みユーザー

2023/04/20 04:53

> 以下XMLファイルから2つの項目を取得する処理ができております。両方ともConfigModelクラスのstring型のフィールドに格納してます。 そのコードも提示できませんか?
guest

回答3

0

これではいかがでしょう。

XML

1<?xml version="1.0" encoding="utf-8"?> 2<ConfigModel> 3 <Csv> 4 <filePath></filePath> 5 <Delimiter>&#9;</Delimiter> 6 </Csv> 7</ConfigModel>

投稿2023/04/20 07:15

episteme

総合スコア16614

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

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

退会済みユーザー

退会済みユーザー

2023/04/20 07:31

それでその先 ReadCsvFile(string filePath, string delimiter) の delimiter にどのようにタブ文字を代入するのでしょうか?
episteme

2023/04/20 07:35

XMLから読み込むとこが質問には明示されていないので、正直「知らんがな」です。
退会済みユーザー

退会済みユーザー

2023/04/20 07:58

じゃあ最初から「知らんがな」ということで最初からスルーするのがよろしいかと思いますけど。
episteme

2023/04/20 08:06

XML上では \t ではなく &#9; ではないかと回答したまで。
退会済みユーザー

退会済みユーザー

2023/04/20 09:26

XML 上で \t はどう書くかという質問ではないのは明らか。なので回答になってない。回答でないことを回答欄に書くべきでなないのでは?
退会済みユーザー

退会済みユーザー

2023/04/20 09:27

「グッドを送る」とかした人は誰ですか? どういう理由ですか?
episteme

2023/04/20 09:31

> XML 上で \t はどう書くかという質問ではないのは明らか。 そうですか? 現に質問には <Delimiter>¥t</Delimiter> とありますけど。
退会済みユーザー

退会済みユーザー

2023/04/20 09:51 編集

だからそれが質問ではないと言っているのですが? 問題は、それから取得した文字列 "\t" (と質問者は思ってる) を ReadCsvFile(string filePath, string delimiter) の delimiter に代入しても delimiter で区切られた形式にならないということ。質問はその解決策。 ですよね>質問者さん
退会済みユーザー

退会済みユーザー

2023/04/20 14:09

ちなみに <Delimiter>&#9;</Delimiter> として、私が回答に書いた、 XDocument doc = XDocument.Load("xml ファイルのパス"); XElement elem = doc.Element("ConfigModel").Element("Csv").Element("Delimiter"); string value = elem.Value; のようにすると、value は "" になります。それを ReadCsvFile(string filePath, string delimiter) の delimiter に代入するとエラーになります。
TN8001

2023/04/20 16:43

> のようにすると、value は "" になります。 「空白文字の正規化」のため消えてしまいますが、LoadOptionsを付ければ残すことは可能です。 XDocument doc = XDocument.Load("xml ファイルのパス", LoadOptions.PreserveWhitespace); [XAML での空白の処理 - XAML | Microsoft Learn](https://learn.microsoft.com/ja-jp/dotnet/desktop/xaml-services/white-space-processing#white-space-normalization) [LoadOptions 列挙型 (System.Xml.Linq) | Microsoft Learn](https://learn.microsoft.com/ja-jp/dotnet/api/system.xml.linq.loadoptions) XmlSerializer#Deserializeでクラスにマップした場合も残りました。 質問に読み込むところがないので何とも言えないですが... まあだからと言って、覚えられないし使いたくはないですね^^; SurferOnWwwさんの方法が一番わかりやすいとは思います。
guest

0

質問に対するコメント、

以下XMLファイルから2つの項目を取得する処理ができております。両方ともConfigModelクラスのstring型のフィールドに格納してます。

そのコードも提示できませんか?

に返事がないのでいろいろ不明ですが・・・

XML から <Delimiter>¥t</Delimiter> の value を取得するのに、

XDocument doc = XDocument.Load("xml ファイルのパス"); XElement elem = doc.Element("ConfigModel").Element("Csv").Element("Delimiter"); string value = elem.Value;

というようなことをしているとすると、上のコードの変数 value に代入される文字列は "\\t" となります。

"\\t"ReadCsvFile(string filePath, string delimiter) の引数 delimiter に代入したのだと想像してますが、"\t" でないとダメなのは分かりますか?

なので、例えば、

if (value == "\\t") { string delimiter = "\t"; table = ReadCsvFile("csv ファイルのパス", delimiter); }

のようにすれば期待した結果になると思います。お試しください。

投稿2023/04/20 07:10

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

自己解決

空白文字を区切り文字にしたい場合は、
以下のようにダブルクォーテーションで囲い、タブスペースや半角文字などを設定し、

C#側で以下のコードを20行目とし、ダブルクォーテーションを消すというやり方で一旦解決しました。
parser.SetDelimiters(delimiter.Replace(""", ""));

他にも良い方法あるかもしれませんが、
皆様多くのご意見参考になりました。
ありがとうございます。

xml

1<?xml version="1.0" encoding="utf-8"?> 2<ConfigModel> 3 <Csv> 4 <filePath></filePath> 5 <Delimiter>" "</Delimiter> 6 </Csv> 7</ConfigModel>

投稿2023/04/20 07:26

編集2023/04/20 08:15
WHdfghjk

総合スコア12

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

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

退会済みユーザー

退会済みユーザー

2023/04/20 07:49

delimiter.Replace(""", "") というコードは間違っているし、それを直したとしても、<Delimiter>"\t"</Delimiter> から XElement.Value で取得できる文字列は "\"\\t\"" なので、結局ダメなはず。
WHdfghjk

2023/04/20 08:09

説明足らずですいません。 <Delimiter>" "</Delimiter> としたところ再現できました。 delimiter.Replace(""", "") というコードは間違ってるとのことですが、こちらどういうことなのでしょうか。
退会済みユーザー

退会済みユーザー

2023/04/20 09:37

> <Delimiter>" "</Delimiter> としたところ再現できました。 何が再現できたのでしょうか?  > delimiter.Replace(""", "") というコードは間違ってるとのことですが、こちらどういうことなのでしょうか。 「CS8370 機能 '生文字列リテラル' は C# 7.3 では使用できません。11.0 以上の言語バージョンをお使いください。」というエラーになるはず。 XML ファイルを読み込んで、ReadCsvFile(string filePath, string delimiter) の delimiter に代入するところまでのコードを提示してください。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問