Repository navigation
Conversation
mamift
force-pushed
the
testing/dublincore-xhtml
branch
from
September 22, 2026 03:31
1bd25c2 to
5d8961c
Compare
…en global:: is used in other places for namespaces with Xml in them.
…ks for XTCE but needs something more thorough for namespace checking.
…tp urls, then LinqToXsd will now preload those Xsd files from embedded resources, rather than make outbound HTTP calls.
XSD enumerations whose values consist entirely of non-alphanumeric characters (e.g. ComparisonOperatorsType in the XTCE schema with values ==, !=, <, <=, >, >=) previously had every character replaced with '_' when building the C# member name. Distinct values such as "==", "!=" and "<=" therefore all collapsed onto the same member "__", producing duplicate enum members and CS0102 compile errors in the generated code. EnumFacet.CreateValidIdentifier now detects values composed entirely of characters that cannot appear in a C# identifier and expands each character to its full English word name instead of replacing it with an underscore, so "==" becomes EqualsEquals, "<=" becomes LessThanEquals, "&&" becomes AmpersandAmpersand and so on. Mixed values (e.g. "en-fr", which contains letters) keep the legacy underscore replacement, so existing generated code is unaffected. NameGenerator.ExpandSymbolToFullWord is backed by a new lookup table exposed via TryExpandSymbolToFullWord, extended with ASCII whitespace and common Unicode symbols (e.g. +/- signs, sqrt, section sign), and no longer throws for unknown single symbols - such values degrade gracefully to the legacy underscore replacement instead of failing code generation. Co-Authored-By: Claude Code <noreply@anthropic.com>
Even with symbol-to-word expansion, distinct schema values can still map onto the same candidate member name: "*" expands to "Asterisk", which collides with a literal "Asterisk" value, and "a-b" and "a_b" both produce "a_b". Previously such values would be emitted as duplicate enum members and the generated code would not compile. EnumFacet.CreateUniqueFacets now maps the distinct values of an enumeration to facets with mutually unique member names. When candidate names collide, the facet whose schema value is already a valid identifier keeps the name and the others are disambiguated with a deterministic FNV-1a-derived suffix of the schema value, so the result does not depend on facet ordering or on the unstable String.GetHashCode. A final pass falls back to numbered suffixes for crafted schemas that can still collide. The same routine now backs both consumers of facet members, so the generated enum fields and the 'value:member' strings embedded in the RestrictionFacets of the generated validator always agree: - GetEnumFacets (used by TypeBuilder.CreateEnumType and TypesToCodeDom to emit enum members) - CompiledFacets.compileFacets (used to emit the validator facet strings); it now collects the enumeration values first and builds the facet strings once the whole set is known. Non-enum restrictions (e.g. numeric enumerations) still add their typed values immediately, as before. Co-Authored-By: Claude Code <noreply@anthropic.com>
EnumFacetMapping.Parse previously split the stored "value:member" enumeration strings on the first colon, so an enumeration value that itself contains a colon (e.g. "12:30") was truncated to "12" at runtime, breaking validation and round-tripping. Member names are valid C# identifiers and can never contain a colon, so the last colon is always the true separator. Parsing now keeps everything before the last colon as the schema value, which is backwards compatible with all previously generated mapping strings (they contain at most one colon). Co-Authored-By: Claude Code <noreply@anthropic.com>
Regenerated with the fixed code generator. The ComparisonOperatorsType and MathOperatorsType enums no longer collapse their operator values onto duplicate "__" members, which previously caused CS0102 errors and broke the XTCE project (and therefore the test suite) build: - ComparisonOperatorsType: == -> EqualsEquals, != -> ExclamationMarkEquals, <= -> LessThanEquals, >= -> GreaterThanEquals - MathOperatorsType: << -> LessThanLessThan, >> -> GreaterThanGreaterThan, && -> AmpersandAmpersand, || -> PipePipe, >= -> GreaterThanEquals, <= -> LessThanEquals, == -> EqualsEquals, != -> ExclamationMarkEquals The 'value:member' strings in the generated validators were updated in lockstep, and the default value references now point at the renamed members. The XTCE project now compiles cleanly. Co-Authored-By: Claude Code <noreply@anthropic.com>
Adds test fixtures to EnumsTest.xsd and regenerates the committed EnumsTest.xsd-g.cs with the fixed generator: - OperatorEnum: values ==, !=, <, <=, >, >=, &&, || (all-symbol values that previously collapsed onto duplicate "__" members) - ColonContainingEnum: values 12:30 and 23:59 (values containing the 'value:member' separator colon, exercising the last-colon split in EnumFacetMapping) - CollisionEnum: values * and Asterisk (two distinct values that map to the same candidate member name, exercising EnumFacet.CreateUniqueFacets; "*" is disambiguated to "Asterisk_2F0C9F3D" while the literal "Asterisk" value keeps its name) - OperatorElementType: element wrapper for runtime round-trip tests The regeneration is purely additive apart from the generator version bump in the header comment (the committed file predates 3.4.24); all previously generated types are unchanged. Co-Authored-By: Claude Code <noreply@anthropic.com>
EnumFacetTests (unit tests against the generator's facet model): - symbol-only values expand each symbol to its full word name - single symbols map to their full word names - mixed values keep the legacy underscore replacement, so existing generated code is unaffected - keyword values are escaped with '@' - unknown symbols degrade gracefully to underscore replacement - colliding facets are disambiguated with unique, order-independent member names, and duplicate values produce a single facet OperatorEnumTests (integration tests against the EnumsTest schema): - generated code contains the expected unique word members for the operator enum, and unique members for the collision enum - runtime round-trips verify that every operator value is written to XML using its original schema value and parsed back to the correct member, that colon-containing values survive the 'value:member' split, and that the disambiguated collision member maps back to its original symbol value The new test classes are self-contained and do not share the EnumsCodeGenTest fixture, whose generated-tree compilation diagnostics currently warn (and therefore skip) every test in that class; that fixture's behaviour predates and is unrelated to this change. Co-Authored-By: Claude Code <noreply@anthropic.com>
CreateTypeManager emits using imports between the generated code namespaces (each namespace imports the root namespace and vice versa) but never applied the global:: prefixing decision that AddDefaultImports applies to the standard imports. With AlwaysPrefixGlobal="true" those imports were still emitted bare, e.g. `using urn.din.Item70121.Item2012.MsgDef;` inside `namespace www.w3.org.Item2000.Item09.xmldsig`, so the setting was only partially honoured. In auto-detection mode the same ambiguity the default imports guard against - an import sharing a component with the enclosing namespace, which can make the compiler resolve it relative to that namespace - also applied to these imports but was never checked. AddGlobalPrefixIfRequired mirrors AddDefaultImports' decision: prefix global:: when AlwaysPrefixGlobalInUsingDirectives is set, otherwise when the import and the importing namespace share a component (case-insensitive). The root import was previously one CodeNamespaceImport instance shared across every namespace; it is now created per target namespace so each import is decided against the namespace it is declared in. Default-import behaviour is unchanged, so fixtures whose namespaces share no components with their imports generate identical output to before. Co-Authored-By: Claude Code <noreply@anthropic.com>
Adds GlobalPrefixUsingDirectivesTests, a self-contained codegen test class that generates code for a schema set with two namespaces (urn:test:namespace1 importing urn:test:namespace2) and inspects the emitted using directives. WhenAlwaysPrefixGlobalThenAllUsingDirectivesAreGlobalQualified covers the AlwaysPrefixGlobal="true" setting: every using directive must be qualified with global::. WhenImportSharesComponentWithImportingNamespaceThenImportIsGlobalQualified covers auto-detection: the cross-namespace imports share the urn and test components with the namespaces they are declared in, so they must be qualified, while the default imports must remain unqualified. The tests use in-memory schemas and do not inherit the shared codegen fixture, following the precedent set by OperatorEnumTests, because that fixture marks its tests as skipped when its harness compilation reports diagnostics. Co-Authored-By: Claude Code <noreply@anthropic.com>
Regenerated output for the fixtures whose cross-namespace using directives changed: imports added between generated code namespaces are now qualified with global:: when AlwaysPrefixGlobal is set (W3C XMLSchema v1, ImportsXmlAttributes) or when the import shares a component with the enclosing namespace (Multi-namespaces, LegalRuleML, ORMML, Microsoft Search Response, SOAP-WSDL). No other generated code changed. Co-Authored-By: Claude Code <noreply@anthropic.com>
… up to a hitherto unknown bug that was fixed coincidentally.
…ant code fix; there were two 'Stainless Steel 1.4401:Stainless_Steel_1_4401' entries before and now there's just one (the XSD also has two entries for 'Stainless Steel 1.4401:Stainless_Steel_1_4401' in cidxListEnclosureType XSD enum type.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
-aflag will now delete existing files with the.xsd.csextension (since v3.4.17, the default output extension is now.xsd-g.cs) when outputting codexs:schema\@versionattribute is a user defined attribute for the schema version, it does not specify which W3C XSD specification version to validate against (i.e. v1.0 or v1.1). This would've inadvertently causedlinqtoxsdto skip schemas whose versions were v1.1 or higher.-aargument when invoking thelinqtoxsdCLI tool is now always applied i.e. it now always searches for a.xsd.configfile regardless. However, in previous versions, if a config file was not found,linqtoxsdwould skip that XSD file - nowlinqtoxsdwill simply apply default config values for those XSD files.v3.4.24