PhoenixmlDb.XQuery

XsdSchemaProvider

implementation backed by . Provides full XSD validation, type annotations, and schema-element/attribute matching.

#XsdSchemaProvider

Namespace: PhoenixmlDb.XQuery

implementation backed by

. Provides full XSD validation, type annotations, and schema-element/attribute matching.

Schema documents are read by the shared schema layer,

: each document of a schema once, the whole closure before anything is compiled, within that layer's limits (16 MiB a document, 64 MiB and 1,024 documents a schema, 512 levels of nesting, no document type declaration), and with its XSD 1.1 compatibility. A document the schema refers to that cannot be read fails the load; it is not skipped.

#Constructors

##ctor

Creates an empty schema provider. Use

or

to load schemas.

##ctor(PhoenixmlDb.Core.Schema.CompiledSchema)

Creates a schema provider on a schema the shared schema layer compiled, from

or a

. A host that runs many queries against the same schemas compiles them once and gives each engine a provider on the result.

The compiled schema is shared and does not change, so nothing can be added to this provider: an import schema for a namespace the schema declares is satisfied by it, and one for any other namespace is an error (XQST0059), as is XsdSchemaProvider.Add.

The pattern time limit is the one the schema was compiled with (SchemaCompileOptions.PatternMatchTimeout). A query that runs with a shorter QueryExecutionLimits.RegexMatchTimeout lowers it, for every user of the compiled schema, and it stays lowered.

##ctor(String[])

Creates a schema provider with one or more XSD files pre-loaded.

#Properties

Name Description
Catalog A catalog that says where the documents a schema names are really read from; see SchemaCompileOptions.Catalog. Null, the default, for none. What it maps a name to is still read under the resource policy of the load.
ImportCache Where the compiled schemas of import schema are kept, for every provider in the process: a schema read from files is compiled once and used until one of its documents changes, however many queries import it. Each use checks the size and time of every document of the schema, and asks the resource policy of that use about each one.
KnowsXmlNamespace When true, the provider knows the schema of the XML namespace (xml:lang, xml:space, xml:base, xml:id), as XML Schema expects of a processor (XSD 1.0 Β§4.2.6.2): a schema may import that namespace with no schemaLocation. System.Xml does not know it, so such a schema did not compile. Off by default.
PatternMatchTimeout The most time one match of an XSD pattern facet may take, in a cast to a schema type, in validation and while a schema compiles. Default: null, which leaves .NET's process-wide default (infinite unless the host sets it).
SchemaSetForTest The set, for a test that two providers hold the same one.
UsesSharedSet Whether the set is one the XsdSchemaProvider.ImportCache compiled.

#Methods

#Add(String)

Loads an XSD schema from a file path.

#Add(String,IO.TextReader)

Loads an XSD schema from a

.

The text has no location, so a relative

schemaLocation

in it names nothing and the load fails; use

to say where the text is from.

#Add(String,IO.TextReader,PhoenixmlDb.XQuery.Security.ResourcePolicy)

Loads an XSD schema from text, fetching the schema documents it refers to (

xs:include

,

xs:import

,

xs:redefine

) only where

allows imports.

The overloads without a policy resolve those references with no restriction: any file the process can read and any URL it can reach, redirects included. A host that has vetted the schema text itself, but not what that text points to, should use this one;

resolves nothing at all.

#AddFromString(String,String)

Loads an XSD schema from an inline string.

#AddFromString(String,String,PhoenixmlDb.XQuery.Security.ResourcePolicy)

Loads an XSD schema from an inline string under

; see

.

#AddFromString(String,String,Uri,PhoenixmlDb.XQuery.Security.ResourcePolicy)

Loads an XSD schema from text that came from

: a relative

schemaLocation

in it is resolved against that URI. The documents it refers to are read under

, or with no restriction when it is null.

#AddSchemaText(String,String,Uri,PhoenixmlDb.XQuery.Security.ResourcePolicy)

#AddSchemaText(String,String,Uri,PhoenixmlDb.XQuery.Security.ResourcePolicy,Uri)

#AnnotationDerivesFrom(PhoenixmlDb.Xdm.XdmTypeName,Xml.Schema.XmlSchemaType)

Whether a node's type annotation is the declared type or derived from it. An anonymous declared type is compared under the name

gives it, which is what a validated node of that type carries.

#AnnotationName(Xml.Schema.XmlSchemaType)

The name a node of this type is annotated with: the type's own, in the id scheme the rest of the engine uses for type names, or β€” for an anonymous type, which XDM 3.1 Β§2.7.1 says gets an implementation-defined name β€” one made up here and resolvable by

.

#CompileSchemas

Compiles the schema set, first keeping a single schema for the XML namespace. Two schemas that each import xml.xsd from a different location add two copies of it, and compiling fails with "The global attribute 'xml:lang' has already been declared" although the copies declare the same things. The QT3 Catalog schemas do exactly this.

#DateRefusal

Pattern:

csharp
The value '(?<value>[^']*)' is invalid according to its datatype 'http://www\\.w3\\.org/2001/XMLSchema:(?<type>date|dateTime|gYear|gYearMonth)'
            

Options:

csharp
RegexOptions.CultureInvariant
            

Explanation:

csharp
β—‹ Match the string "The value '".
β—‹ "value" capture group.
    β—‹ Match a character other than '\'' atomically any number of times.
β—‹ Match the string "' is invalid according to its datatype 'http://www.w3.org/2001/XMLSchema:".
β—‹ "type" capture group.
    β—‹ Match with 2 alternative expressions.
        β—‹ Match a sequence of expressions.
            β—‹ Match the string "date".
            β—‹ Optional (greedy).
                β—‹ Match the string "Time".
        β—‹ Match a sequence of expressions.
            β—‹ Match the string "gYear".
            β—‹ Optional (greedy).
                β—‹ Match the string "Month".
β—‹ Match '\''.
            

#DateRest

Pattern:

csharp
\\A-(?<month>0[1-9]|1[0-2])-(?<day>\\d\\d)(Z|[+-](0\\d|1[0-3]):[0-5]\\d|[+-]14:00)?\\z
            

Options:

csharp
RegexOptions.CultureInvariant
            

Explanation:

csharp
β—‹ Match if at the beginning of the string.
β—‹ Match '-'.
β—‹ "month" capture group.
    β—‹ Match with 2 alternative expressions.
        β—‹ Match a sequence of expressions.
            β—‹ Match '0'.
            β—‹ Match a character in the set [1-9].
        β—‹ Match a sequence of expressions.
            β—‹ Match '1'.
            β—‹ Match a character in the set [0-2].
β—‹ Match '-'.
β—‹ "day" capture group.
    β—‹ Match a Unicode digit exactly 2 times.
β—‹ Optional (greedy).
    β—‹ 1st capture group.
        β—‹ Match with 3 alternative expressions.
            β—‹ Match 'Z'.
            β—‹ Match a sequence of expressions.
                β—‹ Match a character in the set [+\-].
                β—‹ 2nd capture group.
                    β—‹ Match with 2 alternative expressions.
                        β—‹ Match a sequence of expressions.
                            β—‹ Match '0'.
                            β—‹ Match a Unicode digit.
                        β—‹ Match a sequence of expressions.
                            β—‹ Match '1'.
                            β—‹ Match a character in the set [0-3].
                β—‹ Match ':'.
                β—‹ Match a character in the set [0-5].
                β—‹ Match a Unicode digit.
            β—‹ Match a sequence of expressions.
                β—‹ Match a character in the set [+\-].
                β—‹ Match the string "14:00".
β—‹ Match if at the end of the string.
            

#DateTimeRest

Pattern:

csharp
\\A-(?<month>0[1-9]|1[0-2])-(?<day>\\d\\d)T([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(\\.\\d+)?(Z|[+-](0\\d|1[0-3]):[0-5]\\d|[+-]14:00)?\\z
            

Options:

csharp
RegexOptions.CultureInvariant
            

Explanation:

csharp
β—‹ Match if at the beginning of the string.
β—‹ Match '-'.
β—‹ "month" capture group.
    β—‹ Match with 2 alternative expressions.
        β—‹ Match a sequence of expressions.
            β—‹ Match '0'.
            β—‹ Match a character in the set [1-9].
        β—‹ Match a sequence of expressions.
            β—‹ Match '1'.
            β—‹ Match a character in the set [0-2].
β—‹ Match '-'.
β—‹ "day" capture group.
    β—‹ Match a Unicode digit exactly 2 times.
β—‹ Match 'T'.
β—‹ 1st capture group.
    β—‹ Match with 2 alternative expressions.
        β—‹ Match a sequence of expressions.
            β—‹ Match a character in the set [01].
            β—‹ Match a Unicode digit.
        β—‹ Match a sequence of expressions.
            β—‹ Match '2'.
            β—‹ Match a character in the set [0-3].
β—‹ Match ':'.
β—‹ Match a character in the set [0-5].
β—‹ Match a Unicode digit.
β—‹ Match ':'.
β—‹ Match a character in the set [0-5].
β—‹ Match a Unicode digit.
β—‹ Optional (greedy).
    β—‹ 2nd capture group.
        β—‹ Match '.'.
        β—‹ Match a Unicode digit greedily at least once.
β—‹ Optional (greedy).
    β—‹ 3rd capture group.
        β—‹ Match with 3 alternative expressions.
            β—‹ Match 'Z'.
            β—‹ Match a sequence of expressions.
                β—‹ Match a character in the set [+\-].
                β—‹ 4th capture group.
                    β—‹ Match with 2 alternative expressions.
                        β—‹ Match a sequence of expressions.
                            β—‹ Match '0'.
                            β—‹ Match a Unicode digit.
                        β—‹ Match a sequence of expressions.
                            β—‹ Match '1'.
                            β—‹ Match a character in the set [0-3].
                β—‹ Match ':'.
                β—‹ Match a character in the set [0-5].
                β—‹ Match a Unicode digit.
            β—‹ Match a sequence of expressions.
                β—‹ Match a character in the set [+\-].
                β—‹ Match the string "14:00".
β—‹ Match if at the end of the string.
            

#DeclaringEntities(Collections.Generic.IReadOnlyCollection<String>)

Validates as if the document type declaration of the document declared the entities

, until the scope is disposed. A value of type xs:ENTITY must name an entity the document declares, and the validating parse reads no document type declaration (DTDs are prohibited there), so every such value was "Reference to an undeclared entity". A caller that read the document with its DTD passes the names of the entities the DTD declares.

Parameters:

  • names β€” The names of the entities the document declares.

Returns: The scope; dispose it to end it.

#DerivesFrom(Xml.Schema.XmlSchemaType,Xml.Schema.XmlSchemaType,Int32)

XSD derivation, and membership of a union (XPath 3.1 Β§2.5.6.1): a type derives from a union of which it, or a type it derives from, is a member type, at any depth of unions in unions. Since XPath 3.0 an element or attribute whose annotation is a member type of U matches element(*, U); and an element of a union type is annotated with the member its value matched. So element(*, U), and schema-element(N) of a declaration of type U, matched no element of a union type at all.

#ExtendedYear

Pattern:

csharp
\\A(?<sign>-?)(?<digits>\\d{4,})
            

Options:

csharp
RegexOptions.CultureInvariant
            

Explanation:

csharp
β—‹ Match if at the beginning of the string.
β—‹ "sign" capture group.
    β—‹ Match '-' atomically, optionally.
β—‹ "digits" capture group.
    β—‹ Match a Unicode digit atomically at least 4 times.
            

#FindType(String,String)

The type of that name: one the schemas define, or a built-in type; null when there is none.

#GYearMonthRest

Pattern:

csharp
\\A-(0[1-9]|1[0-2])(Z|[+-](0\\d|1[0-3]):[0-5]\\d|[+-]14:00)?\\z
            

Options:

csharp
RegexOptions.CultureInvariant
            

Explanation:

csharp
β—‹ Match if at the beginning of the string.
β—‹ Match '-'.
β—‹ 1st capture group.
    β—‹ Match with 2 alternative expressions.
        β—‹ Match a sequence of expressions.
            β—‹ Match '0'.
            β—‹ Match a character in the set [1-9].
        β—‹ Match a sequence of expressions.
            β—‹ Match '1'.
            β—‹ Match a character in the set [0-2].
β—‹ Optional (greedy).
    β—‹ 2nd capture group.
        β—‹ Match with 3 alternative expressions.
            β—‹ Match 'Z'.
            β—‹ Match a sequence of expressions.
                β—‹ Match a character in the set [+\-].
                β—‹ 3rd capture group.
                    β—‹ Match with 2 alternative expressions.
                        β—‹ Match a sequence of expressions.
                            β—‹ Match '0'.
                            β—‹ Match a Unicode digit.
                        β—‹ Match a sequence of expressions.
                            β—‹ Match '1'.
                            β—‹ Match a character in the set [0-3].
                β—‹ Match ':'.
                β—‹ Match a character in the set [0-5].
                β—‹ Match a Unicode digit.
            β—‹ Match a sequence of expressions.
                β—‹ Match a character in the set [+\-].
                β—‹ Match the string "14:00".
β—‹ Match if at the end of the string.
            

#GetSchemaSimpleTypeNames(String)

Validates a lexical value against a schema-defined simple type, for cast/castable. The facet checking is XmlSchemaDatatype.ParseValue's, not ours: it already enforces pattern, enumeration, length, bounds and whitespace for every XSD simple type, including unions and lists. Reimplementing that in the engine would be both large and worse.

#HasIdrefTypedValue(PhoenixmlDb.Xdm.XdmTypeName,String)

#ImportSchema(String,Collections.Generic.IReadOnlyList<String>,PhoenixmlDb.XQuery.Security.ResourcePolicy)

#ImportSchema(String,Collections.Generic.IReadOnlyList<String>,PhoenixmlDb.XQuery.Security.ResourcePolicy,Uri)

#IsIdConstraintError(String)

Whether the error is one of the constraints on a document as a whole, on ID and IDREF. They are not applied when an element is validated: the same ID twice, or an IDREF to no ID, in the subtree does not make the element invalid (XQuery 3.1 Β§3.21.2, XSLT 3.0 Β§25.4.1). System.Xml applies them always and gives no code to know them by.

#LimitPatternMatchTime(TimeSpan)

#Load(String,Uri,PhoenixmlDb.Core.Schema.SchemaSource,PhoenixmlDb.XQuery.Security.ResourcePolicy,String,Uri)

Reads one schema β€” the root and everything it includes, imports or redefines β€” through the schema layer, adds it to the set and compiles the set.

#OwnTheSet

Replaces a shared set with one of this provider's own that holds the same schemas, so that something can be added to it.

#RememberNamespaceId(String)

Records the (NamespaceId β†’ URI) mapping for a URI a caller has just registered with the provider. The id is computed using the same hash scheme that

SchemaFeatureChecker

uses, so subsequent lookups against XdmQNames built by that checker round-trip correctly. Built-in XSD/XML/XSI URIs are pre-registered and not re-hashed.

#RemoveUncompiled

Leaves nothing in the set from a load that failed.

#SubstitutesFor(Xml.XmlQualifiedName,Xml.XmlQualifiedName)

Whether the element declared as

is in the substitution group headed by

, directly or through other members (XSD 3.3.6).

#Timezone

Pattern:

csharp
\\A(Z|[+-](0\\d|1[0-3]):[0-5]\\d|[+-]14:00)?\\z
            

Options:

csharp
RegexOptions.CultureInvariant
            

Explanation:

csharp
β—‹ Match if at the beginning of the string.
β—‹ Optional (greedy).
    β—‹ 1st capture group.
        β—‹ Match with 3 alternative expressions.
            β—‹ Match 'Z'.
            β—‹ Match a sequence of expressions.
                β—‹ Match a character in the set [+\-].
                β—‹ 2nd capture group.
                    β—‹ Match with 2 alternative expressions.
                        β—‹ Match a sequence of expressions.
                            β—‹ Match '0'.
                            β—‹ Match a Unicode digit.
                        β—‹ Match a sequence of expressions.
                            β—‹ Match '1'.
                            β—‹ Match a character in the set [0-3].
                β—‹ Match ':'.
                β—‹ Match a character in the set [0-5].
                β—‹ Match a Unicode digit.
            β—‹ Match a sequence of expressions.
                β—‹ Match a character in the set [+\-].
                β—‹ Match the string "14:00".
β—‹ Match if at the end of the string.
            

#TryAddBuiltInJsonSchema

Adds the built-in schema for the XML representation of JSON (F&O 3.1 Β§17.1), the type system of fn:json-to-xml's result. False if the resource is missing from the build.

#TryLoadShared(Collections.Generic.List<ValueTuple<String,Uri,PhoenixmlDb.XQuery.Security.ResourcePolicy>>)

Takes the compiled schema of

from the

as this provider's set. False, with nothing changed, when the cache cannot give one.

#TypeNamespaceId(String)

The NamespaceId of a schema type's namespace, as type annotations carry it. Shared by the parser (element(*, T)) and the annotating parse, so the two compare equal.

#TypedValueRecipe(Xml.Schema.XmlSchemaType)

How a node of this type atomizes, or null when its typed value stays xs:untypedAtomic here: mixed and empty content, unions (the annotation normally names the member that matched instead), and types derived from xs:QName or xs:NOTATION.

#UndeclaredEntity

Pattern:

csharp
Reference to an undeclared entity, '(?<name>[^']*)'
            

Options:

csharp
RegexOptions.CultureInvariant
            

Explanation:

csharp
β—‹ Match the string "Reference to an undeclared entity, '".
β—‹ "name" capture group.
    β—‹ Match a character other than '\'' atomically any number of times.
β—‹ Match '\''.
            

#Validate(PhoenixmlDb.Xdm.Nodes.XdmNode,PhoenixmlDb.XQuery.INodeProvider,PhoenixmlDb.XQuery.ValidationMode,String,String)

Validates

with its markup, serialized through

(#40). Returns the node unchanged.

#ValidateAgainstType(String,String,String,Xml.ConformanceLevel,Collections.Generic.IReadOnlyDictionary<String,String>,Boolean)

Validates the one element of

against a type, whatever the schema declares for an element of its name:

validate type T { … }

in XQuery, and the

type

attribute in XSLT. The type was not used at all here: the content was validated by its declaration, and with no declaration any content passed.

#ValidateAndAnnotate(String,PhoenixmlDb.XQuery.INodeBuilder,PhoenixmlDb.XQuery.ValidationMode,String,String)

Validates

against the loaded schemas and returns a freshly built XDM tree whose elements/attributes carry

TypeAnnotation

values from

SchemaInfo.SchemaType

. Throws

(XQDY0027) on validation failure.

#ValidateAndAnnotate(String,PhoenixmlDb.XQuery.INodeBuilder,PhoenixmlDb.XQuery.ValidationMode,String,String,String)

for a document loaded from

: the annotated tree keeps it as its document and base URI, as an unvalidated load of the same file does.

#ValidateElementAndAnnotate(String,PhoenixmlDb.XQuery.INodeBuilder,PhoenixmlDb.XQuery.ValidationMode,String,String)

#WithTypeOfRoot(String,String,String)

with

xsi:type

for the given type on its outermost element, under prefixes of ours; null when that element has an

xsi:type

of its own, or cannot be found.

#WithoutInjectedType(Collections.Generic.IReadOnlyList<PhoenixmlDb.Xdm.Nodes.XdmNode>)

The nodes of a parse of

, as they would be without what it added.

#WithoutWhitespaceInElementOnlyContent(Collections.Generic.IReadOnlyList<PhoenixmlDb.Xdm.Nodes.XdmNode>)

The nodes of an annotated tree without the whitespace text children of elements whose type has element-only content: a validated element of such a type has no text children (XDM 3.1 Β§6.2.3, the children of an element with element-only content). They were kept, so position() counted them and xsl:strip-space, which cannot change a validated tree, could not take them away.

#Fields

Name Description
AnonymousTypeNamespace The namespace of the names this provider gives anonymous types.
_fixed True when the set is a CompiledSchema's, which other users share: nothing may be added to it.
_holdsOnlyXmlNamespace True while the schema of the XML namespace is all that the set holds.
_namespaceUriById Maps NamespaceId values seen in inbound XdmQName parameters back to namespace URIs. Populated as schemas are loaded (built-in XSD/XML/XSI ids registered up-front, and any arbitrary URI's hash-based id added on first encounter via XsdSchemaProvider.RememberNamespaceId). Solves the lossy NamespaceId-from-URI hashing problem for the QName-based lookup methods β€” the URI-string overloads sidestep this entirely and should be preferred where possible.
_sharedLoads The loads that made the set, when the set is one the XsdSchemaProvider.ImportCache compiled and other providers may share. Such a set is never changed: a further load gets another set from the cache, or the provider builds a set of its own from these loads.
t_declaredEntities Whether the error is System.Xml refusing a date that XML Schema allows: one with a negative year, or a year of more than four digits (XSD 1.0 Part 2 Β§3.2.9.1). System.Xml reads dates into a DateTime, which has neither, and calls -0055-10-10 an invalid xs:date. Such a value is valid, and the error is not one.