FSI 缓存不需要的东西?
FSI caches something unwanted?
我在 F# 中有一些代码可以根据模式验证 XML。代码如下:
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"
当我 select all 和 Alt+Enter 时,每次都工作正常。在第一次 运行 所有脚本文件之后,我只是 select 最后一行调用 Validate 函数,它失败并出现以下错误:
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 .$FSI_0006.main@()
Stopped due to error
我认为这个错误可能是由于 FSI 会话缓存了一些东西然后它发现 XmlDocument 有重复的根元素引起的。但实际上我通过 "use" 声明了 XmlStream 和 XmlReader。请帮我弄清楚为什么我必须重置交互式会话或重新运行所有脚本才能使该功能正常工作。
每次调用 Validate
时,它都会调用 LoadSchema
,这会将架构添加到 schemas
。因此,如果您调用 Validate
两次,schemas
最终将包含同一架构的两个副本。难怪会导致错误。
我在 F# 中有一些代码可以根据模式验证 XML。代码如下:
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"
当我 select all 和 Alt+Enter 时,每次都工作正常。在第一次 运行 所有脚本文件之后,我只是 select 最后一行调用 Validate 函数,它失败并出现以下错误:
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 .$FSI_0006.main@() Stopped due to error
我认为这个错误可能是由于 FSI 会话缓存了一些东西然后它发现 XmlDocument 有重复的根元素引起的。但实际上我通过 "use" 声明了 XmlStream 和 XmlReader。请帮我弄清楚为什么我必须重置交互式会话或重新运行所有脚本才能使该功能正常工作。
每次调用 Validate
时,它都会调用 LoadSchema
,这会将架构添加到 schemas
。因此,如果您调用 Validate
两次,schemas
最终将包含同一架构的两个副本。难怪会导致错误。