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

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

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

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

C#

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

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

Q&A

解決済

1回答

18107閲覧

C# XMLファイル取り込み

King_of_Flies

総合スコア382

XML

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

C#

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

VB.NET

Microsoft Visual Basic .NETのことで、Microsoft Visual Basic(VB6)の後継。 .NET環境向けのプログラムを開発することができます。 現在のVB.NETでは、.NET Frameworkを利用して開発を行うことが可能です。

0グッド

1クリップ

投稿2017/05/23 04:20

編集2017/05/23 07:00

お疲れ様です。
TAKKOです。

C#を使用したXMLファイルの取り込みの件で、質問させていただきます。

C#

1//略 2static void Main(string[] args) 3{ 4 //読み込み 5 FileStream inputStream = new FileStream(@"test.xml", FileMode.Open);//ファイルストリームのインスタンス生成 6 XmlSerializer serializer = new XmlSerializer(typeof(ReadingXML.Audit)); // シリアライザーのインスタンスを生成 7 ReadingXML.Audit model = (ReadingXML.Audit)serializer.Deserialize(inputStream); 8}

xml

1<?xml version="1.0" encoding="UTF-8"?> 2 <Audit xmlns="http://~" 3 xmlns:xsi="http://~" 4 xsi:schemaLocation="http~"> 5 <Version>11.2</Version> 6 <AuditRecord> 7 <hoge>1</hoge>//各要素 8 <huge>1</huge>//各要素 9 </AuditRecord> 10</Audit>

こんな感じでコードを組んで、デバッグをするとReading.Audit model内にはプロパティが格納され、各要素が格納され、値の取得が出来ているのが確認できたのですが、
System.InvalidOperationExceptionが発生していて、
内部メッセージに{"XMLドキュメント(2,4)でエラーが発生しました。"}
と出力されてしまいます。

エラーの行としては
ReadingXML.Audit model = (ReadingXML.Audit)serializer.Deserialize(inputStream);
の部分です。

XMLファイルのAudit VersionをXMLファイル内から削除すると正常に読み込むことが出来るのですが、
コード内で、Audit Versionを無視するような処理は可能でしょうか?

よろしくお願いします。

【追記】
正規

C#

1using System; 2using System.Collections.Generic; 3using System.Linq; 4using System.Text; 5using System.Threading.Tasks; 6using System.IO; 7using System.Xml.Serialization; 8 9namespace ReadingXML 10{ 11 [System.Xml.Serialization.XmlRoot("XML")] 12 public class XML 13 { 14 [System.Xml.Serialization.XmlElement("Audit")] 15 public System.Collections.Generic.List<ReadingXML.Audit> Audit { get;set;} 16 } 17 18 /// <summary> 19 /// XMLファイル内のAudit内の各要素のクラス 20 /// </summary> 21 public class Audit 22 { 23 [System.Xml.Serialization.XmlElement("Version")] 24 public String Version { get; set; } 25 [System.Xml.Serialization.XmlElement("AuditRecord")] 26 public System.Collections.Generic.List<ReadingXML.AuditRecord> AuditRecord { get; set; } 27 } 28 29 /// <summary> 30 /// XMLファイル内のAuditRecord内の各要素のクラス 31 /// </summary> 32 public class AuditRecord 33 { 34 [System.Xml.Serialization.XmlElement("Audit_Type")] 35 public String Audit_Type { get; set; } 36 37 //以下12要素(略 38 } 39 40 class Program 41 { 42 static void Main(string[] args) 43 { 44 string filePath = @"test.xml"; 45 //読み込み 46 FileStream inputStream = new FileStream(filePath, FileMode.Open);//ファイルストリームのインスタンス生成 47 XmlSerializer serializer = new XmlSerializer(typeof(ReadingXML.Audit)); // シリアライザーのインスタンスを生成 48 ReadingXML.Audit model = (ReadingXML.Audit)serializer.Deserialize(inputStream); 49 } 50 } 51} 52

xml

1<?xml version="1.0" encoding="UTF-8"?> 2 <Audit xmlns="http://~" 3 xmlns:xsi="http://~" 4 xsi:schemaLocation=""> 5 <Version>11.2</Version> 6<AuditRecord><Audit_Type>1</Audit_Type> 7</AuditRecord> 8<AuditRecord><Audit_Type>1</Audit_Type></AuditRecord>//Audit_Type以外にも要素はあるが略 9<AuditRecord><Audit_Type>1</Audit_Type></AuditRecord> 10<AuditRecord><Audit_Type>1</Audit_Type></AuditRecord> 11<AuditRecord><Audit_Type>1</Audit_Type></AuditRecord> 12</Audit>

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

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

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

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

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

guest

回答1

0

ベストアンサー

こんにちは。

XMLSerializerは「シリアライザ」です。
シリアライザというのは、C#内の「オブジェクト」とC#外の「XML」を一対一に対応させるためのものです。なので、マッピング先のクラスの構造が異なっていれば当然デシリアライズ操作は失敗します。
シリアライザを利用するのであれば、マッピング対象のクラス側(ReadingXML.Audit)にVersionプロパティを追加する必要があります。

XMLを「データソース」と見なしてそれを読み込む用途であれば、XElementクラスとその周辺(System.Xml.Linq名前空間)の利用をオススメします。こちらはXMLの「解析」「読み込み」を行うものなので、マッピング操作そのものを自分で書くことができます。


追記:

Linq to XMLを使用してXMLを読み込むサンプルを書いてみました。
丸ごとコピーでコンパイル/実行可能なようにしてあります。

質問のXMLデータをそのまま使用しています。が、XMLを書く時はインデントルールを決めて間違いなく記述することで、全体の構造を把握しやすくなります。

xml

1<?xml version="1.0" encoding="UTF-8"?> 2<Audit xmlns="http://xxx" 3 xmlns:xsi="http://yyy" 4 xsi:schemaLocation="zzz"> 5 <Version>11.2</Version> 6 <AuditRecord> 7 <Audit_Type>1</Audit_Type> 8 </AuditRecord> 9 <AuditRecord> 10 <Audit_Type>1</Audit_Type> 11 </AuditRecord> 12 <AuditRecord> 13 <Audit_Type>1</Audit_Type> 14 </AuditRecord> 15 <AuditRecord> 16 <Audit_Type>1</Audit_Type> 17 </AuditRecord> 18 <AuditRecord> 19 <Audit_Type>1</Audit_Type> 20 </AuditRecord> 21</Audit>

マッピングクラスは不要なので、AuditRecordクラスしか残りませんでした。
他にも必要なデータがあれば、Root(xml変数)から好きなように掘ってください。

csharp

1using System; 2using System.Linq; 3using System.Xml.Linq; 4 5namespace ReadingXML 6{ 7 class Program 8 { 9 static void Main(string[] args) 10 { 11 var filePath = @"test.xml"; 12 13 // xmlをロード 14 var xml = XElement.Load(filePath); 15 var ns = xml.GetDefaultNamespace(); // namespace 16 17 // AuditRecordエレメントを全て取得 18 var xmlRecords = xml.Elements(ns + "AuditRecord"); 19 20 // AuditRecordオブジェクトに変換 21 var records = xmlRecords.Select(record => new AuditRecord 22 { 23 Audit_Type = record.Element(ns + "Audit_Type").Value, 24 // XXX = record.Element(ns + "xxx").Value, 25 // YYY = ... 26 }).ToList(); 27 28 // 出力テスト 29 foreach (var record in records) 30 Console.WriteLine(record.Audit_Type); // 1, 1, 1, 1, 1 31 } 32 33 public class AuditRecord 34 { 35 public String Audit_Type { get; set; } 36 37 // public String XXX { get; set; } 38 39 // public String YYY... 40 } 41 } 42}

投稿2017/05/23 04:30

編集2017/05/23 08:30
tamoto

総合スコア4105

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

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

King_of_Flies

2017/05/23 04:47

例えばこんな感じで、クラスがあります。 namespace RedingXML { [System.Xml.Setialization.XmlRoot("Root")] public class Root { [System.Xml.Serialization.xmlElement("Version")] public String Version {get;set;} [System.Xml.Serialization.XmlElement("AuditRecord")] public System.Collections.Generic.List<ReadingXML.AuditRecord> Au { get; set; } } public class AuditRecord { //AuditRecord内の各要素 略 } } これは既にVersionが要素として宣言されていると思うのですが、なにがダメなのでしょうか? P.S. xmlのファイルに間違いがありました。 各要素 </Audit > が最後にあるので、Audit タグで全ての要素が囲まれているようです。
King_of_Flies

2017/05/23 04:51

質問のXMLファイルの中身を修正しました。
tamoto

2017/05/23 05:19

コメントのコードがそもそも動くコードになっていないように見えます。typoとか。 コメントの断片では「Root」というマッピングクラスが存在しているようですが、質問のコードでシリアライザに紐つけているのは「Audit」クラスではないですか?
King_of_Flies

2017/05/23 05:55

シリアル化について調べても全く理解できなかったため 質問を変えさせていただきます。 FileStream inputStream = new FileStream(@"test.xml", FileMode.Open);//ファイルストリームのインスタンス生成 という処理でxmlファイルを読み込んでいると思いますが、 この読み込んだxmlファイルのうち、指定の行を削除する方法はありますか?
tamoto

2017/05/23 06:42 編集

えーと……削除したい行数が定まっているなら、ファイルを文字列として読み込ませるときに指定行をスキップして、その後StringReaderに入れるとかで実現できると思いますが、普通のシリアライズや解析処理よりも格段に難易度が高いので全くオススメしませんよ。。 可能であれば、質問に、 「読み込みたいXMLの本当に正しいデータ構造(データそのものは不要)」 「読み込む先のマッピングクラスの本当に正しいデータ構造」 を記載してほしいです。現状ではサンプルコードを示すことすらできないので説明が難しいです。
King_of_Flies

2017/05/23 07:00

追記から下のコードを追記しました。 一部省略していますが、今のところこのような形です。
tamoto

2017/05/23 08:36

コード記載ありがとうございます。そのまま利用できるコードで非常に助かりました。 回答の方に解析のサンプルコードを追記しましたのでご確認下さい。 大幅に変更を加えているので、質問からは読み取れない要件を満たしていない部分が発生している可能性がありますが、ご了承下さい。
King_of_Flies

2017/05/23 08:52

>そのまま利用できるコードで非常に助かりました。 クラスが大分削除されていたのですが、分かりにくくなかったですか? すいませんでした;; あと、ありがとうございます。 まだ、コードの解析から初めてますので、 あす、改めて結果報告いたします。
tamoto

2017/05/23 08:57

コンパイル/実行する際に必要なコードは揃っていたので、「質問と同じことを実現するコードを書けば良い」と回答の方針が定まることがありがたいのですよ。まあ、それで省略された部分に関しての追加質問を受けることになると相変わらず困ってしまいますが。 ゆっくりお待ちしていますね。
King_of_Flies

2017/05/23 09:02

省略とかしてたわけではなく、 本当に実装したいことっていうのは、 XMLファイルを読み込んで、CSVファイル形式に変換し、出力するってことですね。 まだ実装途中で、XMLファイルの読み込みからてこずっていたので、 その部分だけ切り出して質問した経緯はあります。
King_of_Flies

2017/05/24 00:14

今朝、動作確認したところ、 PDB ファイルを開けないか、ファイルが見つかりません。というエラーで、 そもそもConsole.Writeの出力が出来なかったため、再調査しています。
King_of_Flies

2017/05/24 00:17

あ、でも、Record内には期待されるobjectが格納されていました!
King_of_Flies

2017/05/24 00:23

おそらく、今出てるエラーは、今回の問題とは別問題ですね
King_of_Flies

2017/05/24 00:30

console出力できました! あとはこいつをCSVに出力するだけです! 頑張ってみます!
King_of_Flies

2017/05/25 07:48

すいません、解決していたのにBAつけるのを忘れていました。^^; ありがとうございました。
hidori

2017/05/25 10:57

>XMLファイルを読み込んで、CSVファイル形式に変換し、出力するってことですね。 であれば、やはり XmlSerializer なんか使わずに XDocument, XElement 辺りを使った方がはるかに簡単ですよ。
King_of_Flies

2017/05/26 01:55

アドバイスありがとうございます。 一応、既にプログラムは完成してしまった後ですので、 リファレンスだけ調べさせていただきます。
tamoto

2017/05/26 03:11

この回答のとおり、XmlSerializerとLinq to XMLは「用途が異なる」、そして今回の要件にはLinq to XMLが適していた、ということなので、今後似たような要件が発生した際には、また用途に合わせて使い分けて下さいということですね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問