2

さて、ここに行きます。アプリに読み込んでいる一連のXMLドキュメントがあります。私の小さなテストでは、XMLドキュメントで指定されたスキーマに対して検証するリーダーを作成しました。次のコードを使用すると、非常にうまく機能します。

// Set the validation settings.
XmlReaderSettings settings = new XmlReaderSettings();
settings.ValidationType = ValidationType.Schema;
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);

// Create the XmlReader object.
XmlReader reader = XmlReader.Create("xml/note.xml", settings);

// Load the XDocument from the reader
XDocument loadedDoc = XDocument.Load(reader);

これで、XMLドキュメントが正しく読み込まれ、発生した検証エラーはすべてコールバックによって処理されます。

ただし、要素に対してGetSchemaInfo()を呼び出して要素に関するスキーマ情報を取得したい場合は、nullが与えられます。ここでのこの質問は、オーバーロードされたValidateメソッドの使用について説明していますが、何かが足りない場合を除いて、この状況には実際には当てはまりません。

インラインスキーマを使用してスキーマ情報をXDocにロードすることは可能ですか、それとも別の方法で行う必要がありますか?

4

1 に答える 1

0

私自身の質問に対する私の答えをチェックしてください。

コード ブロックの後の最初の段落は重要ですが、基本的にSchemaInfo そこにはありますが、検証コールバックのまで追加されません。

私が使用した回避策は基本的に次のとおりです (注: このコードは、XML を直接ロードして を呼び出すときにテストされ、機能しますXDocument.ValidateXmlSchemaSet、前提はXmlReaderおよびインライン スキーマと同じまたは類似している必要があります):

List<XElement> errorElements = new List<XElement>();

serializedObject.Validate((sender, args) =>
{
    var exception = (args.Exception as XmlSchemaValidationException);

    if (exception != null)
    {
        var element = (exception.SourceObject as XElement);

        if (element != null)
            errorElements.Add(element);
     }

});

foreach element in errorElements
{
    var si = element.GetSchemaInfo; 

    // do something with SchemaInfo
}

SchemaInfo私は要素のキャプチャのみを試みていたため、asキャストとnullチェックが行われましたが、これは他のノードタイプでも機能するはずですAttributes(ただし、テストされていないため、間違っている可能性があります)。

匿名のデリゲートの代わりに特定のコールバック メソッドを使用する場合はerrorElements、クラス レベルのフィールドである必要があり、検証が完了した後に必要なことを行うことができます (ここでも、テストされていないメソッドを追加します) 鬼ごっこ)。

public class SomeClass
{

    List<XElement> errorElements = new List<XElement>();

    public void Load()
    {

        // Set the validation settings.
        XmlReaderSettings settings = new XmlReaderSettings();
        settings.ValidationType = ValidationType.Schema;
        settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
        settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
        settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
        settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
        settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);

        // Create the XmlReader object.
        XmlReader reader = XmlReader.Create("xml/note.xml", settings);

        // Load the XDocument from the reader
        XDocument loadedDoc = XDocument.Load(reader);

        // do something with errorElements

    }

    public void ValidationCallBack(object sender, ValidationEventArgs e)
    {
        var exception = (args.Exception as XmlSchemaValidationException);

        if (exception != null)
        {
            var element = (exception.SourceObject as XElement);

            if (element != null)
                errorElements.Add(element);
         }

    }

}

すべてのIXSchemaInfoノードを必要とするというコメントに応えて、ノードが失敗したか合格したかに関係なく、検証後にスキーマ情報が XElement に追加されるため、失敗したノードのリストを保持する必要がないため、要件は実際には簡単になります。ノード。これを行うことができるはずです:

public void Load()
{

    // Set the validation settings.
    XmlReaderSettings settings = new XmlReaderSettings();
    settings.ValidationType = ValidationType.Schema;
    settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
    settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
    settings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
    settings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
    settings.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);

    // Create the XmlReader object.
    XmlReader reader = XmlReader.Create("xml/note.xml", settings);

    // Load the XDocument from the reader
    XDocument loadedDoc = XDocument.Load(reader);

    foreach (var node in loadedDoc.Descendants())
    {
        var si = node.GetSchemaInfo();
    }

}

上記の例はあなたのXElements にのみアクセスしますXDocumentが、それは私の要点を説明するためのものです。読み込みが完了し、xml が検証されると、スキーマ情報がそこにあるはずです。

于 2012-08-23T08:38:05.030 に答える