2015-05-28 40 views
2

我在F#中有一些代码来验证针对模式的XML。该代码是如下:FSI缓存不需要的东西?

module IA.HelperScripts.ValidateXmlSchema 
open System.IO 
open System.Xml 
open System.Xml.Schema 

let dictionary = __SOURCE_DIRECTORY__ 
let solutionPath = dictionary.Substring(0, dictionary.LastIndexOf('\\', dictionary.LastIndexOf('\\') - 1)) 
let schemaFolder = solutionPath + "\\Schemas" 
let errorMessages = new System.Text.StringBuilder() 
let schemas = new XmlSchemaSet() 

let LoadSchema (schemaPath : string) (schemas : XmlSchemaSet) = 
    use stream = new StreamReader(schemaPath) 
    use xmlReader = XmlReader.Create(stream) 
    let schema = XmlSchema.Read(xmlReader, null) 
    schemas.Add(schema) 

let Validate (xmlPath : string) = 
    for schemaPath in Directory.GetFiles(schemaFolder) do 
     LoadSchema schemaPath schemas |> ignore 

    let settings = new XmlReaderSettings() 
    settings.Schemas <- schemas 
    settings.ValidationType <- ValidationType.Schema 
    settings.ValidationEventHandler.AddHandler(fun o (e: ValidationEventArgs) -> 
     errorMessages.AppendFormat("{0} at position {1} of line {2}.", e.Message, e.Exception.LinePosition, e.Exception.LineNumber).AppendLine() |> ignore) 

    use xmlStream = new StreamReader(xmlPath) 
    use xmlReader = XmlReader.Create(xmlStream, settings) 
    let document = new XmlDocument() 
    document.Load(xmlReader) |> ignore 

    let result = errorMessages.ToString() 

    match result with 
    | r when r.Length > 0 -> printfn "Error: \r\n%s" result 
    | _ -> printfn "Validation Passed" 

我有另一个FSX文件,其中负载以上FS文件,并执行验证功能。代码如下:

#load "ValidateXmlSchema.fs" 
open System.Reflection 
open System.Collections.Generic 


fsi.ShowDeclarationValues <- false 

IA.HelperScripts.ValidateXmlSchema.Validate @"D:\t\IA\XmlForValidation.xml" 

当我选择所有和Alt + Enter时,它每次都能正常工作。第一次运行的所有脚本文件后,然后我就选择最后一行调用验证功能,它失败,以下错误:

System.Xml.Schema.XmlSchemaValidationException: The global element ' http://tempuri.org/BaseSchema:PartnerFeed ' has already been declared. at System.Xml.Schema.XmlSchemaValidator.SendValidationEvent(XmlSchemaValidationException e, XmlSeverityType severity) at System.Xml.Schema.XmlSchemaValidator.SendValidationEvent(XmlSchemaException e) at System.Xml.Schema.XmlSchemaValidator.RecompileSchemaSet() at System.Xml.Schema.XmlSchemaValidator.Init() at System.Xml.Schema.XmlSchemaValidator..ctor(XmlNameTable nameTable, XmlSchemaSet schemas, IXmlNamespaceResolver namespaceResolver, XmlSchemaValidationFlags validationFlags) at System.Xml.XsdValidatingReader.SetupValidator(XmlReaderSettings readerSettings, XmlReader reader, XmlSchemaObject partialValidationType) at System.Xml.XsdValidatingReader..ctor(XmlReader reader, XmlResolver xmlResolver, XmlReaderSettings readerSettings, XmlSchemaObject partialValidationType) at System.Xml.XmlReaderSettings.AddValidation(XmlReader reader) at System.Xml.XmlReaderSettings.CreateReader(TextReader input, String baseUriString, XmlParserContext inputContext) at System.Xml.XmlReader.Create(TextReader input, XmlReaderSettings settings, String baseUri) at FSI_0004.IA.HelperScripts.ValidateXmlSchema.Validate(String xmlPath) in D:\ECOVSO\KSP\Dev\KSP\Tools\HelperScripts\ValidateXmlSchema.fs:line 28 at [email protected]() Stopped due to error

我觉得可以由FSI会议缓存的东西造成的错误,然后将其发现XmlDocument具有重复的根元素。但实际上,我通过“use”声明了XmlStream和XmlReader。请帮我弄清楚为什么我必须重置交互式会话或重新运行所有脚本才能使该功能正常工作。

+0

在我看来,您将在该特定文件夹中找到的所有文件添加为模式 - 并且两个(或更多)似乎共享“PartnerFeed”定义 - 不要认为这与F#-interactive有任何关系或根元素 - 为什么不只是调试它(例如输入几个'printfn'进行日志记录,或者只是将它变成控制台应用程序并使用VS进行调试) – Carsten

回答

0

每当您拨打Validate时,都会调用LoadSchema,这会将模式添加到schemas。因此,如果您拨打Validate两次,schemas将最终包含相同模式的两个副本。难怪会导致错误。

+0

是的,这是根本原因。非常感谢。 –