XML 文字列とスキーマをロードして関数に渡しました。スキーマに対して XML を正しく検証していますが、常に最初の無効な要素のスコープで検証を停止します。無効なデータ、続行、無効/欠落した属性、続行、ただし無効な要素、停止し、そのスコープ内でそれ以上検証されません。
スキーマは次のとおりです。
<?xml version="1.0" encoding="utf-16"?>
<xs:schema xmlns:b="http://schemas.microsoft.com/BizTalk/2003" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="root">
<xs:complexType>
<xs:sequence>
<xs:element name="items">
<xs:complexType>
<xs:sequence maxOccurs="unbounded">
<xs:element name="foo">
<xs:complexType>
<xs:sequence>
<xs:element name="bar" type="xs:integer" />
<xs:element name="bat" type="xs:integer" />
</xs:sequence>
<xs:attribute name="attr1" type="xs:integer" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
Xml は次のとおりです。
<root>
<items>
<foo attr1='1'>
<invalid0>1</invalid0>
<invalid1>b</invalid1>
</foo>
<foo attr1='1'>
<invalid2>b</invalid2>
<bat>b</bat>
</foo>
<foo attr1='1'>
<bar>3</bar>
</foo>
<invalidFoo attr1='1'>
<bar>d</bar>
<bat>2</bat>
</invalidFoo>
<foo>
<bar>3</bar>
<bat>q</bat>
</foo>
</items>
</root>
したがって、この例で何が起こるかというと、バリデーターは最初に到達して<foo>
確認し、それ以上<invalid0>
検証しないため、 . Validator は次の.<foo>
<invalid1>
<foo>
次に<foo>
、そこに<invalid2>
属さない があり、<bat>
要素の無効なデータ (整数ではなく文字列) をキャッチしようとしないことがわかります。そのまま次に進みます<foo>
次の要素に移動し<foo>
、欠落に関するエラーをスローして、次の要素に移動します。クールです。<bat>
<foo>
当然のことながら、内部では<invalidFoo>
検証を行いません。<invalidFoo>
なぜなら、もちろん、<invalidFoo>
?
私にとっての難点は、この時点でバリデーターが後続のすべての<foo>
兄弟要素の検証を停止するため、最後の無効なデータが<bat>
キャッチされないことです。だから今、私が尋ねている理由は、私が検証を使用している方法は、すべてのエラーを (または少なくともできるだけ多く) キャッチしてユーザーに戻そうとするからです。実際のコードで最初に行ったテストは、次のようなものでした。
<root>
<items>
<invalidFoo attr1='1'>
<invalid0>1</invalid0>
<invalid1>b</invalid1>
</invalidFoo>
<foo attr1='1'>
<invalid2>b</invalid2>
<bat>b</bat>
</foo>
<foo attr1='1'>
<bar>3</bar>
</foo>
<invalidFoo attr1='1'>
<bar>d</bar>
<bat>2</bat>
</invalidFoo>
<foo>
<bar>3</bar>
<bat>q</bat>
</foo>
</items>
</root>
そのため、バリデーターは最初<invalidFoo>
にそれを見て停止しました。長い間、何らかの理由で検証が常に最初のエラーで停止していると想定していました。有効な<foo>
バックを追加するまで、他の無効なデータエラーを連続してキャッチして蓄積し始めました。しかし、無効な要素タグ名にヒットするとすぐに、すべての兄弟/子レベルの検証がスキップされます。属性やデータではなく、無効な要素でのみ発生します。
今、私はこれが正しいか間違っていると言っているのではありません.これが正しいか間違っているかを尋ねています. 特に兄弟要素の場合、バリデーターは続行する必要がありますか? それとも、前の要素が無効であることに基づいて、基本的に要素のリスト全体を無効にする必要がありますか? この状況で Xml Schema Validator に期待される動作は何ですか?
これはすべて、次の C# コードを使用して行われています (期待どおりに動作します)。
public static void ValidateAgainstSchema(string XMLSourceDocument, XmlSchemaSet validatingSchemas)
{
if (validatingSchemas == null)
{
throw new ArgumentNullException("In ValidateAgainstSchema: No schema loaded.");
}
string errorHolder = string.Empty;
ValidationHandler handler = new ValidationHandler();
XmlReaderSettings settings = new XmlReaderSettings();
settings.CloseInput = true;
settings.ValidationType = ValidationType.Schema;
settings.ValidationEventHandler += new ValidationEventHandler(handler.HandleValidationError);
settings.Schemas.Add(validatingSchemas);
settings.ValidationFlags =
XmlSchemaValidationFlags.ReportValidationWarnings |
XmlSchemaValidationFlags.ProcessIdentityConstraints |
XmlSchemaValidationFlags.ProcessInlineSchema |
XmlSchemaValidationFlags.ProcessSchemaLocation;
StringReader srStringReader = new StringReader(XMLSourceDocument);
using (XmlReader validatingReader = XmlReader.Create(srStringReader, settings))
{
while (validatingReader.Read()) { }
}
if (handler.MyValidationErrors.Count > 0)
{
foreach (String messageItem in handler.MyValidationErrors)
{
errorHolder += messageItem;
}
throw new XmlSchemaValidationException(errorHolder);
}
}
検証イベント ハンドラーはエラーをキャッチし、IList<string>
後でまとめて表示するためにそれらを に追加します。