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

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

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

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

C#

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

Q&A

解決済

2回答

3032閲覧

System.Xml.XmlException: Root element is missingについて

void_390duke

総合スコア7

XML

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

C#

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

1グッド

0クリップ

投稿2020/09/12 15:27

現在このようなコードを作っています

c#

1using System; 2using System.IO; 3using System.IO.Compression; 4using System.Linq; 5using System.Xml.Linq; 6 7namespace XMLTutorial20200912 8{ 9 class Program 10 { 11 static void Main(string[] args) 12 { 13 string xmldoc = 14 "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>" + 15 "<PCROOT>" + 16 "<PInfo Key=\"0\">" + 17 "oll" + 18 "</PInfo>" + 19 "<PInfo Key=\"0\">" + 20 "tll" + 21 "</PInfo>" + 22 "<PInfo Key=\"1\">" + 23 "ools" + 24 "</PInfo>" + 25 "<PInfo Key=\"1\">" + 26 "oljl" + 27 "</PInfo>" + 28 "<PInfo Key=\"1\">" + 29 "ollj" + 30 "</PInfo>" + 31 "</PCROOT>"; 32 33 XDocument xdoc = XDocument.Parse(xmldoc); 34 Console.WriteLine(xdoc.ToString()); 35 GZipCompress(xdoc, @"pc1.gz"); 36 XDocument xdocloaded= GZipDecompress(@"pc1.gz"); 37 38 var key0 = xdocloaded.Element("PCROOT").Elements("PInfo").Where(p => p.Attribute("Key").Value == "1"); 39 foreach(var i in key0) 40 { 41 Console.WriteLine(i.Value); 42 } 43 Console.ReadKey(); 44 } 45 public static void GZipCompress(XDocument xdin, string gzpath) 46 { 47 using (var memStream = new MemoryStream()) 48 { 49 xdin.Save(memStream, SaveOptions.None); 50 using (var fout = File.Create(gzpath)) 51 { 52 using (var gzout = new GZipStream(fout, CompressionMode.Compress)) 53 { 54 memStream.WriteTo(gzout); 55 } 56 } 57 } 58 } 59 public static XDocument GZipDecompress(string gzpath) 60 { 61 using (var fin = new FileStream(gzpath, FileMode.Open, FileAccess.Read, FileShare.Read)) 62 { 63 using (var fout = new MemoryStream()) 64 { 65 using (var gzin = new GZipStream(fin, CompressionMode.Decompress)) 66 { 67 gzin.CopyTo(fout); 68 var res = XDocument.Load(fout);//here 69 return res; 70 } 71 } 72 } 73 } 74 } 75}

このコードの解凍部分(hereの部分です)でタイトルのエラーが発生してしまいます。元の文字列にはROOTととらえられる部分が含まれているのですが、どこを修正すべきなのでしょうか。もしくはGZ圧縮で改変が起こってしまったのでしょうか。(そのようなことはないとは思いますが)
文字列をXDocumentにした後、コンソール出力してみましたが、入力したものにインデントが入ったものがそのまま出力されていました。

TN8001👍を押しています

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

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

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

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

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

退会済みユーザー

退会済みユーザー

2020/09/13 00:27

開発環境を書けませんか? OS、.NET Framework か Core のどっちかとそのバージョン、Visual Studio のバージョンなど。
TN8001

2020/09/13 03:04

質問コードではMemoryStreamを挟む意味がないように思いますが、何か書かれていない処理があるのでしょうか?
void_390duke

2020/09/13 07:37

OSはWindows 10 Homeのversion1909で.Net Framework4.7.2を使用しています。 MemoryStreamを挟まなくてもできるのであればそちらのほうを教えていただけるとありがたいです。
guest

回答2

0

ベストアンサー

こうでいいと思うのですが、どうでしょうか。

cs

1using System; 2using System.IO; 3using System.IO.Compression; 4using System.Linq; 5using System.Text; 6using System.Xml; 7using System.Xml.Linq; 8 9namespace Questions291429 10{ 11 class Program 12 { 13 static void Main() 14 { 15 var xmldoc = 16@"<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?> 17<PCROOT> 18 <PInfo Key=""0"">oll</PInfo> 19 <PInfo Key=""0"">tll</PInfo> 20 <PInfo Key=""1"">ools</PInfo> 21 <PInfo Key=""1"">oljl</PInfo> 22 <PInfo Key=""1"">ollj</PInfo> 23</PCROOT>"; 24 25 var xdoc = XDocument.Parse(xmldoc); 26 Console.WriteLine(xdoc.ToString()); 27 GZipCompress(xdoc, @"pc1.gz"); 28 29 var xdocloaded = GZipDecompress(@"pc1.gz"); 30 var key0 = xdocloaded.Element("PCROOT") 31 .Elements("PInfo") 32 .Where(p => p.Attribute("Key").Value == "1"); 33 34 foreach(var i in key0) 35 { 36 Console.WriteLine(i.Value); 37 } 38 39 Console.ReadKey(); 40 } 41 42 static void GZipCompress(XDocument xdin, string gzpath) 43 { 44 using(var fs = File.Create(gzpath)) 45 using(var gs = new GZipStream(fs, CompressionMode.Compress)) 46 // しなくても読めたが中のファイルにBOMが付くのが気持ち悪い場合 47 //using(var writer = new XmlTextWriter(gs, new UTF8Encoding(false))) 48 { 49 //xdin.Save(writer); 50 xdin.Save(gs); 51 } 52 } 53 54 static XDocument GZipDecompress(string gzpath) 55 { 56 using(var fs = new FileStream(gzpath, FileMode.Open, FileAccess.Read, FileShare.Read)) 57 using(var gs = new GZipStream(fs, CompressionMode.Decompress)) 58 { 59 return XDocument.Load(gs); 60 } 61 } 62 } 63}

投稿2020/09/13 07:46

編集2023/07/23 05:35
TN8001

総合スコア9396

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

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

void_390duke

2020/09/13 07:58

簡潔なコードの提案ありがとうございました。私はGZipStreamについて理解がほとんどなかったのですが、動きとしては、コンストラクタに渡したストリームに、自分を圧縮/解凍したものを渡すという動きをしている(ように見える)という認識でよろしいですか?
TN8001

2020/09/13 08:09

はい。そんな感じでよろしいんじゃないでしょうか。 void_390dukeさんと同じく私もよくわかってません^^; あまりにも違ったら誰かが突っ込んでくれると思います^^;
guest

0

どこを修正すべきなのでしょうか。

GZipDecompress メソッドの // here の行の前に、MemoryStream.Seek メソッドで fout の Position を 0 にすればよさそうです。

イメージ説明

結果は:

<PCROOT> <PInfo Key="0">oll</PInfo> <PInfo Key="0">tll</PInfo> <PInfo Key="1">ools</PInfo> <PInfo Key="1">oljl</PInfo> <PInfo Key="1">ollj</PInfo> </PCROOT> ools oljl ollj

投稿2020/09/13 01:06

編集2020/09/13 01:08
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

void_390duke

2020/09/13 07:39

ストリームの読み取り部分をリセットする必要があったのですね。勝手に作ったらデフォルトで初めからになるものかと考えておりました。
退会済みユーザー

退会済みユーザー

2020/09/13 08:11

gzin.CopyTo(fout); で MemeoryStream に読み込んだ際 MemoryStream の Position が末尾になるようです。なので、XDocument.Load(fout); の際 Position 0 にもどしてから XDocument に load しなければならないということです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問