Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 50 additions & 26 deletions src/FSharp.Data.DesignTime/CommonProviderImplementation/Helpers.fs
Original file line number Diff line number Diff line change
Expand Up @@ -725,34 +725,58 @@ module internal ProviderHelpers =

yield m :> _

| Schema _ ->
let getSchemaCode _ =
if parseResult.IsUri then
<@
Async.RunSynchronously(
asyncReadTextAtRuntimeWithDesignTimeRules
defaultResolutionFolder
resolutionFolder
formatName
encodingStr
valueToBeParsedOrItsUri
)
@>
else
<@ new StringReader(valueToBeParsedOrItsUri) :> TextReader @>
| Schema _ -> () // GetSchema is generated below, outside this block
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot Add a test case for this fix



// GetSchema is generated for Schema sources regardless of EmbeddedResource,
// so that deployed assemblies can validate XML against the schema at runtime.
match source with
| Schema _ ->
let getSchemaCode _ =
if parseResult.IsResource then
// EmbeddedResource was specified and the resource was found at design time.
// At runtime, read the schema from the embedded resource in the user's assembly.
let parts = resource.Split(',')
let asmName = parts.[0].Trim()
let resName = parts.[1].Trim()

<@
// Assembly.Load handles assemblies not yet in AppDomain
let loadedAsm = System.Reflection.Assembly.Load(asmName)

// Do not use 'use' here β€” the reader lifetime is managed by
// parseSchemaFromTextReader (XmlReader with CloseInput=true)
let stream = loadedAsm.GetManifestResourceStream(resName)
new System.IO.StreamReader(stream) :> TextReader
@>
|> spec.CreateFromTextReaderForSampleList // hack: this will actually parse the schema
elif parseResult.IsUri then
<@
Async.RunSynchronously(
asyncReadTextAtRuntimeWithDesignTimeRules
defaultResolutionFolder
resolutionFolder
formatName
encodingStr
valueToBeParsedOrItsUri
)
@>
|> spec.CreateFromTextReaderForSampleList // hack: this will actually parse the schema
else
<@ new StringReader(valueToBeParsedOrItsUri) :> TextReader @>
|> spec.CreateFromTextReaderForSampleList // hack: this will actually parse the schema

// Generate static GetSchema method
yield
ProvidedMethod(
"GetSchema",
[],
typeof<System.Xml.Schema.XmlSchemaSet>,
isStatic = true,
invokeCode = getSchemaCode
)
:> _

// Generate static GetSchema method
yield
ProvidedMethod(
"GetSchema",
[],
typeof<System.Xml.Schema.XmlSchemaSet>,
isStatic = true,
invokeCode = getSchemaCode
)
:> _
| _ -> ()

]
|> spec.GeneratedType.AddMembers
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
</PropertyGroup>
<ItemGroup>
<Compile Include="JsonProvider.fs" />
<Compile Include="XmlProvider.fs" />
<Compile Include="Program.fs" />
</ItemGroup>
<ItemGroup>
Expand Down
9 changes: 9 additions & 0 deletions tests/FSharp.Data.Reference.Tests/XmlProvider.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
module FSharp.Data.Reference.Tests.XmlProvider

open NUnit.Framework
open FsUnit

[<Test>]
let ``GetSchema works for XmlProvider with Schema and EmbeddedResource`` () =
let schema = FSharp.Data.Tests.XmlProvider.XmlSchemaWithEmbeddedResource.GetSchema()
schema.Count |> should equal 1
4 changes: 4 additions & 0 deletions tests/FSharp.Data.Tests/XmlProvider.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1320,3 +1320,7 @@ let ``Inline schemas as overrides replace value-based inference when present`` (
sample[1].Value.GetType() |> should equal (typeof<int option>)
// (Note the types in the inline schemas are automatically transformed to options as needed
// when another node does not define any value for the given property)

// Used by FSharp.Data.Reference.Tests to verify that GetSchema works with EmbeddedResource
type XmlSchemaWithEmbeddedResource =
XmlProvider<Schema = "Data/po.xsd", EmbeddedResource = "FSharp.Data.Tests, FSharp.Data.Tests.Data.po.xsd">
Loading