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

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

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

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

C#

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

XSD

XSDは一般的に、XMLドキュメントの特定のタイプの表現を含んだ、W3C XML Schemaフォーマットで書かれたドキュメントを指します。

Q&A

解決済

1回答

2274閲覧

[スキーマチェックに関する質問]xsdによってxmlを検証し、複数エラーメッセージを返却値として受け取りたい

k-y

総合スコア5

XML

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

C#

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

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

XSD

XSDは一般的に、XMLドキュメントの特定のタイプの表現を含んだ、W3C XML Schemaフォーマットで書かれたドキュメントを指します。

0グッド

0クリップ

投稿2020/04/30 02:22

編集2020/04/30 02:52

はじめに

初めまして、エンジニア歴1年目で最近C#を触り始めたものです。
早速ですが、1週間ほど悩んで解決できないことがあるので質問させていただきます。

使用環境及び言語

Microsoft Visual Studio 2019でC#を使用しております。

実現したいこと

実現したいこととしましては下記になります。

1.xsdによるxmlの検証(これはおそらくできている)
2.エラーが出た場合、エラーメッセージをArrayList型に設定し、返却値として渡す(すべてのエラーを設定したい)

現在の状況

xsdによってxmlを検証し、コンソールにエラーメッセージを出すところまでは調べれば出てきたのですが、
・複数のエラーが起きた時に最初のエラーのみが表示される点
・実際にはコンソールに表示するのではなく、エラーメッセージをArrayList型に設定し返却値とする点
以上の二点が現在実装できていない状況です。

以下、現在のソースコードです。(xmlファイル、xsdファイルについては適当なものをローカルに保存し、ファイルパスを渡しています)

c#

1 using System; 2 using System.IO; 3 using System.Xml; 4 using System.Xml.Schema; 5 6 private ArrayList xmlCheck(string xmlFilePath, string xsdFilePath) 7 { 8 //xsdファイルパスから型変換 9 XmlTextReader reader = new XmlTextReader(xsdFilePath); 10 XmlSchema xmlschema = XmlSchema.Read(reader, ValidationCallback); 11 XmlSchemaSet schemaSet = new XmlSchemaSet(); 12 schemaSet.Add(xmlschema); 13 14 // XMLファイルとXSDファイルを設定する。 15 XmlDocument xmlDocument = new XmlDocument(); 16 xmlDocument.Schemas.Add(schemaSet); 17 xmlDocument.Load(xmlFilePath); 18 try{ 19 //スキーマチェック 20 xmlDocument.Validate(ValidationEventHandler); 21 22 //仮の返却値 23 return null; 24 25 //xsd等の規約に対する例外?(そもそも必要?) 26 }catch(XmlSchemaValidationException ex) 27 { 28 //エラーあり(true)を返却 29 return ex; 30 } 31 } 32 33 private void ValidationCallback(object sender, ValidationEventArgs e) 34 { 35 switch (e.Severity) 36 { 37 case XmlSeverityType.Error: 38 Console.WriteLine("Error:" + e.Message); 39 break; 40 case XmlSeverityType.Warning: 41 Console.WriteLine("Warning:" + e.Message); 42 break; 43 } 44 } 45 46 private void ValidationEventHandler(object sender, ValidationEventArgs e) 47 { 48 switch(e.Severity) 49 { 50 case XmlSeverityType.Error: 51 //errorInfoList.Add(e.Message); 52 53 Console.WriteLine("Error:" + e.Message); 54 break; 55 case XmlSeverityType.Warning: 56 Console.WriteLine("Warning:" + e.Message); 57 break; 58 } 59 }

終わりに

以上が私の質問になります。解答だけでなく分かりにくい点や、もっと情報が欲しい場合等も対応したいと思うので、そういった指摘でもございましたら是非よろしくお願いします。

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

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

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

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

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

Zuishin

2020/04/30 03:00 編集

Validate は間違っているときに例外を起こします。例外が起きたらそれ以上の処理はできません。なので、この方法ですべてのエラーを列挙することはできません。 一つのエラーによって他の部分に問題が発生することがあるので、一つ一つ修正するのが良いと思います。それで賄いきれないくらいエラーがあまりに多く発生するようであれば、XML を使うという方法自体を見直す必要があるかもしれません。それが選べないのであれば、自分で構文チェッカを書くか、サードパーティーの構文チェッカを探す必要があるかもしれません。その場合、予算や使用目的なども書いておくと、情報があるかもしれません。
k-y

2020/04/30 03:06

Zuishinさん ご解答ありがとうございます。 ・XML を使うという方法自体を見直す必要があるかもしれません。→選べません… ・サードパーティーの構文チェッカを探す必要があるかもしれません。→調べてみます ps:→思い付きですが、ノード毎に繰り返しValidate メソッド使用するのはどうかと思ったので試してみます。("Validate は間違っているときに例外を起こします。例外が起きたらそれ以上の処理はできません。なので、この方法ですべてのエラーを列挙することはできません。"とあることからダメそうですが)
Zuishin

2020/04/30 03:08

スキーマがルートから指定しているのでなければできるかもしれませんが、無理じゃないかなと思います。
guest

回答1

0

ベストアンサー

ちょっと制限があるかもしれませんが以下のようにする事で、複数個のXSDエラーを取得することができました。
~~ちょっとした制限っていうのは、XML側でXSDを指定していると多分だめだという事です。~~大丈夫そうでした。
やり方としては以下のようにXMLをXSD無しで、ロードした後Validationです。

cs

1using System; 2using System.Collections.Generic; 3using System.Linq; 4using System.Text; 5using System.Threading.Tasks; 6using System.Xml; 7using System.Xml.Schema; 8using System.Xml.XPath; 9 10namespace XmlSchemaValidate { 11 class Program { 12 static void Main(string[] args) { 13 // XMLファイルとXSDファイルを設定する。 14 XmlDocument document = new XmlDocument(); 15 document.Load("test.xml"); 16 17 XmlTextReader reader = new XmlTextReader("test.xsd"); 18 XmlSchema xmlschema = XmlSchema.Read(reader, ValidationCallback); 19 XmlSchemaSet schemaSet = new XmlSchemaSet(); 20 schemaSet.Add(xmlschema); 21 document.Schemas.Add(schemaSet); 22 23 try { 24 ValidationEventHandler eventHandler = new ValidationEventHandler(ValidationEventHandler); 25 document.Validate(eventHandler); 26 } catch (Exception ex) { 27 Console.WriteLine(ex.Message); 28 } 29 Console.Read(); 30 } 31 static void ValidationEventHandler(object sender, ValidationEventArgs e) { 32 switch (e.Severity) { 33 case XmlSeverityType.Error: 34 Console.WriteLine("Error: {0}", e.Message); 35 break; 36 case XmlSeverityType.Warning: 37 Console.WriteLine("Warning {0}", e.Message); 38 break; 39 } 40 } 41 static void ValidationCallback(object sender, ValidationEventArgs e) { 42 //こっちは動かない 43 } 44 } 45} 46

XMLとXSDはここのものをちょっと変更しただけです。

xml

1<bookstore xmlns="http://www.contoso.com/books"> 2 <book genre="autobiography" publicationdate="1981-03-22"> 3 <title>The Autobiography of Benjamin Franklin</title> 4 <author> 5 <first-name>Benjamin</first-name> 6 <last-name>Franklin</last-name> 7 </author> 8 <price>8.99</price> 9 </book> 10 <book genre="novel" publicationdate="1967-11-17" ISBN="0-201-63361-2"> 11 <title>The Confidence Man</title> 12 <authorr> 13 <first-name>Herman</first-name> 14 <last-name>Melville</last-name> 15 </authorr> 16 <price>11.99</price> 17 </book> 18 <books genre="philosophy" publicationdate="1991-02-15" ISBN="1-861001-57-6"> 19 <title>The Gorgias</title> 20 <author> 21 <name>Plato</name> 22 </author> 23 <price>9.99</price> 24 </books> 25</bookstore>

xsd

1<?xml version="1.0" encoding="utf-8"?> 2<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.contoso.com/books" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 3 <xs:element name="bookstore"> 4 <xs:complexType> 5 <xs:sequence> 6 <xs:element maxOccurs="unbounded" name="book"> 7 <xs:complexType> 8 <xs:sequence> 9 <xs:element name="title" type="xs:string" /> 10 <xs:element name="author"> 11 <xs:complexType> 12 <xs:sequence> 13 <xs:element minOccurs="0" name="name" type="xs:string" /> 14 <xs:element minOccurs="0" name="first-name" type="xs:string" /> 15 <xs:element minOccurs="0" name="last-name" type="xs:string" /> 16 </xs:sequence> 17 </xs:complexType> 18 </xs:element> 19 <xs:element name="price" type="xs:decimal" /> 20 </xs:sequence> 21 <xs:attribute name="genre" type="xs:string" use="required" /> 22 <xs:attribute name="publicationdate" type="xs:date" use="required" /> 23 <xs:attribute name="ISBN" type="xs:string" use="required" /> 24 </xs:complexType> 25 </xs:element> 26 </xs:sequence> 27 </xs:complexType> 28 </xs:element> 29</xs:schema>

投稿2020/05/16 11:36

編集2020/05/16 13:49
Hey_CH

総合スコア437

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

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

k-y

2020/05/18 03:00 編集

ありがとうございます。早速試してみます。因みに、リストにして返却する云々は解決しました。残りは複数エラーですね。 そこ辺りも含めて、今週に質問自体を更新します。
k-y

2020/05/22 02:59

Console.WriteLine("Error:" + e.Message);→Console.WriteLine("Error: {0}", e.Message); で複数エラーをコンソールに表示できるんですね。 ValidationEventHandlerでe.Messageをエラーリストに一つしか格納できないんですが、そこは自力で何とかできるかもなのでやってみます。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問