【问题标题】:FSI caches something unwanted?FSI 缓存不需要的东西?
【发布时间】:2015-08-10 09:25:41
【问题描述】:

我在 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"

当我选择全部并 Alt+Enter 时,每次都可以正常工作。第一次运行所有脚本文件后,我只选择最后一行调用验证函数,它失败并出现以下错误:

System.Xml.Schema.XmlSchemaValidationException: 全局元素“http://tempuri.org/BaseSchema:PartnerFeed”已被声明。 在 System.Xml.Schema.XmlSchemaValidator.SendValidationEvent(XmlSchemaValidationException e,XmlSeverityType 严重性) 在 System.Xml.Schema.XmlSchemaValidator.SendValidationEvent(XmlSchemaException e) 在 System.Xml.Schema.XmlSchemaValidator.RecompileSchemaSet() 在 System.Xml.Schema.XmlSchemaValidator.Init() 在 System.Xml.Schema.XmlSchemaValidator..ctor(XmlNameTable nameTable,XmlSchemaSet 架构,IXmlNamespaceResolver namespaceResolver,XmlSchemaValidationFlags 验证标志) 在 System.Xml.XsdValidatingReader.SetupValidator(XmlReaderSettings readerSettings,XmlReader reader,XmlSchemaObject partialValidationType) 在 System.Xml.XsdValidatingReader..ctor(XmlReader 阅读器,XmlResolver xmlResolver,XmlReaderSettings readerSettings,XmlSchemaObject partialValidationType) 在 System.Xml.XmlReaderSettings.AddValidation(XmlReader 阅读器) 在 System.Xml.XmlReaderSettings.CreateReader(TextReader 输入,字符串 baseUriString,XmlParserContext inputContext) 在 System.Xml.XmlReader.Create(TextReader 输入,XmlReaderSettings 设置,字符串 baseUri) 在 D:\ECOVSO\KSP\Dev\KSP\Tools\HelperScripts\ValidateXmlSchema.fs:line 28 中的 FSI_0004.IA.HelperScripts.ValidateXmlSchema.Validate(String xmlPath) 在 .$FSI_0006.main@() 由于错误而停止

我认为该错误可能是由于 FSI 会话缓存了某些内容,然后它发现 XmlDocument 具有重复的根元素。但实际上我通过“使用”声明了 XmlStream 和 XmlReader。请帮我弄清楚为什么我必须重置交互式会话或重新运行所有脚本才能使该功能正常工作。

【问题讨论】:

  • 在我看来,您将在该特定文件夹中找到的所有文件添加为模式 - 并且两个(或更多)似乎共享 PartnerFeed 定义 - 不要认为这有什么要完全使用 F#-interactive 或根元素 - 为什么不直接调试它(例如输入一些 printfn 进行日志记录,或者只是将其放入控制台应用程序并使用 VS 进行调试)

标签: xml f# f#-interactive


【解决方案1】:

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

【讨论】:

  • 是的,这是根本原因。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2019-03-16
  • 2021-06-29
  • 2011-04-04
  • 2012-03-03
  • 1970-01-01
  • 2014-12-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多