all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Adding new schemas to nxml-mode. Am I doing it right?
@ 2024-02-18 20:12 Jostein Kjønigsen
  2024-02-19 22:20 ` Stefan Kangas
  0 siblings, 1 reply; 7+ messages in thread
From: Jostein Kjønigsen @ 2024-02-18 20:12 UTC (permalink / raw)
  To: Ergus via Emacs development discussions.

[-- Attachment #1: Type: text/plain, Size: 2691 bytes --]

Hey everyone!

I recently discovered that nxml-mode in Emacs supports validating XML content against XML schemas, which I had never noticed before. It turns out that none of the files I've edited using nxml-mode had a supported schema.

Looking into this I learned a few things about nxml-mode:

XML is not validated against XSD schemas, which are the most common schema format today.
Emacs relies on RNC schemas[1], which are less common and have fewer tools, but are simpler.
Emacs cannot automatically obtain the schemas which are declared in XML documents.

The last point is the most impactful in terms of usability, but it might require more effort to fix than we can currently manage.

As an end-user, effectively only the RNC schemas provided with Emacs are available. To make matters worse, seemingly these list of supported schemas have not changed since 2007. Someone correct me if I'm wrong.

I would like Emacs to support XSD and automatically fetch schemas at runtime, but I also want a better nxml-mode experience for the file formats I use daily, today.

To address this, I have created RNC schemas for the formats I depend on. I have attached an abbreviated diff of the changes. The main changes are:

Updating schemas.xml with typeIDs and conditions for applying them in the correct order.
Generating new RNC schemas based on those typeIDs.

I tried to find tooling to convert XSD schemas to RNC, but I couldn't find anything which actually worked. After a few days of getting nowhere, I instead decided to use a tool called "jing-trang”[2] to infer the XML schema based on existing documents in my possession (200+ software projects, 50+ GBs).

While this method doesn't guarantee the accuracy of the schemas, they are based on a large number of files, ensuring that most common elements and attributes are present and specified. It may not be scientifically accurate (like an actual XSD to RNC translation), but it works for my purposes.

Accurate schema support is a small yet significant feature that can make a noticeable difference when working with XML. Ideally, Emacs should have schemas for all XML-based file-types commonly used.

As such, I would like to contribute these patches to core Emacs to help improve the current situation, but I want to make sure I'm doing it correctly.

How can I create accurate, quality schemas in RNC with the current tooling?
What are the criteria for accepting new schemas in Emacs core? Are there any?

I would appreciate any comments or feedback on this matter.

Thanks!

[1] https://relaxng.org/
[2] https://github.com/relaxng/jing-trang


—
Kind Regards
Jostein Kjønigsen



[-- Attachment #2.1: Type: text/html, Size: 12939 bytes --]

[-- Attachment #2.2: schemas.patch --]
[-- Type: application/octet-stream, Size: 1533 bytes --]

diff --git a/etc/schema/schemas.xml b/etc/schema/schemas.xml
index f04bba849b4..dd1e23a5a8e 100644
--- a/etc/schema/schemas.xml
+++ b/etc/schema/schemas.xml
@@ -66,4 +66,30 @@
   <typeId id="LibreOffice" uri="OpenDocument-schema-v1.3+libreoffice.rnc"/>
   <typeId id="OpenDocument Manifest" uri="od-manifest-schema-v1.2-os.rnc"/>
 
+  <!-- .net development related schemas -->
+  <uri pattern="nuget.config" typeId="Nuget Config" />
+  <typeId id="Nuget Config" uri="nuget.rnc" />
+
+  <uri pattern="*.nuspec" typeId="Nuget Spec" />
+  <namespace ns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd" typeId="Nuget Spec" />
+  <typeId id="Nuget Spec" uri="nuspec.rnc" />
+
+  <uri pattern="web.config" typeId="Dotnet App Config" />
+  <uri pattern="app.config" typeId="Dotnet App Config" />
+  <namespace ns="http://schemas.microsoft.com/.NetConfiguration/v2.0" typeId="Dotnet App Config" />
+  <typeId id="Dotnet App Config" uri="dotnet-appconfig.rnc" />
+
+  <uri pattern="Directory.Build.props" typeId="Dotnet Build Props" />
+  <typeId id="Dotnet Build Props" uri="dotnet-build-props.rnc" />
+
+  <uri pattern="Directory.Packages.props" typeId="Dotnet Packages Props" />
+  <typeId id="Dotnet Packages Props" uri="dotnet-packages-props.rnc" />
+
+  <uri pattern="*.resx" typeId="Dotnet Resx" />
+  <typeId id="Dotnet Resx" uri="dotnet-resx.rnc" />
+
+  <uri pattern="*.*proj" typeId="MSBuild" />
+  <documentElement localName="Project" typeId="MSBuild"/>
+  <typeId id="MSBuild" uri="msbuild.rnc" />
+
 </locatingRules>

[-- Attachment #2.3: Type: text/html, Size: 212 bytes --]

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: Adding new schemas to nxml-mode. Am I doing it right?
  2024-02-18 20:12 Adding new schemas to nxml-mode. Am I doing it right? Jostein Kjønigsen
@ 2024-02-19 22:20 ` Stefan Kangas
  2024-02-20 20:02   ` [PATCH] Adding new schemas to nxml-mode Jostein Kjønigsen
  0 siblings, 1 reply; 7+ messages in thread
From: Stefan Kangas @ 2024-02-19 22:20 UTC (permalink / raw)
  To: Jostein Kjønigsen, Ergus via Emacs development discussions.
  Cc: Stefan Monnier

Jostein Kjønigsen <jostein@secure.kjonigsen.net> writes:

> As such, I would like to contribute these patches to core Emacs to
> help improve the current situation, but I want to make sure I'm doing
> it correctly.

Your plan sounds good to me, but I know very little about this stuff.
I'm hoping that someone else will chime in, but AFAIK we don't have
anyone onboard that is working on this.  Perhaps what you see is the
result of that lack of manpower.

> What are the criteria for accepting new schemas in Emacs core? Are
> there any?

I'm not aware of any criteria that would be applied to schemas
specifically, so I guess it's the usual: is it useful, can we legally
distribute it, etc.



^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH] Adding new schemas to nxml-mode
  2024-02-19 22:20 ` Stefan Kangas
@ 2024-02-20 20:02   ` Jostein Kjønigsen
  2024-02-21  3:01     ` Stefan Kangas
  0 siblings, 1 reply; 7+ messages in thread
From: Jostein Kjønigsen @ 2024-02-20 20:02 UTC (permalink / raw)
  To: Stefan Kangas; +Cc: Ergus via Emacs development discussions., Stefan Monnier

[-- Attachment #1: Type: text/plain, Size: 1653 bytes --]

With those encouraging words, I guess there’s no reason to be mucking about then.

Attached is the patch with all schemas, and mappings for Emacs to apply them. I’ve tried to keep the mapping “sober” enough to not trigger for documents it shouldn’t, while trying to make sure they get applied when it makes sense.

Now before installing, I think it would be nice if:

- If someone could at least look over the mapping and see if there are obvious cases where the schemas will be applied and they shouldn’t. 
- Most schemas in this batch are related to .NET development. If anyone using Emacs for .NET development could verify that they work and don’t cause noise/warnings for valid files.

Basically as a minimum make sure it works for more people than just me.

—
Kind Regards
Jostein Kjønigsen

> On 19 Feb 2024, at 23:20, Stefan Kangas <stefankangas@gmail.com> wrote:
> 
> Jostein Kjønigsen <jostein@secure.kjonigsen.net> writes:
> 
>> As such, I would like to contribute these patches to core Emacs to
>> help improve the current situation, but I want to make sure I'm doing
>> it correctly.
> 
> Your plan sounds good to me, but I know very little about this stuff.
> I'm hoping that someone else will chime in, but AFAIK we don't have
> anyone onboard that is working on this.  Perhaps what you see is the
> result of that lack of manpower.
> 
>> What are the criteria for accepting new schemas in Emacs core? Are
>> there any?
> 
> I'm not aware of any criteria that would be applied to schemas
> specifically, so I guess it's the usual: is it useful, can we legally
> distribute it, etc.
[-- Attachment #2.1: Type: text/html, Size: 2260 bytes --]

[-- Attachment #2.2: 0001-nxml-mode-Add-schemas-for-.net-related-development-f.patch --]
[-- Type: application/octet-stream, Size: 66010 bytes --]

From 318bc52c24308095662694aaea0feb2e4d640b32 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jostein=20Kj=C3=B8nigsen?= <jostein@kjonigsen.net>
Date: Thu, 15 Feb 2024 21:54:14 +0100
Subject: [PATCH] nxml-mode: Add schemas for .net related development
 file-formats

- MSBuild project files
- Dotnet build properties files
- Dotnet package properties files
- Dotnet resource extension files
- Dotnet Application config files
- Nuget config file
- Nuget package specification file
- Nuget packages config file
---
 etc/schema/dotnet-appconfig.rnc       | 399 ++++++++++++
 etc/schema/dotnet-build-props.rnc     |  93 +++
 etc/schema/dotnet-packages-config.rnc |  10 +
 etc/schema/dotnet-packages-props.rnc  |  21 +
 etc/schema/dotnet-resx.rnc            |  57 ++
 etc/schema/msbuild.rnc                | 905 ++++++++++++++++++++++++++
 etc/schema/nuget.rnc                  |  25 +
 etc/schema/nuspec.rnc                 | 100 +++
 etc/schema/schemas.xml                |  29 +
 9 files changed, 1639 insertions(+)
 create mode 100644 etc/schema/dotnet-appconfig.rnc
 create mode 100644 etc/schema/dotnet-build-props.rnc
 create mode 100644 etc/schema/dotnet-packages-config.rnc
 create mode 100644 etc/schema/dotnet-packages-props.rnc
 create mode 100644 etc/schema/dotnet-resx.rnc
 create mode 100644 etc/schema/msbuild.rnc
 create mode 100644 etc/schema/nuget.rnc
 create mode 100644 etc/schema/nuspec.rnc

diff --git a/etc/schema/dotnet-appconfig.rnc b/etc/schema/dotnet-appconfig.rnc
new file mode 100644
index 00000000000..81833df1827
--- /dev/null
+++ b/etc/schema/dotnet-appconfig.rnc
@@ -0,0 +1,399 @@
+default namespace = ""
+namespace ns1 = "http://schemas.microsoft.com/.NetConfiguration/v2.0"
+namespace ns2 = "urn:schemas-microsoft-com:asm.v1"
+
+start =
+  element configuration {
+    element configSections { (section | sectionGroup)+ }?,
+    element system.web.webPages.razor {
+      element host {
+        attribute factoryType { text }
+      },
+      pages
+    }?,
+    (system.web
+     | system.webServer
+     | element appSettings { (text | add)+ }
+     | element connectionStrings { add* }
+     | element entityFramework {
+         element defaultConnectionFactory {
+           attribute type { text },
+           element parameters {
+             element parameter {
+               attribute value { xsd:NCName }
+             }
+           }
+         },
+         element providers {
+           element provider {
+             attribute invariantName { xsd:NCName },
+             attribute type { text }
+           }
+         }
+       }
+     | element location {
+         attribute inheritInChildApplications { xsd:boolean }?,
+         attribute path { text },
+         system.web?,
+         system.webServer?
+       }
+     | element runtime {
+         element ns2:assemblyBinding {
+           attribute appliesTo { xsd:NCName }?,
+           element ns2:dependentAssembly {
+             element ns2:Paket { xsd:NCName }?,
+             element ns2:assemblyIdentity {
+               attribute culture { xsd:NCName }?,
+               attribute name { xsd:NCName },
+               attribute publicKeyToken { xsd:NMTOKEN }
+             },
+             element ns2:bindingRedirect {
+               attribute newVersion { xsd:NMTOKEN },
+               attribute oldVersion { xsd:NMTOKEN }
+             }
+           }+
+         }+
+       }
+     | element system.codedom {
+         element compilers {
+           element compiler {
+             attribute compilerOptions { text }?,
+             attribute extension { xsd:NMTOKEN },
+             attribute language { text },
+             attribute type { text },
+             attribute warningLevel { xsd:integer },
+             element providerOption {
+               attribute name { xsd:NCName },
+               attribute value { xsd:NCName }
+             }*
+           }+
+         }
+       }
+     | element system.diagnostics {
+         element sources {
+           element source {
+             attribute name { xsd:NCName },
+             element listeners { add }?
+           }+
+         },
+         (element switches { empty },
+          element sharedListeners { empty },
+          element trace {
+            attribute autoflush { xsd:boolean }
+          })?
+       }
+     | element system.serviceModel {
+         (element behaviors {
+            element serviceBehaviors {
+              element behavior {
+                attribute name { text }?,
+                element serviceMetadata {
+                  attribute httpGetEnabled { xsd:boolean },
+                  attribute httpsGetEnabled { xsd:boolean }?
+                },
+                element serviceDebug {
+                  attribute httpHelpPageEnabled { xsd:boolean }?,
+                  attribute includeExceptionDetailInFaults {
+                    xsd:boolean
+                  }
+                },
+                element dataContractSerializer {
+                  attribute maxItemsInObjectGraph { xsd:integer }
+                }?,
+                element serviceTelemetry { empty }?
+              }
+            }
+          }
+          | element bindings {
+              element basicHttpBinding {
+                element binding {
+                  attribute closeTimeout { xsd:time }?,
+                  attribute maxBufferSize { xsd:integer }?,
+                  attribute maxReceivedMessageSize { xsd:integer }?,
+                  attribute name { xsd:NCName }?,
+                  attribute openTimeout { xsd:time }?,
+                  attribute receiveTimeout { xsd:time }?,
+                  attribute sendTimeout { xsd:time }?,
+                  element readerQuotas {
+                    attribute maxArrayLength { xsd:integer },
+                    attribute maxBytesPerRead { xsd:integer }?,
+                    attribute maxDepth { xsd:integer }?,
+                    attribute maxNameTableCharCount { xsd:integer }?,
+                    attribute maxStringContentLength { xsd:integer }
+                  }?,
+                  security?
+                }+
+              }?
+            }
+          | element client { empty }
+          | element extensions {
+              element behaviorExtensions { add+ }
+            }
+          | element protocolMapping { add+ }
+          | element serviceHostingEnvironment {
+              attribute aspNetCompatibilityEnabled { xsd:boolean }?,
+              attribute multipleSiteBindingsEnabled { xsd:boolean }?
+            })*,
+         (element diagnostics {
+            element messageLogging {
+              attribute logEntireMessage { xsd:boolean },
+              attribute logMalformedMessages { xsd:boolean },
+              attribute logMessagesAtServiceLevel { xsd:boolean },
+              attribute logMessagesAtTransportLevel { xsd:boolean },
+              attribute maxMessagesToLog { xsd:integer },
+              attribute maxSizeOfMessageToLog { xsd:integer }
+            }
+          }
+          | element services {
+              element service {
+                attribute behaviorConfiguration { xsd:NCName }?,
+                attribute name { text },
+                element endpoint {
+                  attribute address { xsd:NCName }?,
+                  attribute binding { xsd:NCName },
+                  attribute bindingConfiguration { xsd:NCName }?,
+                  attribute contract { xsd:NCName }
+                }+
+              }+
+            })?
+       })+
+  }
+  | element ns1:configuration {
+      element ns1:configSections {
+        element ns1:section {
+          attribute name { xsd:NCName },
+          attribute requirePermission { xsd:boolean },
+          attribute type { text }
+        }
+      },
+      element ns1:appSettings { empty },
+      element ns1:connectionStrings { empty },
+      element ns1:system.web {
+        element ns1:compilation {
+          attribute debug { xsd:boolean },
+          attribute defaultLanguage { text },
+          attribute targetFramework { xsd:decimal }
+        },
+        element ns1:authentication {
+          attribute mode { xsd:NCName }
+        },
+        element ns1:httpModules { ns1.add },
+        element ns1:pages {
+          attribute clientIDMode { xsd:NCName },
+          attribute controlRenderingCompatibilityVersion { xsd:decimal }
+        }
+      },
+      element ns1:system.webServer {
+        element ns1:modules {
+          attribute runAllManagedModulesForAllRequests { xsd:boolean },
+          ns1.add
+        }
+      },
+      element ns1:rewriter {
+        element ns1:rewrite {
+          attribute to { text },
+          attribute url { text }
+        }+
+      }
+    }
+section =
+  element section {
+    attribute allowExeDefinition { xsd:NCName }?,
+    attribute name { xsd:NCName },
+    attribute requirePermission { xsd:boolean }?,
+    attribute restartOnExternalChanges { xsd:boolean }?,
+    attribute type { text }
+  }
+sectionGroup =
+  element sectionGroup {
+    attribute name { xsd:NCName },
+    attribute type { text }?,
+    (section | sectionGroup)+
+  }
+pages =
+  element pages {
+    attribute clientIDMode { xsd:NCName }?,
+    attribute controlRenderingCompatibilityVersion { xsd:decimal }?,
+    attribute enableEventValidation { xsd:boolean }?,
+    attribute pageBaseType { xsd:NCName }?,
+    attribute theme { text }?,
+    attribute validateRequest { xsd:boolean }?,
+    attribute viewStateEncryptionMode { xsd:NCName }?,
+    element namespaces { add+ }?
+  }
+add =
+  element add {
+    attribute assembly { text }?,
+    attribute binding { xsd:NCName }?,
+    attribute bindingConfiguration { text }?,
+    attribute connectionString { xsd:anyURI }?,
+    attribute initializeData { text }?,
+    attribute input { text }?,
+    attribute key { xsd:NMTOKEN }?,
+    attribute matchType { xsd:NCName }?,
+    attribute modules { xsd:NCName }?,
+    attribute name { xsd:NCName }?,
+    attribute namespace { xsd:NCName }?,
+    attribute negate { xsd:boolean }?,
+    attribute path { text }?,
+    attribute preCondition { text }?,
+    attribute providerName { xsd:NCName }?,
+    attribute resourceType { xsd:NCName }?,
+    attribute responseBufferLimit { xsd:integer }?,
+    attribute scheme { xsd:NCName }?,
+    attribute scriptProcessor { text }?,
+    attribute type { text }?,
+    attribute validate { xsd:boolean }?,
+    attribute value { text }?,
+    attribute verb { text }?
+  }
+Globalization =
+  element Globalization {
+    element ResourceProviders { empty }
+    | add+
+  }
+security =
+  element security {
+    attribute mode { xsd:NCName }?,
+    (element requestFiltering {
+       attribute removeServerHeader { xsd:boolean },
+       element requestLimits {
+         attribute maxAllowedContentLength { xsd:integer }
+       }?
+     }
+     | element transport {
+         attribute clientCredentialType { xsd:NCName }
+       })?
+  }
+system.webServer =
+  element system.webServer {
+    element staticContent {
+      element mimeMap {
+        attribute fileExtension { xsd:NMTOKEN },
+        attribute mimeType { text }
+      }+
+    }?,
+    element rewrite {
+      element rules {
+        element rule {
+          attribute name { xsd:NCName },
+          attribute stopProcessing { xsd:boolean },
+          element match {
+            attribute url { text }
+          },
+          element conditions {
+            attribute logicalGrouping { xsd:NCName },
+            add+
+          },
+          element action {
+            attribute type { xsd:NCName },
+            attribute url { text }
+          }
+        }
+      }
+    }?,
+    element httpErrors {
+      attribute errorMode { xsd:NCName }?,
+      attribute existingResponse { xsd:NCName },
+      (remove+,
+       element error {
+         attribute path { text },
+         attribute prefixLanguageFilePath { text },
+         attribute responseMode { xsd:NCName },
+         attribute statusCode { xsd:integer }
+       }+)?
+    }?,
+    (security
+     | element aspNetCore {
+         attribute arguments { text }?,
+         attribute hostingModel { xsd:NCName },
+         attribute processPath { text },
+         attribute stdoutLogEnabled { xsd:boolean },
+         attribute stdoutLogFile { text }
+       }
+     | element handlers { (add | remove)+ }
+     | element httpProtocol {
+         element customHeaders {
+           element clear { empty }?,
+           remove+
+         }
+       }
+     | element modules {
+         attribute runAllManagedModulesForAllRequests { xsd:boolean }?,
+         (add | remove)*
+       }
+     | element validation {
+         attribute validateIntegratedModeConfiguration { xsd:boolean }
+       })*,
+    element directoryBrowse {
+      attribute enabled { xsd:boolean }
+    }?
+  }
+system.web =
+  element system.web {
+    element authorization {
+      element allow {
+        attribute users { text }
+      }
+    }
+    | (pages
+       | element authentication {
+           attribute mode { xsd:NCName }
+         }
+       | element compilation {
+           attribute debug { xsd:boolean }?,
+           attribute targetFramework { xsd:NMTOKEN }?,
+           attribute tempDirectory { text }?,
+           element assemblies { add+ }?
+         }
+       | element customErrors {
+           attribute defaultRedirect { text }?,
+           attribute mode { xsd:NCName },
+           attribute redirectMode { xsd:NCName }?
+         }
+       | element globalization {
+           attribute requestEncoding { xsd:NCName },
+           attribute responseEncoding { xsd:NCName }
+         }
+       | element httpHandlers { add+ }
+       | element httpModules { add* }
+       | element httpRuntime {
+           attribute appRequestQueueLimit { xsd:integer }?,
+           attribute enableVersionHeader { xsd:boolean }?,
+           attribute executionTimeout { xsd:integer }?,
+           attribute maxRequestLength { xsd:integer }?,
+           attribute minFreeThreads { xsd:integer }?,
+           attribute minLocalRequestFreeThreads { xsd:integer }?,
+           attribute requestPathInvalidCharacters { text }?,
+           attribute requestValidationMode { xsd:decimal }?,
+           attribute targetFramework { xsd:NMTOKEN }?,
+           attribute useFullyQualifiedRedirectUrl { xsd:boolean }?
+         }
+       | element identity {
+           attribute impersonate { xsd:boolean }
+         }
+       | element machineKey {
+           attribute validation { xsd:NCName }
+         }
+       | element sessionState {
+           attribute cookieSameSite { xsd:NCName }?,
+           attribute cookieless { xsd:boolean },
+           attribute mode { xsd:NCName },
+           attribute stateConnectionString { text }?,
+           attribute timeout { xsd:integer }
+         }
+       | element xhtmlConformance {
+           attribute mode { xsd:NCName }
+         })*
+  }
+ns1.add =
+  element ns1:add {
+    attribute name { xsd:NCName },
+    attribute type { text }
+  }
+remove =
+  element remove {
+    attribute name { xsd:NCName }?,
+    attribute statusCode { xsd:integer }?,
+    attribute subStatusCode { xsd:integer }?
+  }
diff --git a/etc/schema/dotnet-build-props.rnc b/etc/schema/dotnet-build-props.rnc
new file mode 100644
index 00000000000..12da068113a
--- /dev/null
+++ b/etc/schema/dotnet-build-props.rnc
@@ -0,0 +1,93 @@
+default namespace = ""
+
+start =
+  element Project {
+    (element Import {
+       attribute Project { text }
+     }
+     | element ItemGroup {
+         attribute Condition { text }?,
+         (element InternalsVisibleTo {
+            attribute Condition { text },
+            attribute Include { text }
+          }
+          | element None {
+              attribute Include { text },
+              attribute Pack { xsd:boolean },
+              attribute PackagePath { text }
+            }
+          | element SourceRoot {
+              attribute Include { text }
+            }
+          | element Using {
+              attribute Include { xsd:NCName }
+            }+
+          | element PackageReference {
+              attribute Include { xsd:NCName },
+              attribute Version { text },
+              (element PrivateAssets { xsd:NCName },
+               element IncludeAssets { text })?
+            }+)
+       }
+     | element PropertyGroup {
+         attribute Condition { text }?,
+         element TargetFramework { xsd:NCName }?,
+         (element DotnetMonoRepoVersion { xsd:NMTOKEN }
+          | element WarningsAsErrors { text }
+          | (element Version {
+               attribute Condition { text },
+               text
+             },
+             element SuperOfficeBuildToolsVersion { xsd:NMTOKEN }))?,
+         (element AccelerateBuildsInVisualStudio { xsd:boolean }
+          | element AnalysisMode { xsd:NCName }
+          | element CentralPackageTransitivePinningEnabled {
+              xsd:boolean
+            }
+          | element CodeAnalysisTreatWarningsAsErrors { xsd:boolean }
+          | element DefaultItemExcludes { text }
+          | element Deterministic { xsd:boolean }
+          | element EnableNETAnalyzers { xsd:boolean }
+          | element GenerateDocumentationFile { xsd:boolean }
+          | element ImplicitUsings { xsd:NCName }
+          | element IsPackable { xsd:boolean }
+          | element LangVersion { xsd:NCName }
+          | element ManagePackageVersionsCentrally { xsd:boolean }
+          | element NoWarn { text }
+          | element Nullable { xsd:NCName }
+          | element TreatWarningsAsErrors { xsd:boolean }
+          | element WarningsNotAsErrors { xsd:NMTOKEN })*,
+         (element AvaloniaVersion { xsd:NMTOKEN }
+          | element SatelliteResourceLanguages { xsd:NCName })?,
+         element ProduceReferenceAssembly { xsd:boolean }?,
+         (element DefaultDocumentationFolder { text },
+          element DefaultDocumentationLinksBaseUrl { text },
+          element DefaultDocumentationLinksOutputFile { text },
+          element DefaultDocumentationExternLinksFiles { text },
+          element DefaultDocumentationConfigurationFile { text })?,
+         element SignAssembly { xsd:boolean }?,
+         (element ContinuousIntegrationBuild { xsd:boolean }
+          | element NetSdk { xsd:NCName })?,
+         (element Product { text },
+          element Company { text },
+          element Copyright { text })?,
+         element AssemblyOriginatorKeyFile { text }?,
+         (element GenerateDocumentation { xsd:boolean }
+          | element RunSettingsFilePath { text }
+          | (element RunNswag { xsd:boolean },
+             element RunNodeBuild { xsd:boolean }))?
+       }
+     | element Target {
+         attribute BeforeTargets { xsd:NCName },
+         attribute Condition { text },
+         attribute Name { xsd:NCName },
+         element RemoveDir {
+           attribute Condition { text },
+           attribute Directories { text }
+         },
+         element Delete {
+           attribute Condition { text },
+           attribute Files { text }
+         }
+       })*
+  }
diff --git a/etc/schema/dotnet-packages-config.rnc b/etc/schema/dotnet-packages-config.rnc
new file mode 100644
index 00000000000..0e10e562b62
--- /dev/null
+++ b/etc/schema/dotnet-packages-config.rnc
@@ -0,0 +1,10 @@
+default namespace = ""
+
+start =
+  element packages {
+    element package {
+      attribute id { xsd:NCName },
+      attribute targetFramework { xsd:NCName }?,
+      attribute version { xsd:NMTOKEN }
+    }+
+  }
diff --git a/etc/schema/dotnet-packages-props.rnc b/etc/schema/dotnet-packages-props.rnc
new file mode 100644
index 00000000000..c91dea94c97
--- /dev/null
+++ b/etc/schema/dotnet-packages-props.rnc
@@ -0,0 +1,21 @@
+default namespace = ""
+
+start =
+  element Project {
+    element PropertyGroup {
+      element ManagePackageVersionsCentrally { xsd:boolean },
+      element CentralPackageTransitivePinningEnabled { xsd:boolean }
+    }?,
+    element ItemGroup {
+      attribute Condition { text }?,
+      (element GlobalPackageReference {
+         attribute Condition { text }?,
+         attribute Include { xsd:NCName },
+         attribute Version { xsd:NMTOKEN }
+       }+
+       | element PackageVersion {
+           attribute Include { xsd:NCName },
+           attribute Version { text }
+         }+)
+    }+
+  }
diff --git a/etc/schema/dotnet-resx.rnc b/etc/schema/dotnet-resx.rnc
new file mode 100644
index 00000000000..26b77e47527
--- /dev/null
+++ b/etc/schema/dotnet-resx.rnc
@@ -0,0 +1,57 @@
+default namespace = ""
+namespace msdata = "urn:schemas-microsoft-com:xml-msdata"
+namespace xsd = "http://www.w3.org/2001/XMLSchema"
+
+start =
+  element root {
+    element xsd:schema {
+      attribute id { xsd:NCName },
+      element xsd:import {
+        attribute namespace { xsd:anyURI }
+      }?,
+      xsd.element
+    },
+    element resheader {
+      attribute name { xsd:NCName },
+      value
+    }+,
+    (element assembly {
+       attribute alias { xsd:NCName },
+       attribute name { text }
+     }
+     | element data {
+         attribute mimetype { text }?,
+         attribute name { text },
+         attribute type { text }?,
+         attribute xml:space { xsd:NCName }?,
+         value
+       }
+     | element metadata {
+         attribute name { xsd:NCName },
+         attribute type { text },
+         value
+       })*
+  }
+xsd.element =
+  element xsd:element {
+    attribute minOccurs { xsd:integer }?,
+    attribute name { xsd:NCName },
+    attribute type { xsd:NMTOKEN }?,
+    attribute msdata:IsDataSet { xsd:boolean }?,
+    attribute msdata:Ordinal { xsd:integer }?,
+    element xsd:complexType {
+      element xsd:choice {
+        attribute maxOccurs { xsd:NCName },
+        xsd.element+
+      }?,
+      element xsd:sequence { xsd.element+ }?,
+      element xsd:attribute {
+        attribute name { xsd:NCName }?,
+        attribute ref { xsd:NMTOKEN }?,
+        attribute type { xsd:NMTOKEN }?,
+        attribute use { xsd:NCName }?,
+        attribute msdata:Ordinal { xsd:integer }?
+      }*
+    }*
+  }
+value = element value { text }
diff --git a/etc/schema/msbuild.rnc b/etc/schema/msbuild.rnc
new file mode 100644
index 00000000000..aa0139cb779
--- /dev/null
+++ b/etc/schema/msbuild.rnc
@@ -0,0 +1,905 @@
+default namespace = ""
+namespace ns1 = "http://schemas.microsoft.com/developer/msbuild/2003"
+
+start = Project | ns1.Project
+Project =
+  element Project {
+    attribute Sdk { text }?,
+    (text
+     | ItemGroup
+     | element Import {
+         attribute Project { text }
+       }
+     | element ProjectExtensions {
+         element VisualStudio {
+           element FlavorProperties {
+             attribute GUID { text },
+             element WebProjectProperties {
+               element UseIIS { xsd:NCName },
+               element AutoAssignPort { xsd:NCName },
+               element DevelopmentServerPort { xsd:integer },
+               element DevelopmentServerVPath { text },
+               element IISUrl { xsd:anyURI },
+               element NTLMAuthentication { xsd:NCName },
+               element UseCustomServer { xsd:NCName },
+               element CustomServerUrl { empty },
+               element SaveServerSettingsInUserFile { xsd:NCName }
+             }
+           }
+         }
+       }
+     | element PropertyGroup {
+         attribute Condition { text }?,
+         attribute Label { xsd:NCName }?,
+         element TargetFrameworks { text }?,
+         element ServiceName { xsd:NCName }?,
+         (element DeployDefaultTargetFrameworkVersion { xsd:decimal },
+          element VisualStudioVersion {
+            attribute Condition { text },
+            xsd:decimal
+          })?,
+         element ClientName { text }?,
+         (element DisableDataAnnotationsParam { text }
+          | element NSwagGenerateExceptionClasses { xsd:boolean })?,
+         element WrapResponseMethods { text }?,
+         (element NSwagOptions { text }
+          | element TargetsForTfmSpecificBuildOutput { text })?,
+         (element SoAssemblyFileVersion {
+            attribute Condition { text },
+            xsd:NMTOKEN
+          },
+          element SoReleaseVersion {
+            attribute Condition { text },
+            text
+          })?,
+         (element WebRoot { text },
+          element WebProjectFile { text },
+          element WebOutputPath { text })?,
+         (element ApiName {
+            attribute Condition { text },
+            xsd:NCName
+          }
+          | element AppConfig { xsd:NCName }
+          | element AppendTargetFrameworkToOutputPath { xsd:boolean }
+          | element ApplicationIcon { text }
+          | element ApplicationManifest { xsd:NCName }
+          | element AspNetCoreHostingModel { xsd:NCName }
+          | element AssemblyName { text }
+          | element AssemblyOriginatorKeyFile { text }
+          | element AssemblyTitle { text }
+          | element AssemblyVersion { xsd:NMTOKEN }
+          | element Authors { text }
+          | element AutoGenerateBindingRedirects {
+              attribute Condition { text }?,
+              xsd:boolean
+            }
+          | element AzureFunctionsVersion { xsd:NCName }
+          | element BicepCompileAfterTargets { xsd:NCName }
+          | element BicepCompileBeforeTargets { xsd:NCName }
+          | element BootstrapperEnabled { xsd:boolean }
+          | element BuildServerSideRenderer { xsd:boolean }
+          | element BuiltInComInteropSupport { xsd:boolean }
+          | element Company { text }
+          | element CopyLocalLockFileAssemblies { xsd:boolean }
+          | element Copyright { text }
+          | element DebugType {
+              attribute Condition { text }?,
+              xsd:NCName
+            }
+          | element DefaultItemExcludes { text }
+          | element DefineConstants { text }
+          | element DelaySign { xsd:boolean }
+          | element Description { text }
+          | element Deterministic { xsd:boolean }
+          | element DisableTransitiveProjectReferences { xsd:boolean }
+          | element DockerDefaultTargetOS { xsd:NCName }
+          | element DockerfileContext { text }
+          | element EmbedUntrackedSources { xsd:boolean }
+          | element EnableCompressionInSingleFile { xsd:boolean }
+          | element EnableDefaultCompileItems { xsd:boolean }
+          | element EnableDefaultEmbeddedResourceItems { xsd:boolean }
+          | element ErrorReport { xsd:NCName }
+          | element FileVersion { xsd:NMTOKEN }
+          | element FindInvalidProjectReferences { xsd:boolean }
+          | element GenerateAssemblyInfo { xsd:boolean }
+          | element GenerateBindingRedirectsOutputType { xsd:boolean }
+          | element GenerateDocumentationFile { xsd:NCName }
+          | element GeneratePackageOnBuild { xsd:NCName }
+          | element GenerateResourceUsePreserializedResources {
+              xsd:boolean
+            }
+          | element ImplicitUsings { xsd:NCName }
+          | element IncludeNativeLibrariesForSelfExtract { xsd:boolean }
+          | element IncludeSymbols { xsd:boolean }
+          | element IsPackable { xsd:boolean }
+          | element LangVersion { xsd:NMTOKEN }
+          | element MapFileExtensions { xsd:boolean }
+          | element NoWarn { text }
+          | element Nullable { xsd:NCName }
+          | element OutputPath { text }
+          | element OutputType { xsd:NCName }
+          | element PackageIcon { text }
+          | element PackageIconUrl { empty }
+          | element PackageId { text }
+          | element PackageLicenseFile { xsd:NCName }
+          | element PackageProjectUrl { xsd:anyURI }
+          | element PackageReleaseNotes { text }
+          | element PackageTags { text }
+          | element PlatformTarget { xsd:NCName }
+          | element Platforms { text }
+          | element Prefer32Bit { xsd:boolean }
+          | element ProduceReferenceAssembly { xsd:NCName }
+          | element Product { text }
+          | element ProjectGuid { text }
+          | element PublishRepositoryUrl { xsd:boolean }
+          | element PublishSingleFile { xsd:boolean }
+          | element RepositoryType { empty }
+          | element RepositoryUrl { empty }
+          | element RestoreProjectStyle { xsd:NCName }
+          | element RootNamespace { text }
+          | element RunPostBuildEvent { xsd:NCName }
+          | element RuntimeIdentifier { xsd:NCName }
+          | element RuntimeIdentifiers { text }
+          | element SatelliteResourceLanguages { xsd:NCName }
+          | element SelfContained { xsd:boolean }
+          | element SignAssembly { xsd:NCName }
+          | element SoVersionOptions { xsd:NCName }
+          | element SpaRoot { text }
+          | element Summary { text }
+          | element SupportedOSPlatformVersion { xsd:decimal }
+          | element SymbolPackageFormat { xsd:NCName }
+          | element TargetFramework { text }
+          | element Title { text }
+          | element TreatWarningsAsErrors { xsd:boolean }
+          | element TypeScriptCompileBlocked {
+              attribute Condition { text }?,
+              xsd:boolean
+            }
+          | element TypeScriptToolsVersion { xsd:NCName }
+          | element UseAppHost { xsd:boolean }
+          | element UseApplicationTrust { xsd:boolean }
+          | element UseWPF { xsd:boolean }
+          | element UseWindowsForms { xsd:boolean }
+          | element UserSecretsId { text }
+          | element Version { text }
+          | element WarningsAsErrors { empty }
+          | element WasmMainJSPath { text })*,
+         (element AvaloniaUseCompiledBindingsByDefault { xsd:boolean }
+          | element _FunctionsSkipCleanOutput { xsd:boolean }
+          | (element ApplicationId { xsd:NCName },
+             element ApplicationVersion { xsd:integer },
+             element ApplicationDisplayVersion { xsd:decimal },
+             element AndroidPackageFormat { xsd:NCName },
+             element AndroidEnableProfiledAot { xsd:NCName })
+          | (element OutDir { text },
+             element ExcludeXmlAssemblyFiles { xsd:boolean }))?,
+         element EnableUnsafeBinaryFormatterSerialization {
+           xsd:boolean
+         }?,
+         (element AssemblySearchPaths { text }
+          | element BaseOutputPath { text }
+          | element ContinuousIntegrationBuild { xsd:boolean }
+          | element DebugSymbols { xsd:boolean }
+          | element DefaultDocumentationIncludeUndocumentedItems {
+              xsd:boolean
+            }
+          | element DscZipFile { text }
+          | element IncludeAllContentForSelfExtract { xsd:boolean }
+          | element IsTestProject { xsd:boolean }
+          | element Optimize { xsd:boolean }
+          | element PackageRequireLicenseAcceptance { xsd:boolean }
+          | element ShouldIncludeNativeSkiaSharp { xsd:NCName }
+          | element StartupObject { xsd:NCName }
+          | (element SccProjectName { xsd:NCName },
+             element SccProvider { xsd:NCName },
+             element SccAuxPath { xsd:NCName },
+             element SccLocalPath { xsd:NCName })
+          | (element CFBundleName { text },
+             element CFBundleDisplayName { text },
+             element CFBundleIdentifier { xsd:NCName },
+             element CFBundleVersion { xsd:NMTOKEN },
+             element CFBundleShortVersionString { xsd:NMTOKEN },
+             element CFBundlePackageType { xsd:NCName },
+             element CFBundleExecutable { xsd:NCName },
+             element CFBundleIconFile { xsd:NCName },
+             element NSPrincipalClass { xsd:NCName },
+             element NSHighResolutionCapable { xsd:boolean }))?
+       }
+     | element Target {
+         attribute AfterTargets { xsd:NCName }?,
+         attribute BeforeTargets { xsd:NCName }?,
+         attribute Condition { text }?,
+         attribute DependsOnTargets { text }?,
+         attribute Inputs { text }?,
+         attribute Name { xsd:NCName },
+         attribute Outputs { text }?,
+         (ItemGroup
+          | element Error {
+              attribute Condition { text },
+              attribute Text { text }
+            }
+          | element Exec {
+              attribute Command { text },
+              attribute Condition { text }?,
+              attribute ContinueOnError { xsd:boolean }?,
+              attribute EnvironmentVariables { text }?,
+              attribute WorkingDirectory { text }?,
+              element Output {
+                attribute PropertyName { xsd:NCName },
+                attribute TaskParameter { xsd:NCName }
+              }?
+            }
+          | element MakeDir {
+              attribute Directories { text }
+            }
+          | element Message {
+              attribute Condition { text }?,
+              attribute Importance { xsd:NCName },
+              attribute Text { text }
+            })*,
+         (element Copy {
+            attribute DestinationFolder { text },
+            attribute SourceFiles { text }
+          }
+          | element MSBuild {
+              attribute BuildInParallel { xsd:boolean },
+              attribute Projects { text },
+              attribute Properties { text },
+              attribute Targets { xsd:NCName }
+            })?
+       })+
+  }
+ns1.Project =
+  element ns1:Project {
+    attribute DefaultTargets { xsd:NCName }?,
+    attribute ToolsVersion { xsd:decimal }?,
+    (text
+     | ns1.ItemGroup
+     | ns1.PropertyGroup
+     | element ns1:Choose {
+         element ns1:When {
+           attribute Condition { text },
+           (ns1.PropertyGroup | ns1.ItemGroup+)
+         }+,
+         element ns1:Otherwise { ns1.ItemGroup }?
+       }
+     | element ns1:Import {
+         attribute Condition { text }?,
+         attribute Label { xsd:NCName }?,
+         attribute Project { text }
+       }
+     | element ns1:ProjectExtensions {
+         element ns1:VisualStudio {
+           element ns1:FlavorProperties {
+             attribute GUID { text },
+             (element ns1:WebProjectProperties {
+                (element ns1:UseIIS { xsd:NCName },
+                 element ns1:AutoAssignPort { xsd:NCName },
+                 element ns1:DevelopmentServerPort { xsd:integer },
+                 element ns1:DevelopmentServerVPath { text },
+                 element ns1:IISUrl { xsd:anyURI },
+                 element ns1:NTLMAuthentication { xsd:NCName },
+                 element ns1:UseCustomServer { xsd:NCName },
+                 element ns1:CustomServerUrl { empty })?,
+                element ns1:SaveServerSettingsInUserFile { xsd:NCName }
+              }
+              | (element ns1:ProjectProperties {
+                   attribute AddItemTemplatesGuid { text },
+                   attribute ApplicationType { xsd:NCName },
+                   attribute DebugInfoExeName { text },
+                   attribute HostName { xsd:NCName },
+                   attribute HostPackage { text },
+                   attribute Language { xsd:NCName },
+                   attribute OfficeVersion { xsd:decimal },
+                   attribute TemplatesPath { xsd:NCName },
+                   attribute VstxVersion { xsd:decimal }
+                 },
+                 element ns1:Host {
+                   attribute GeneratedCodeNamespace { xsd:NCName },
+                   attribute IconIndex { xsd:integer },
+                   attribute Name { xsd:NCName },
+                   attribute PublishedHash { text },
+                   element ns1:HostItem {
+                     attribute Blueprint { xsd:NCName },
+                     attribute CanActivate { xsd:boolean },
+                     attribute CanonicalName { xsd:NCName },
+                     attribute Code { xsd:NCName },
+                     attribute GeneratedCode { xsd:NCName },
+                     attribute IconIndex { xsd:integer },
+                     attribute Name { xsd:NCName },
+                     attribute PublishedHash { text }
+                   }
+                 }))
+           }
+           | element ns1:UserProperties {
+               attribute Name { xsd:NCName }
+             }
+         }
+       }
+     | element ns1:Target {
+         attribute BeforeTargets { xsd:NCName }?,
+         attribute Condition { text }?,
+         attribute Name { xsd:NCName },
+         attribute Outputs { text }?,
+         (element ns1:Copy {
+            attribute ContinueOnError { xsd:boolean }?,
+            attribute DestinationFolder { text },
+            attribute OverwriteReadOnlyFiles { xsd:NCName },
+            attribute SourceFiles { text }
+          }
+          | element ns1:CreateItem {
+              attribute Exclude { text }?,
+              attribute Include { text },
+              ns1.Output
+            }
+          | element ns1:Delete {
+              attribute Files { text },
+              attribute TreatErrorsAsWarnings { xsd:NCName }
+            }
+          | element ns1:Exec {
+              attribute Command { text },
+              attribute WorkingDirectory { text }?
+            }
+          | element ns1:GetVersionParts {
+              attribute AssemblyPath { text },
+              ns1.Output+
+            }
+          | element ns1:Message {
+              attribute Importance { xsd:NCName }?,
+              attribute Text { text }
+            }
+          | element ns1:TokenReplace {
+              attribute Condition { text }?,
+              attribute Destination { text },
+              attribute Path { text },
+              attribute Replacement { text },
+              attribute Token { text }
+            })*,
+         (ns1.PropertyGroup
+          | element ns1:CallTarget {
+              attribute Condition { text }?,
+              attribute Targets { xsd:NCName }
+            }
+          | (ns1.ItemGroup
+             | element ns1:MakeDir {
+                 attribute Directories { text }
+               }
+             | element ns1:WriteCodeFragment {
+                 attribute AssemblyAttributes { text },
+                 attribute Language { text },
+                 attribute OutputFile { text }
+               })*
+          | element ns1:Error {
+              attribute Condition { text },
+              attribute HelpKeyword { xsd:NCName },
+              attribute Text { text }
+            }*)
+       }
+     | element ns1:UsingTask {
+         attribute AssemblyFile { text },
+         attribute TaskFactory { xsd:NCName },
+         attribute TaskName { xsd:NCName },
+         element ns1:ParameterGroup {
+           (element ns1:AssemblyPath {
+              attribute ParameterType { xsd:NCName },
+              attribute Required { xsd:boolean }
+            },
+            element ns1:MajorVersion {
+              attribute Output { xsd:boolean },
+              attribute ParameterType { xsd:NCName }
+            },
+            element ns1:MinorVersion {
+              attribute Output { xsd:boolean },
+              attribute ParameterType { xsd:NCName }
+            },
+            element ns1:BuildVersion {
+              attribute Output { xsd:boolean },
+              attribute ParameterType { xsd:NCName }
+            },
+            element ns1:RevisionVersion {
+              attribute Output { xsd:boolean },
+              attribute ParameterType { xsd:NCName }
+            })
+           | (element ns1:Path {
+                attribute ParameterType { xsd:NCName },
+                attribute Required { xsd:boolean }
+              },
+              element ns1:Destination {
+                attribute ParameterType { xsd:NCName },
+                attribute Required { xsd:boolean }
+              },
+              element ns1:Token {
+                attribute ParameterType { xsd:NCName },
+                attribute Required { xsd:boolean }
+              },
+              element ns1:Replacement {
+                attribute ParameterType { xsd:NCName },
+                attribute Required { xsd:boolean }
+              })
+         },
+         element ns1:Task {
+           element ns1:Using {
+             attribute Namespace { xsd:NCName }
+           }?,
+           element ns1:Code {
+             attribute Language { xsd:NCName },
+             attribute Type { xsd:NCName },
+             text
+           }
+         }
+       })+
+  }
+ItemGroup =
+  element ItemGroup {
+    attribute Condition { text }?,
+    element Using {
+      attribute Alias { xsd:NCName }?,
+      attribute Include { xsd:NCName }
+    }*,
+    element FrameworkReference {
+      attribute Include { xsd:NCName }
+    }?,
+    element _ReferenceCopyLocalPaths {
+      attribute Include { text }
+    }?,
+    element Bicep {
+      attribute Exclude { text }?,
+      attribute Include { text }?,
+      attribute OutputFile { text }?,
+      attribute Update { text }?,
+      element OutputFile { text }?
+    }*,
+    (element AndroidResource {
+       attribute Include { xsd:NCName },
+       Link
+     }
+     | element ApiClientGen {
+         attribute Include { xsd:NCName }
+       }
+     | element Bicepparam {
+         attribute Include { text }
+       }
+     | element BuildOutputInPackage {
+         attribute Include { text },
+         attribute TargetPath { text }
+       }
+     | element DesignData {
+         attribute Include { text }
+       }
+     | element Service {
+         attribute Include { text }
+       }
+     | (element DistFiles {
+          attribute Condition { text }?,
+          attribute Include { text }
+        }+,
+        element ResolvedFileToPublish {
+          attribute Exclude { text },
+          attribute Include { text },
+          element RelativePath { text },
+          CopyToPublishDirectory,
+          ExcludeFromSingleFile?
+        })
+     | element ClaimsRequirement {
+         attribute Include { xsd:NCName }
+       }*
+     | element DocumentName {
+         attribute Include { xsd:NCName }
+       }*
+     | element Folder {
+         attribute Include { text }
+       }*
+     | element Watch {
+         attribute Exclude { text }?,
+         attribute Include { text }?,
+         attribute Remove { text }?
+       }*
+     | element OpenApiReference {
+         attribute ClassName { text }?,
+         attribute Include { text },
+         attribute Namespace { text }?,
+         attribute Options { text }?,
+         element CodeGenerator { xsd:NCName }?
+       }*),
+    element WCFMetadata {
+      attribute Include { text }
+    }?,
+    (element AdditionalFiles {
+       attribute Remove { text }
+     }
+     | element ProjectsToPublish {
+         attribute Include { text }
+       })?,
+    (element Compile {
+       attribute Include { text }?,
+       attribute Link { xsd:NCName }?,
+       attribute Remove { text }?,
+       attribute Update { text }?,
+       Link?,
+       (DependentUpon
+        | element AutoGen { xsd:NCName }
+        | element DesignTime { xsd:NCName })*,
+       (SubType
+        | element DesignTimeSharedInput { xsd:NCName })?
+     }
+     | element Content {
+         attribute CopyToOutputDirectory { xsd:NCName }?,
+         attribute CopyToPublishDirectory { xsd:NCName }?,
+         attribute Exclude { text }?,
+         attribute Include { text }?,
+         attribute Link { text }?,
+         attribute Remove { text }?,
+         attribute Update { text }?,
+         Link?,
+         (CopyToOutputDirectory
+          | CopyToPublishDirectory
+          | DependentUpon
+          | ExcludeFromSingleFile
+          | SubType)*
+       }
+     | element EmbeddedResource {
+         attribute Condition { text }?,
+         attribute Include { text }?,
+         attribute Link { text }?,
+         attribute LogicalName { xsd:NCName }?,
+         attribute Remove { text }?,
+         attribute Update { text }?,
+         (CopyToOutputDirectory
+          | Link
+          | element LogicalName { text })?,
+         element CustomToolNamespace { xsd:NCName }?,
+         (Generator, LastGenOutput)?,
+         (DependentUpon | SubType)?
+       }
+     | element None {
+         attribute CopyToOutputDirectory { xsd:NCName }?,
+         attribute CopyToPublishDirectory { xsd:NCName }?,
+         attribute Exclude { text }?,
+         attribute Include { text }?,
+         attribute Link { xsd:NCName }?,
+         attribute Remove { text }?,
+         attribute Update { text }?,
+         (DependentUpon | SubType)?,
+         Generator?,
+         (LastGenOutput
+          | (element Pack { xsd:NCName }
+             | element PackagePath { empty })*),
+         CopyToOutputDirectory?,
+         CopyToPublishDirectory?
+       }
+     | element Resource {
+         attribute Include { text }
+       }
+     | element WCFMetadataStorage {
+         attribute Include { text }
+       })*,
+    (element AvaloniaXaml {
+       attribute Remove { text }
+     }
+     | element COMReference {
+         attribute Include { xsd:NCName },
+         element Guid { text },
+         element VersionMajor { xsd:integer },
+         element VersionMinor { xsd:integer },
+         element Lcid { xsd:integer },
+         element WrapperTool { xsd:NCName },
+         element Isolated { xsd:NCName },
+         EmbedInteropTypes
+       }
+     | element WasmExtraFilesToDeploy {
+         attribute Include { text }
+       }
+     | element ApiClient {
+         attribute Include { xsd:NCName }
+       }*
+     | (element PackageDownload {
+          attribute Include { xsd:NCName },
+          attribute Version { text }
+        }
+        | element PackageReference {
+            attribute Condition { text }?,
+            attribute ExcludeAssets { xsd:NCName }?,
+            attribute Include { xsd:NCName },
+            attribute PrivateAssets { xsd:NCName }?,
+            attribute Version { text }?,
+            (element IncludeAssets { text }
+             | element PrivateAssets { xsd:NCName })*
+          }
+        | element ProjectReference {
+            attribute Include { text }?,
+            attribute PrivateAssets { xsd:NCName }?,
+            attribute Remove { xsd:NCName }?,
+            (element Properties { text }
+             | (Project,
+                element Name { xsd:NCName }))?
+          }
+        | element Reference {
+            attribute Include { text },
+            (EmbedInteropTypes
+             | element HintPath {
+                 attribute Condition { text }?,
+                 text
+               }
+             | element Private { xsd:NCName }
+             | element SpecificVersion { xsd:NCName })*
+          })*
+     | element AvaloniaResource {
+         attribute Include { text }?,
+         attribute Remove { text }?
+       }*
+     | element TypeScriptCompile {
+         attribute Include { text }?,
+         attribute Remove { text }?,
+         DependentUpon?
+       }*
+     | element Page {
+         attribute Generator { xsd:NMTOKEN }?,
+         attribute Include { text }?,
+         attribute Remove { text }?,
+         attribute SubType { xsd:NCName }?
+       }*)
+  }
+ns1.PropertyGroup =
+  element ns1:PropertyGroup {
+    attribute Condition { text }?,
+    element ns1:__paket__MSTest_TestAdapter_props { text }?,
+    (element ns1:ApplicationManifest { xsd:NCName }
+     | element ns1:__paket__MSTest_TestAdapter_targets { text })?,
+    (element ns1:NugetFolder { text },
+     element ns1:BuildFolder { text })?,
+    element ns1:SoReleaseVersion { text }?,
+    element ns1:__paket__MSTest_TestFramework_targets { text }?,
+    element ns1:SoLegacyVersion { xsd:NCName }?,
+    element ns1:SoBetaTag { empty }?,
+    element ns1:ComputerName { text }?,
+    (element ns1:AppDesignerFolder { xsd:NCName }
+     | element ns1:ApplicationRevision { xsd:integer }
+     | element ns1:ApplicationVersion { text }
+     | element ns1:AssemblyName { xsd:NCName }
+     | element ns1:AssemblyOriginatorKeyFile { text }
+     | element ns1:AutoGenerateBindingRedirects { xsd:boolean }
+     | element ns1:AutoIncrementApplicationRevision { xsd:boolean }
+     | element ns1:BootstrapperEnabled { xsd:boolean }
+     | element ns1:CodeAnalysisRuleSet { xsd:NCName }
+     | element ns1:Configuration {
+         attribute Condition { text },
+         xsd:NCName
+       }
+     | element ns1:DebugSymbols { xsd:boolean }
+     | element ns1:DebugType { xsd:NCName }
+     | element ns1:DefineConstants { text }
+     | element ns1:DependsOnNETStandard { xsd:NCName }
+     | element ns1:Deterministic { xsd:boolean }
+     | element ns1:DocumentationFile { text }
+     | element ns1:EnableUnmanagedDebugging { xsd:boolean }
+     | element ns1:ErrorReport { xsd:NCName }
+     | element ns1:FileAlignment { xsd:integer }
+     | element ns1:FileUpgradeFlags { empty }
+     | element ns1:FindInvalidProjectReferences { xsd:boolean }
+     | element ns1:FriendlyName { xsd:NCName }
+     | element ns1:GenerateBindingRedirectsOutputType { xsd:boolean }
+     | element ns1:IISExpressAnonymousAuthentication { empty }
+     | element ns1:IISExpressSSLPort { text }
+     | element ns1:IISExpressUseClassicPipelineMode { empty }
+     | element ns1:IISExpressWindowsAuthentication { empty }
+     | element ns1:Install { xsd:boolean }
+     | element ns1:InstallFrom { xsd:NCName }
+     | element ns1:InstallUrl { empty }
+     | element ns1:IsCodedUITest { xsd:NCName }
+     | element ns1:IsWebBootstrapper { xsd:NCName }
+     | element ns1:LoadBehavior { xsd:integer }
+     | element ns1:ManifestCertificateThumbprint { text }
+     | element ns1:ManifestKeyFile { text }
+     | element ns1:MapFileExtensions { xsd:boolean }
+     | element ns1:NoStandardLibraries { xsd:boolean }
+     | element ns1:NoWarn { text }
+     | element ns1:NuGetPackageImportStamp { empty }
+     | element ns1:NugetExe { text }
+     | element ns1:OfficeApplicationDescription { empty }
+     | element ns1:OldToolsVersion { xsd:decimal }
+     | element ns1:Optimize { xsd:boolean }
+     | element ns1:OutputPath { text }
+     | element ns1:OutputType { xsd:NCName }
+     | element ns1:PackageDestinationDirectory { text }
+     | element ns1:Platform {
+         attribute Condition { text },
+         xsd:NCName
+       }
+     | element ns1:PlatformTarget { xsd:NCName }
+     | element ns1:Prefer32Bit { xsd:boolean }
+     | element ns1:ProductName { xsd:NCName }
+     | element ns1:ProductVersion { text }
+     | element ns1:ProjectGuid { text }
+     | element ns1:ProjectTypeGuids { text }
+     | element ns1:PublishUrl { text }
+     | element ns1:PublisherName { empty }
+     | element ns1:ReferencePath { text }
+     | element ns1:RestorePackages { xsd:boolean }
+     | element ns1:RootNamespace { xsd:NCName }
+     | element ns1:RunPostBuildEvent { xsd:NCName }
+     | element ns1:SccAuxPath { xsd:anyURI }
+     | element ns1:SccLocalPath { xsd:NMTOKEN }
+     | element ns1:SccProjectName { text }
+     | element ns1:SccProvider { text }
+     | element ns1:SchemaVersion { xsd:decimal }
+     | element ns1:SignAssembly { xsd:boolean }
+     | element ns1:SignManifests { xsd:boolean }
+     | element ns1:SolutionDir {
+         attribute Condition { text },
+         text
+       }
+     | element ns1:StartupObject { empty }
+     | element ns1:SuperOfficeBuildVersion { xsd:NMTOKEN }
+     | element ns1:SuperOfficeDir { text }
+     | element ns1:SuperOfficeTargetDir { text }
+     | element ns1:SupportUrl { empty }
+     | element ns1:TargetCulture { xsd:NCName }
+     | element ns1:TargetFrameworkProfile { text }
+     | element ns1:TargetFrameworkVersion { xsd:NCName }
+     | element ns1:TestProjectType { xsd:NCName }
+     | element ns1:TypeScriptCompileBlocked { xsd:boolean }
+     | element ns1:TypeScriptToolsVersion { xsd:decimal }
+     | element ns1:UpdateEnabled { xsd:boolean }
+     | element ns1:UpdateInterval { xsd:integer }
+     | element ns1:UpdateIntervalUnits { xsd:NCName }
+     | element ns1:UpdateMode { xsd:NCName }
+     | element ns1:UpdatePeriodically { xsd:boolean }
+     | element ns1:UpdateRequired { xsd:boolean }
+     | element ns1:UpgradeBackupLocation { empty }
+     | element ns1:Use64BitIISExpress { empty }
+     | element ns1:UseApplicationTrust { xsd:boolean }
+     | element ns1:UseGlobalApplicationHostFile { empty }
+     | element ns1:UseIISExpress { xsd:boolean }
+     | element ns1:UseVSHostingProcess { xsd:boolean }
+     | element ns1:VSTO_TrustAssembliesLocation { xsd:boolean }
+     | element ns1:VSToolsPath {
+         attribute Condition { text },
+         text
+       }
+     | element ns1:VisualStudioVersion {
+         attribute Condition { text },
+         xsd:decimal
+       }
+     | element ns1:WarningLevel { xsd:integer }
+     | element ns1:WcfConfigValidationEnabled { xsd:NCName })*,
+    (element ns1:ApplicationIcon { xsd:NCName }
+     | element ns1:ErrorText { text }
+     | element ns1:RuntimeIdentifier { xsd:NCName })?,
+    element ns1:PreBuildEvent {
+      attribute Condition { text }?,
+      text
+    }?,
+    (element ns1:OfficeApplication { xsd:NCName }
+     | element ns1:__paket__NETStandard_Library_targets { text }
+     | element ns1:PostBuildEvent {
+         attribute Condition { text }?,
+         text
+       }*)
+  }
+ns1.ItemGroup =
+  element ns1:ItemGroup {
+    (element ns1:AssemblyAttributes {
+       attribute Include { xsd:NCName },
+       element ns1:_Parameter1 { text }
+     }
+     | element ns1:COMReference {
+         attribute Include { xsd:NCName },
+         element ns1:Guid { text },
+         element ns1:VersionMajor { xsd:integer },
+         element ns1:VersionMinor { xsd:integer },
+         element ns1:Lcid { xsd:integer },
+         element ns1:WrapperTool { xsd:NCName },
+         element ns1:Isolated { xsd:NCName },
+         ns1.EmbedInteropTypes
+       }
+     | element ns1:CodeAnalysisDependentAssemblyPaths {
+         attribute Condition { text },
+         attribute Include { text },
+         element ns1:Visible { xsd:NCName }
+       }
+     | element ns1:PackageSourceDirectory {
+         attribute Include { text }
+       }
+     | element ns1:WCFMetadata {
+         attribute Include { text }
+       }
+     | element ns1:Page {
+         attribute Include { text },
+         ns1.Generator,
+         ns1.SubType
+       }*
+     | element ns1:Analyzer {
+         attribute Include { text },
+         ns1.Paket
+       }*
+     | element ns1:Folder {
+         attribute Include { text }
+       }*
+     | element ns1:Service {
+         attribute Include { text }
+       }*
+     | element ns1:PackageReference {
+         attribute Include { xsd:NCName },
+         element ns1:Version { xsd:NMTOKEN }?
+       }*
+     | element ns1:ProjectReference {
+         attribute Include { text },
+         ns1.Project,
+         element ns1:Name { xsd:NCName }
+       }*),
+    element ns1:ApplicationDefinition {
+      attribute Include { xsd:NCName },
+      ns1.Generator,
+      ns1.SubType
+    }?,
+    (element ns1:WebReferences {
+       attribute Include { text }
+     }
+     | element ns1:Reference {
+         attribute Include { text },
+         element ns1:SpecificVersion { xsd:NCName }?,
+         ns1.EmbedInteropTypes?,
+         element ns1:HintPath { text }?,
+         element ns1:Private { xsd:NCName }?,
+         (ns1.Paket
+          | element ns1:RequiredTargetFramework { xsd:decimal })?
+       }*),
+    (element ns1:Compile {
+       attribute Include { text },
+       element ns1:AutoGen { xsd:NCName }?,
+       ns1.Link?,
+       (ns1.DependentUpon
+        | element ns1:DesignTime { xsd:NCName }
+        | element ns1:DesignTimeSharedInput { xsd:NCName })*,
+       ns1.SubType?
+     }
+     | element ns1:Content {
+         attribute Include { text },
+         (ns1.DependentUpon | ns1.SubType)?
+       }
+     | element ns1:EmbeddedResource {
+         attribute Include { text },
+         (ns1.Generator, ns1.LastGenOutput)?,
+         (ns1.DependentUpon | ns1.SubType)?
+       }
+     | element ns1:EntityDeploy {
+         attribute Include { xsd:NCName },
+         ns1.Generator,
+         ns1.LastGenOutput
+       }
+     | element ns1:None {
+         attribute Include { text },
+         element ns1:CopyToOutputDirectory { xsd:NCName }?,
+         ns1.Link?,
+         (ns1.Generator, ns1.LastGenOutput)?,
+         (ns1.DependentUpon | ns1.SubType)?
+       })*,
+    (element ns1:AppDesigner {
+       attribute Include { text }
+     }
+     | element ns1:Resource {
+         attribute Include { text }
+       }*)
+  }
+ns1.Output =
+  element ns1:Output {
+    attribute ItemName { xsd:NCName }?,
+    attribute PropertyName { xsd:NCName }?,
+    attribute TaskParameter { xsd:NCName }
+  }
+CopyToPublishDirectory = element CopyToPublishDirectory { xsd:NCName }
+ExcludeFromSingleFile = element ExcludeFromSingleFile { xsd:boolean }
+Link = element Link { text }
+SubType = element SubType { text }
+DependentUpon = element DependentUpon { text }
+Generator = element Generator { text }
+LastGenOutput = element LastGenOutput { xsd:NCName }
+CopyToOutputDirectory = element CopyToOutputDirectory { xsd:NCName }
+EmbedInteropTypes = element EmbedInteropTypes { xsd:NCName }
+ns1.Generator = element ns1:Generator { xsd:NMTOKEN }
+ns1.SubType = element ns1:SubType { xsd:NCName }
+ns1.EmbedInteropTypes = element ns1:EmbedInteropTypes { xsd:NCName }
+ns1.Paket = element ns1:Paket { xsd:NCName }
+ns1.DependentUpon = element ns1:DependentUpon { xsd:NCName }
+ns1.Link = element ns1:Link { text }
+ns1.LastGenOutput = element ns1:LastGenOutput { xsd:NCName }
diff --git a/etc/schema/nuget.rnc b/etc/schema/nuget.rnc
new file mode 100644
index 00000000000..ab7052e91d1
--- /dev/null
+++ b/etc/schema/nuget.rnc
@@ -0,0 +1,25 @@
+default namespace = ""
+
+start =
+  element configuration {
+    element packageRestore { add+ }?,
+    (element config { add }
+     | element packageSourceMapping {
+         element packageSource {
+           attribute key { xsd:NCName },
+           element package {
+             attribute pattern { text }
+           }
+         }+
+       }
+     | element packageSources {
+         element clear { empty },
+         add+
+       })+
+  }
+add =
+  element add {
+    attribute key { xsd:NCName },
+    attribute protocolVersion { xsd:integer }?,
+    attribute value { xsd:anyURI }
+  }
diff --git a/etc/schema/nuspec.rnc b/etc/schema/nuspec.rnc
new file mode 100644
index 00000000000..a4332f84fc0
--- /dev/null
+++ b/etc/schema/nuspec.rnc
@@ -0,0 +1,100 @@
+namespace a = "http://relaxng.org/ns/compatibility/annotations/1.0"
+default namespace mstns = "http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"
+namespace rng = "http://relaxng.org/ns/structure/1.0"
+
+dependency =
+  attribute id { xsd:string },
+  attribute version { xsd:string }?,
+  attribute include { xsd:string }?,
+  attribute exclude { xsd:string }?
+dependencyGroup =
+  element dependency { dependency }*,
+  attribute targetFramework { xsd:string }?
+reference = attribute file { xsd:string }
+contentFileEntries =
+  attribute include { xsd:string },
+  attribute exclude { xsd:string }?,
+  attribute buildAction { xsd:string }?,
+  attribute copyToOutput { xsd:boolean }?,
+  attribute flatten { xsd:boolean }?
+referenceGroup =
+  element reference { reference }+,
+  attribute targetFramework { xsd:string }?
+frameworkReference = attribute name { xsd:string }
+frameworkReferenceGroup =
+  element frameworkReference { frameworkReference }*,
+  attribute targetFramework { xsd:string }
+start |= starting_package
+starting_package =
+  element package {
+    element metadata {
+      (element id { xsd:string }
+       & element version { xsd:string }
+       & element title { xsd:string }?
+       & element authors { xsd:string }
+       & element owners { xsd:string }?
+       & element licenseUrl { xsd:anyURI }?
+       & element projectUrl { xsd:anyURI }?
+       & element iconUrl { xsd:anyURI }?
+       & element requireLicenseAcceptance { xsd:boolean }?
+       & element developmentDependency { xsd:boolean }?
+       & element description { xsd:string }
+       & element summary { xsd:string }?
+       & element releaseNotes { xsd:string }?
+       & (element copyright { xsd:string }?)
+         >> a:documentation [
+              "\x{a}" ~
+              "            default value is : en-US"
+            ]
+       & element language { xsd:string }?
+       & element tags { xsd:string }?
+       & element serviceable { xsd:boolean }?
+       & element icon { xsd:string }?
+       & element readme { xsd:string }?
+       & element repository {
+           attribute type { xsd:string }?,
+           attribute url { xsd:anyURI }?,
+           attribute branch { xsd:string }?,
+           attribute commit { xsd:string }?
+         }?
+       & element license {
+           xsd:string,
+           attribute type { xsd:string },
+           attribute version { xsd:string }?
+         }?
+       & element packageTypes {
+           element packageType {
+             attribute name { xsd:string },
+             attribute version { xsd:string }?
+           }*
+         }?
+       & element dependencies {
+           (element dependency { dependency }
+            | element group { dependencyGroup })*
+         }?
+       & element frameworkAssemblies {
+           element frameworkAssembly {
+             attribute assemblyName { xsd:string },
+             attribute targetFramework { xsd:string }?
+           }*
+         }?
+       & element frameworkReferences {
+           element group { frameworkReferenceGroup }*
+         }?
+       & element references {
+           (element reference { reference }
+            | element group { referenceGroup })*
+         }?
+       & element contentFiles {
+           (element files { contentFileEntries })*
+         }?),
+      attribute minClientVersion { xsd:string }?
+    },
+    element files {
+      element file {
+        attribute src { xsd:string },
+        attribute target { xsd:string }?,
+        attribute exclude { xsd:string }?
+      }*
+    }?
+  }
diff --git a/etc/schema/schemas.xml b/etc/schema/schemas.xml
index f04bba849b4..23a23adcbab 100644
--- a/etc/schema/schemas.xml
+++ b/etc/schema/schemas.xml
@@ -66,4 +66,33 @@
   <typeId id="LibreOffice" uri="OpenDocument-schema-v1.3+libreoffice.rnc"/>
   <typeId id="OpenDocument Manifest" uri="od-manifest-schema-v1.2-os.rnc"/>
 
+  <!-- .net development related schemas -->
+  <uri pattern="nuget.config" typeId="Nuget Config" />
+  <typeId id="Nuget Config" uri="nuget.rnc" />
+
+  <uri pattern="*.nuspec" typeId="Nuget Spec" />
+  <namespace ns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd" typeId="Nuget Spec" />
+  <typeId id="Nuget Spec" uri="nuspec.rnc" />
+
+  <uri pattern="web.config" typeId="Dotnet App Config" />
+  <uri pattern="app.config" typeId="Dotnet App Config" />
+  <namespace ns="http://schemas.microsoft.com/.NetConfiguration/v2.0" typeId="Dotnet App Config" />
+  <typeId id="Dotnet App Config" uri="dotnet-appconfig.rnc" />
+
+  <uri pattern="Directory.Build.props" typeId="Dotnet Build Props" />
+  <typeId id="Dotnet Build Props" uri="dotnet-build-props.rnc" />
+
+  <uri pattern="Directory.Packages.props" typeId="Dotnet Packages Props" />
+  <typeId id="Dotnet Packages Props" uri="dotnet-packages-props.rnc" />
+
+  <uri pattern="packages.config" typeId="Dotnet Packages Config" />
+  <typeId id="Dotnet Packages Config" uri="dotnet-packages-config.rnc" />
+
+  <uri pattern="*.resx" typeId="Dotnet Resx" />
+  <typeId id="Dotnet Resx" uri="dotnet-resx.rnc" />
+
+  <uri pattern="*.*proj" typeId="MSBuild" />
+  <documentElement localName="Project" typeId="MSBuild"/>
+  <typeId id="MSBuild" uri="msbuild.rnc" />
+
 </locatingRules>
-- 
2.39.3 (Apple Git-145)


[-- Attachment #2.3: Type: text/html, Size: 212 bytes --]

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] Adding new schemas to nxml-mode
  2024-02-20 20:02   ` [PATCH] Adding new schemas to nxml-mode Jostein Kjønigsen
@ 2024-02-21  3:01     ` Stefan Kangas
  2024-02-22 15:13       ` Jostein Kjønigsen
  0 siblings, 1 reply; 7+ messages in thread
From: Stefan Kangas @ 2024-02-21  3:01 UTC (permalink / raw)
  To: Jostein Kjønigsen; +Cc: emacs-devel, Stefan Monnier

Jostein Kjønigsen <jostein@secure.kjonigsen.net> writes:

> With those encouraging words, I guess there’s no reason to be mucking
> about then.

Great!

> Attached is the patch with all schemas, and mappings for Emacs to
> apply them.

Thanks, please find some comments below.

> Basically as a minimum make sure it works for more people than just me.

What happens if it doesn't "work" in this context?  Can it hurt or is it
just an extra feature that they won't benefit from?

> From 318bc52c24308095662694aaea0feb2e4d640b32 Mon Sep 17 00:00:00 2001
> From: =?UTF-8?q?Jostein=20Kj=C3=B8nigsen?= <jostein@kjonigsen.net>
> Date: Thu, 15 Feb 2024 21:54:14 +0100
> Subject: [PATCH] nxml-mode: Add schemas for .net related development
>  file-formats
>
> - MSBuild project files
> - Dotnet build properties files
> - Dotnet package properties files
> - Dotnet resource extension files
> - Dotnet Application config files
> - Nuget config file
> - Nuget package specification file
> - Nuget packages config file

- I think this should also come with updates to etc/schemas/README
  describing the copyright and legal status of these new schemas.
  See that file to get an idea of what's needed.
- Does "Dotnet" also include "Mono" (or some other free software
  replacement)?  If yes, I think the commit message should say so
  explicitly, so that we mention both but advertise mainly the free
  version.  I.e. it should say "Mono/Dotnet" rather than "Dotnet/Mono".
- Should this be called out in NEWS?
- (This should also have a proper ChangeLog in the commit message, of
  course.)



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Adding new schemas to nxml-mode
  2024-02-21  3:01     ` Stefan Kangas
@ 2024-02-22 15:13       ` Jostein Kjønigsen
  2024-02-23 14:25         ` Jostein Kjønigsen
  0 siblings, 1 reply; 7+ messages in thread
From: Jostein Kjønigsen @ 2024-02-22 15:13 UTC (permalink / raw)
  To: Stefan Kangas; +Cc: Ergus via Emacs development discussions., Stefan Monnier

[-- Attachment #1: Type: text/plain, Size: 2750 bytes --]



> On 21 Feb 2024, at 04:01, Stefan Kangas <stefankangas@gmail.com> wrote:
> 
>> Basically as a minimum make sure it works for more people than just me.
> 
> What happens if it doesn't "work" in this context?  Can it hurt or is it
> just an extra feature that they won't benefit from?

In terms of “working" I would consider the following:

* The appropriate schemas are activated for the appropriate and expected files.
* The schemas, when activated, do not create warnings for correctly formatted XML-files (according to that schema).

In terms of NOT working, I would consider the following:

* A schema is activated for a file which it is not appropriate for.
* A schema, when activated for an appropriate file-type, flags correctly formatted XML-elements within that file as erroneous.

> - I think this should also come with updates to etc/schemas/README
>  describing the copyright and legal status of these new schemas.
>  See that file to get an idea of what's needed.

I didn't know about that one. Will look into it!

> - Does "Dotnet" also include "Mono" (or some other free software
>  replacement)?  If yes, I think the commit message should say so
>  explicitly, so that we mention both but advertise mainly the free
>  version.  I.e. it should say "Mono/Dotnet" rather than "Dotnet/Mono".

Not going to go for a technical deep dive here, but in short:

- .NET Framework was a closed-source Windows only development platform created by Microsoft
- Mono is a open-source cross-platform reimplementation of .NET Framework

Today when one refers to .NET when typically refers to the “new” modern .NET project (with no “framework” suffix), which is both open-source and cross-platform. Modern .NET supersedes .NET Framework, and in many ways Mono as well.

While all file-types covered by schemas submitted here are relevant/applicable to all those three development platforms, as they all work on the same type of source-files and build-systems… I would argue that the “main” development target these days for any developer working on up to date tooling is going to be .NET, not Mono. As such, I think just referring to it as dotnet is appropriate.

> - Should this be called out in NEWS?

It could. I have no opinion on how “big” a feature/change has to be before it’s considered newsworthy.

I’ll let more seasoned Emacs-contributors decide that, if that’s OK.

> - (This should also have a proper ChangeLog in the commit message, of
>  course.)


I thought I added a pretty decent one in my commit… Was that not included in the patch?

Or do you mean adding it to a ChangeLog file of some sort? If so, which one?


—
Kind Regards
Jostein Kjønigsen

[-- Attachment #2: Type: text/html, Size: 3766 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] Adding new schemas to nxml-mode
  2024-02-22 15:13       ` Jostein Kjønigsen
@ 2024-02-23 14:25         ` Jostein Kjønigsen
  2024-05-18 19:48           ` Stefan Kangas
  0 siblings, 1 reply; 7+ messages in thread
From: Jostein Kjønigsen @ 2024-02-23 14:25 UTC (permalink / raw)
  To: Stefan Kangas; +Cc: Ergus via Emacs development discussions., Stefan Monnier

[-- Attachment #1: Type: text/plain, Size: 144 bytes --]

This latest patch addresses the copyright/readme issue, and also tweaks the schemas slightly after I've found a few inconsistencies locally.


[-- Attachment #2: 0001-nxml-mode-Add-schemas-for-.net-related-development-f.patch --]
[-- Type: application/octet-stream, Size: 69294 bytes --]

From cab2e11165a05a6df94724c301ccd12bb7038a83 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jostein=20Kj=C3=B8nigsen?= <jostein@kjonigsen.net>
Date: Thu, 15 Feb 2024 21:54:14 +0100
Subject: [PATCH] nxml-mode: Add schemas for .net related development
 file-formats

- MSBuild project files
- Dotnet package properties files
- Dotnet resource extension files
- Dotnet Application config files
- Nuget config file
- Nuget package specification file
- Nuget packages config file
---
 etc/schema/README                     |   20 +
 etc/schema/dotnet-appconfig.rnc       |  411 ++++++++++
 etc/schema/dotnet-packages-config.rnc |   11 +
 etc/schema/dotnet-packages-props.rnc  |   22 +
 etc/schema/dotnet-resx.rnc            |   57 ++
 etc/schema/msbuild.rnc                | 1041 +++++++++++++++++++++++++
 etc/schema/nuget.rnc                  |   25 +
 etc/schema/nuspec.rnc                 |  100 +++
 etc/schema/schemas.xml                |   27 +
 9 files changed, 1714 insertions(+)
 create mode 100644 etc/schema/dotnet-appconfig.rnc
 create mode 100644 etc/schema/dotnet-packages-config.rnc
 create mode 100644 etc/schema/dotnet-packages-props.rnc
 create mode 100644 etc/schema/dotnet-resx.rnc
 create mode 100644 etc/schema/msbuild.rnc
 create mode 100644 etc/schema/nuget.rnc
 create mode 100644 etc/schema/nuspec.rnc

diff --git a/etc/schema/README b/etc/schema/README
index 08dfe45dfbb..7611652762c 100644
--- a/etc/schema/README
+++ b/etc/schema/README
@@ -113,3 +113,23 @@ Software License:
   specific, written prior permission. Title to copyright in this
   software and any associated documentation will at all times remain
   with copyright holders.
+
+
+The following files are related to .NET development:
+
+  dotnet-appconfig.rnc dotnet-packages-config.rnc
+  dotnet-packages.props dotnet-resx.rnc msbuild.rnc nuget.rnc
+  nuspec.rnc
+
+These files are derived/inferred from files from numerous .NET projects,
+whose contents have been created based on public documentation provided
+by Microsoft, or created using the documentation as is.
+
+Links to various related resources:
+- app.config: https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/
+- Directory.Packages.Props: https://learn.microsoft.com/en-us/nuget/consume-packages/central-package-management
+- MSBuild: https://learn.microsoft.com/en-us/visualstudio/msbuild
+- Nuspec: https://learn.microsoft.com/en-us/nuget/reference/nuspec
+- Nuget.config: https://learn.microsoft.com/en-us/nuget/reference/nuget-config-file
+- Packages.config: https://learn.microsoft.com/en-us/nuget/reference/packages-config
+- Resx: Xsd-schema as included in default Resx-files generated by Resxen.exe
diff --git a/etc/schema/dotnet-appconfig.rnc b/etc/schema/dotnet-appconfig.rnc
new file mode 100644
index 00000000000..7e108672ed9
--- /dev/null
+++ b/etc/schema/dotnet-appconfig.rnc
@@ -0,0 +1,411 @@
+default namespace = ""
+namespace ns1 = "http://schemas.microsoft.com/.NetConfiguration/v2.0"
+namespace ns2 = "urn:schemas-microsoft-com:asm.v1"
+namespace xdt = "http://schemas.microsoft.com/XML-Document-Transform"
+
+start =
+  element configuration {
+    element configSections { (section | sectionGroup)* }?,
+    element system.web.webPages.razor {
+      element host {
+        attribute factoryType { text }
+      },
+      pages
+    }?,
+    (system.web
+     | system.webServer
+     | element location {
+         attribute inheritInChildApplications { xsd:boolean }?,
+         attribute path { text }?,
+         system.web?,
+         system.webServer?
+       }
+     | element runtime {
+         element loadFromRemoteSources {
+           attribute enabled { xsd:boolean }
+         }?,
+         element ns2:assemblyBinding {
+           attribute appliesTo { xsd:NCName }?,
+           element ns2:dependentAssembly {
+             element ns2:Paket { xsd:NCName }?,
+             element ns2:assemblyIdentity {
+               attribute culture { xsd:NCName }?,
+               attribute name { xsd:NCName },
+               attribute publicKeyToken { xsd:NMTOKEN }
+             },
+             element ns2:bindingRedirect {
+               attribute newVersion { xsd:NMTOKEN },
+               attribute oldVersion { xsd:NMTOKEN }
+             }
+           }+
+         }+
+       }
+     | element startup {
+         attribute useLegacyV2RuntimeActivationPolicy { xsd:boolean }?,
+         element supportedRuntime {
+           attribute sku { text },
+           attribute version { xsd:NCName }
+         }
+       }
+     | element system.codedom {
+         element compilers {
+           element compiler {
+             attribute compilerOptions { text }?,
+             attribute extension { xsd:NMTOKEN },
+             attribute language { text },
+             attribute type { text },
+             attribute warningLevel { xsd:integer },
+             element providerOption {
+               attribute name { xsd:NCName },
+               attribute value { xsd:NCName }
+             }*
+           }+
+         }
+       }
+     | element system.diagnostics {
+         element sources {
+           element source {
+             attribute name { xsd:NCName },
+             element listeners { add }?
+           }+
+         }?,
+         (element switches { empty },
+          element sharedListeners { empty },
+          element trace {
+            attribute autoflush { xsd:boolean }
+          })?
+       }
+     | element system.serviceModel {
+         element diagnostics {
+           element messageLogging {
+             attribute logEntireMessage { xsd:boolean },
+             attribute logMalformedMessages { xsd:boolean },
+             attribute logMessagesAtServiceLevel { xsd:boolean },
+             attribute logMessagesAtTransportLevel { xsd:boolean },
+             attribute maxMessagesToLog { xsd:integer },
+             attribute maxSizeOfMessageToLog { xsd:integer }
+           }
+         }?,
+         (element behaviors {
+            element serviceBehaviors {
+              element behavior {
+                attribute name { text }?,
+                element serviceMetadata {
+                  attribute httpGetEnabled { xsd:boolean },
+                  attribute httpsGetEnabled { xsd:boolean }?
+                },
+                element serviceDebug {
+                  attribute httpHelpPageEnabled { xsd:boolean }?,
+                  attribute includeExceptionDetailInFaults {
+                    xsd:boolean
+                  }
+                },
+                element dataContractSerializer {
+                  attribute maxItemsInObjectGraph { xsd:integer }
+                }?,
+                (element serviceTelemetry { empty }
+                 | element serviceThrottling {
+                     attribute maxConcurrentCalls { xsd:integer },
+                     attribute maxConcurrentInstances { xsd:integer },
+                     attribute maxConcurrentSessions { xsd:integer }
+                   })?
+              }
+            }
+          }
+          | element bindings {
+              element basicHttpBinding {
+                element binding {
+                  attribute closeTimeout { xsd:time }?,
+                  attribute maxBufferSize { xsd:integer }?,
+                  attribute maxReceivedMessageSize { xsd:integer }?,
+                  attribute name { xsd:NCName }?,
+                  attribute openTimeout { xsd:time }?,
+                  attribute receiveTimeout { xsd:time }?,
+                  attribute sendTimeout { xsd:time }?,
+                  element readerQuotas {
+                    attribute maxArrayLength { xsd:integer },
+                    attribute maxBytesPerRead { xsd:integer }?,
+                    attribute maxDepth { xsd:integer }?,
+                    attribute maxNameTableCharCount { xsd:integer }?,
+                    attribute maxStringContentLength { xsd:integer }
+                  }?,
+                  security?
+                }+
+              }?
+            }
+          | element client { empty }
+          | element extensions {
+              element behaviorExtensions { add+ },
+              (element bindingElementExtensions { add+ },
+               element bindingExtensions { add+ })?
+            }
+          | element protocolMapping { add+ }
+          | element serviceHostingEnvironment {
+              attribute aspNetCompatibilityEnabled { xsd:boolean }?,
+              attribute multipleSiteBindingsEnabled { xsd:boolean }?
+            })*,
+         element services {
+           element service {
+             attribute behaviorConfiguration { xsd:NCName }?,
+             attribute name { text },
+             element endpoint {
+               attribute address { xsd:NCName }?,
+               attribute binding { xsd:NCName },
+               attribute bindingConfiguration { xsd:NCName }?,
+               attribute contract { xsd:NCName }
+             }+
+           }+
+         }?
+       })*
+  }
+  | element ns1:configuration {
+      element ns1:configSections {
+        element ns1:section {
+          attribute name { xsd:NCName },
+          attribute requirePermission { xsd:boolean },
+          attribute type { text }
+        }
+      },
+      element ns1:appSettings { empty },
+      element ns1:connectionStrings { empty },
+      element ns1:system.web {
+        element ns1:compilation {
+          attribute debug { xsd:boolean },
+          attribute defaultLanguage { text },
+          attribute targetFramework { xsd:decimal }
+        },
+        element ns1:authentication {
+          attribute mode { xsd:NCName }
+        },
+        element ns1:httpModules { ns1.add },
+        element ns1:pages {
+          attribute clientIDMode { xsd:NCName },
+          attribute controlRenderingCompatibilityVersion { xsd:decimal }
+        }
+      },
+      element ns1:system.webServer {
+        element ns1:modules {
+          attribute runAllManagedModulesForAllRequests { xsd:boolean },
+          ns1.add
+        }
+      },
+      element ns1:rewriter {
+        element ns1:rewrite {
+          attribute to { text },
+          attribute url { text }
+        }+
+      }
+    }
+section =
+  element section {
+    attribute allowExeDefinition { xsd:NCName }?,
+    attribute name { xsd:NCName },
+    attribute requirePermission { xsd:boolean }?,
+    attribute restartOnExternalChanges { xsd:boolean }?,
+    attribute type { text }
+  }
+sectionGroup =
+  element sectionGroup {
+    attribute name { xsd:NCName },
+    attribute type { text }?,
+    (section | sectionGroup)+
+  }
+pages =
+  element pages {
+    attribute clientIDMode { xsd:NCName }?,
+    attribute controlRenderingCompatibilityVersion { xsd:decimal }?,
+    attribute enableEventValidation { xsd:boolean }?,
+    attribute pageBaseType { xsd:NCName }?,
+    attribute theme { text }?,
+    attribute validateRequest { xsd:boolean }?,
+    attribute viewStateEncryptionMode { xsd:NCName }?,
+    element namespaces { add+ }?
+  }
+add =
+  element add {
+    attribute assembly { text }?,
+    attribute binding { xsd:NCName }?,
+    attribute bindingConfiguration { text }?,
+    attribute connectionString { xsd:anyURI }?,
+    attribute initializationPage { text }?,
+    attribute initializeData { text }?,
+    attribute input { text }?,
+    attribute key { xsd:anyURI }?,
+    attribute matchType { xsd:NCName }?,
+    attribute modules { xsd:NCName }?,
+    attribute name { xsd:NCName }?,
+    attribute namespace { xsd:NCName }?,
+    attribute negate { xsd:boolean }?,
+    attribute path { text }?,
+    attribute preCondition { text }?,
+    attribute providerName { xsd:NCName }?,
+    attribute resourceType { xsd:NCName }?,
+    attribute responseBufferLimit { xsd:integer }?,
+    attribute scheme { xsd:NCName }?,
+    attribute scriptProcessor { text }?,
+    attribute type { text }?,
+    attribute validate { xsd:boolean }?,
+    attribute value { text }?,
+    attribute verb { text }?,
+    attribute xdt:Locator { text }?,
+    attribute xdt:Transform { xsd:NCName }?
+  }
+security =
+  element security {
+    attribute mode { xsd:NCName }?,
+    attribute xdt:Transform { xsd:NCName }?,
+    (element requestFiltering {
+       attribute removeServerHeader { xsd:boolean },
+       element requestLimits {
+         attribute maxAllowedContentLength { xsd:integer }
+       }?
+     }
+     | element transport {
+         attribute clientCredentialType { xsd:NCName }
+       })?
+  }
+system.webServer =
+  element system.webServer {
+    (element httpErrors {
+       attribute errorMode { xsd:NCName }?,
+       attribute existingResponse { xsd:NCName },
+       (remove+,
+        element error {
+          attribute path { text },
+          attribute prefixLanguageFilePath { text },
+          attribute responseMode { xsd:NCName },
+          attribute statusCode { xsd:integer }
+        }+)?
+     }
+     | element staticContent {
+         element mimeMap {
+           attribute fileExtension { xsd:NMTOKEN },
+           attribute mimeType { text }
+         }+
+       })?,
+    (element applicationInitialization {
+       attribute xdt:Transform { xsd:NCName },
+       add
+     }
+     | element rewrite {
+         element rules {
+           clear
+           | element rule {
+               attribute name { text },
+               attribute stopProcessing { xsd:boolean },
+               element match {
+                 attribute url { text }
+               },
+               element conditions {
+                 attribute logicalGrouping { xsd:NCName },
+                 add+
+               }?,
+               element action {
+                 attribute redirectType { xsd:NCName }?,
+                 attribute type { xsd:NCName },
+                 attribute url { text }
+               }
+             }
+         }
+       })?,
+    (security
+     | element aspNetCore {
+         attribute arguments { text }?,
+         attribute hostingModel { xsd:NCName }?,
+         attribute processPath { text }?,
+         attribute requestTimeout { xsd:time }?,
+         attribute stdoutLogEnabled { xsd:boolean }?,
+         attribute stdoutLogFile { text }?,
+         attribute xdt:Transform { text }?
+       }
+     | element handlers { (add | remove)+ }
+     | element httpProtocol {
+         attribute xdt:Transform { xsd:NCName }?,
+         element customHeaders { clear?, remove+ }
+       }
+     | element modules {
+         attribute runAllManagedModulesForAllRequests { xsd:boolean }?,
+         (add | remove)*
+       }
+     | element validation {
+         attribute validateIntegratedModeConfiguration { xsd:boolean }
+       })*,
+    element directoryBrowse {
+      attribute enabled { xsd:boolean }
+    }?
+  }
+system.web =
+  element system.web {
+    element authorization {
+      element allow {
+        attribute users { text }
+      }
+    }
+    | (pages
+       | element authentication {
+           attribute mode { xsd:NCName }
+         }
+       | element compilation {
+           attribute debug { xsd:boolean }?,
+           attribute targetFramework { xsd:NMTOKEN }?,
+           attribute tempDirectory { text }?,
+           attribute xdt:Transform { text }?,
+           element assemblies { add+ }?
+         }
+       | element customErrors {
+           attribute defaultRedirect { text }?,
+           attribute mode { xsd:NCName },
+           attribute redirectMode { xsd:NCName }?
+         }
+       | element globalization {
+           attribute requestEncoding { xsd:NCName },
+           attribute responseEncoding { xsd:NCName }
+         }
+       | element httpHandlers { add+ }
+       | element httpModules { add* }
+       | element httpRuntime {
+           attribute appRequestQueueLimit { xsd:integer }?,
+           attribute enableVersionHeader { xsd:boolean }?,
+           attribute executionTimeout { xsd:integer }?,
+           attribute maxRequestLength { xsd:integer }?,
+           attribute minFreeThreads { xsd:integer }?,
+           attribute minLocalRequestFreeThreads { xsd:integer }?,
+           attribute requestPathInvalidCharacters { text }?,
+           attribute requestValidationMode { xsd:decimal }?,
+           attribute targetFramework { xsd:NMTOKEN }?,
+           attribute useFullyQualifiedRedirectUrl { xsd:boolean }?
+         }
+       | element identity {
+           attribute impersonate { xsd:boolean }
+         }
+       | element machineKey {
+           attribute validation { xsd:NCName }
+         }
+       | element sessionState {
+           attribute cookieSameSite { xsd:NCName }?,
+           attribute cookieless { xsd:boolean },
+           attribute mode { xsd:NCName },
+           attribute stateConnectionString { text }?,
+           attribute timeout { xsd:integer }
+         }
+       | element xhtmlConformance {
+           attribute mode { xsd:NCName }
+         })*
+  }
+Globalization =
+  element Globalization {
+    element ResourceProviders { empty }
+    | add+
+  }
+ns1.add =
+  element ns1:add {
+    attribute name { xsd:NCName },
+    attribute type { text }
+  }
+remove =
+  element remove {
+    attribute name { xsd:NCName }?,
+    attribute statusCode { xsd:integer }?,
+    attribute subStatusCode { xsd:integer }?
+  }
+clear = element clear { empty }
diff --git a/etc/schema/dotnet-packages-config.rnc b/etc/schema/dotnet-packages-config.rnc
new file mode 100644
index 00000000000..702f11aca31
--- /dev/null
+++ b/etc/schema/dotnet-packages-config.rnc
@@ -0,0 +1,11 @@
+default namespace = ""
+
+start =
+  element packages {
+    element package {
+      attribute id { xsd:NCName },
+      attribute targetFramework { xsd:NCName }?,
+      attribute allowedVersions { xsd:NCName }?,
+      attribute version { xsd:NMTOKEN }
+    }+
+  }
diff --git a/etc/schema/dotnet-packages-props.rnc b/etc/schema/dotnet-packages-props.rnc
new file mode 100644
index 00000000000..18c689eb2dd
--- /dev/null
+++ b/etc/schema/dotnet-packages-props.rnc
@@ -0,0 +1,22 @@
+default namespace = ""
+
+start =
+  element Project {
+    element PropertyGroup {
+      element ManagePackageVersionsCentrally { xsd:boolean },
+      element CentralPackageTransitivePinningEnabled { xsd:boolean },
+      element CentralPackageVersionOverrideEnabled { xsd:boolean }
+    }?,
+    element ItemGroup {
+      attribute Condition { text }?,
+      (element GlobalPackageReference {
+         attribute Condition { text }?,
+         attribute Include { xsd:NCName },
+         attribute Version { xsd:NMTOKEN }
+       }+
+       | element PackageVersion {
+           attribute Include { xsd:NCName },
+           attribute Version { text }
+         }+)
+    }+
+  }
diff --git a/etc/schema/dotnet-resx.rnc b/etc/schema/dotnet-resx.rnc
new file mode 100644
index 00000000000..26b77e47527
--- /dev/null
+++ b/etc/schema/dotnet-resx.rnc
@@ -0,0 +1,57 @@
+default namespace = ""
+namespace msdata = "urn:schemas-microsoft-com:xml-msdata"
+namespace xsd = "http://www.w3.org/2001/XMLSchema"
+
+start =
+  element root {
+    element xsd:schema {
+      attribute id { xsd:NCName },
+      element xsd:import {
+        attribute namespace { xsd:anyURI }
+      }?,
+      xsd.element
+    },
+    element resheader {
+      attribute name { xsd:NCName },
+      value
+    }+,
+    (element assembly {
+       attribute alias { xsd:NCName },
+       attribute name { text }
+     }
+     | element data {
+         attribute mimetype { text }?,
+         attribute name { text },
+         attribute type { text }?,
+         attribute xml:space { xsd:NCName }?,
+         value
+       }
+     | element metadata {
+         attribute name { xsd:NCName },
+         attribute type { text },
+         value
+       })*
+  }
+xsd.element =
+  element xsd:element {
+    attribute minOccurs { xsd:integer }?,
+    attribute name { xsd:NCName },
+    attribute type { xsd:NMTOKEN }?,
+    attribute msdata:IsDataSet { xsd:boolean }?,
+    attribute msdata:Ordinal { xsd:integer }?,
+    element xsd:complexType {
+      element xsd:choice {
+        attribute maxOccurs { xsd:NCName },
+        xsd.element+
+      }?,
+      element xsd:sequence { xsd.element+ }?,
+      element xsd:attribute {
+        attribute name { xsd:NCName }?,
+        attribute ref { xsd:NMTOKEN }?,
+        attribute type { xsd:NMTOKEN }?,
+        attribute use { xsd:NCName }?,
+        attribute msdata:Ordinal { xsd:integer }?
+      }*
+    }*
+  }
+value = element value { text }
diff --git a/etc/schema/msbuild.rnc b/etc/schema/msbuild.rnc
new file mode 100644
index 00000000000..9425bbdf0b9
--- /dev/null
+++ b/etc/schema/msbuild.rnc
@@ -0,0 +1,1041 @@
+default namespace = ""
+namespace ns1 = "http://schemas.microsoft.com/developer/msbuild/2003"
+
+start = Project | ns1.Project
+Project =
+  element Project {
+    attribute Sdk { text }?,
+    (text
+     | ItemGroup
+     | PropertyGroup
+     | element Import {
+         attribute Project { text }
+       }
+     | element ProjectExtensions {
+         element VisualStudio {
+           element FlavorProperties {
+             attribute GUID { text },
+             element WebProjectProperties {
+               element UseIIS { xsd:NCName },
+               element AutoAssignPort { xsd:NCName },
+               element DevelopmentServerPort { xsd:integer },
+               element DevelopmentServerVPath { text },
+               element IISUrl { xsd:anyURI },
+               element NTLMAuthentication { xsd:NCName },
+               element UseCustomServer { xsd:NCName },
+               element CustomServerUrl { empty },
+               element SaveServerSettingsInUserFile { xsd:NCName }
+             }
+           }
+           | element UserProperties {
+               attribute configuration_4bicepconfig_1json__JsonSchema {
+                 xsd:anyURI
+               }
+             }
+         }
+       }
+     | element Target {
+         attribute AfterTargets { xsd:NCName }?,
+         attribute BeforeTargets { xsd:NCName }?,
+         attribute Condition { text }?,
+         attribute DependsOnTargets { text }?,
+         attribute Inputs { text }?,
+         attribute Name { xsd:NCName },
+         attribute Outputs { text }?,
+         (PropertyGroup
+          | (element RemoveDir {
+               attribute Condition { text },
+               attribute Directories { text }
+             },
+             element Delete {
+               attribute Condition { text },
+               attribute Files { text }
+             }))?,
+         (ItemGroup
+          | element Error {
+              attribute Condition { text },
+              attribute Text { text }
+            }
+          | element Exec {
+              attribute Command { text },
+              attribute Condition { text }?,
+              attribute ContinueOnError { xsd:boolean }?,
+              attribute EnvironmentVariables { text }?,
+              attribute WorkingDirectory { text }?,
+              element Output {
+                attribute PropertyName { xsd:NCName },
+                attribute TaskParameter { xsd:NCName }
+              }?
+            }
+          | element MakeDir {
+              attribute Directories { text }
+            }
+          | element Message {
+              attribute Condition { text }?,
+              attribute Importance { xsd:NCName },
+              attribute Text { text }
+            })*,
+         (element Copy {
+            attribute DestinationFolder { text },
+            attribute SourceFiles { text }
+          }
+          | element MSBuild {
+              attribute BuildInParallel { xsd:boolean },
+              attribute Projects { text },
+              attribute Properties { text },
+              attribute Targets { xsd:NCName }
+            })?
+       })+
+  }
+ns1.Project =
+  element ns1:Project {
+    attribute DefaultTargets { xsd:NCName }?,
+    attribute ToolsVersion { xsd:decimal }?,
+    (text
+     | ns1.ItemGroup
+     | ns1.PropertyGroup
+     | element ns1:Choose {
+         element ns1:When {
+           attribute Condition { text },
+           (ns1.PropertyGroup | ns1.ItemGroup+)
+         }+,
+         element ns1:Otherwise { ns1.ItemGroup }?
+       }
+     | element ns1:Import {
+         attribute Condition { text }?,
+         attribute Label { xsd:NCName }?,
+         attribute Project { text }
+       }
+     | element ns1:ProjectExtensions {
+         element ns1:VisualStudio {
+           element ns1:FlavorProperties {
+             attribute GUID { text },
+             (element ns1:WebProjectProperties {
+                (element ns1:UseIIS { xsd:NCName },
+                 element ns1:AutoAssignPort { xsd:NCName },
+                 element ns1:DevelopmentServerPort { xsd:integer },
+                 element ns1:DevelopmentServerVPath { text },
+                 element ns1:IISUrl { xsd:anyURI },
+                 element ns1:NTLMAuthentication { xsd:NCName },
+                 element ns1:UseCustomServer { xsd:NCName },
+                 element ns1:CustomServerUrl { empty })?,
+                element ns1:SaveServerSettingsInUserFile { xsd:NCName }
+              }
+              | (element ns1:ProjectProperties {
+                   attribute AddItemTemplatesGuid { text },
+                   attribute ApplicationType { xsd:NCName },
+                   attribute DebugInfoExeName { text },
+                   attribute HostName { xsd:NCName },
+                   attribute HostPackage { text },
+                   attribute Language { xsd:NCName },
+                   attribute OfficeVersion { xsd:decimal },
+                   attribute TemplatesPath { xsd:NCName },
+                   attribute VstxVersion { xsd:decimal }
+                 },
+                 element ns1:Host {
+                   attribute GeneratedCodeNamespace { xsd:NCName },
+                   attribute IconIndex { xsd:integer },
+                   attribute Name { xsd:NCName },
+                   attribute PublishedHash { text },
+                   element ns1:HostItem {
+                     attribute Blueprint { xsd:NCName },
+                     attribute CanActivate { xsd:boolean },
+                     attribute CanonicalName { xsd:NCName },
+                     attribute Code { xsd:NCName },
+                     attribute GeneratedCode { xsd:NCName },
+                     attribute IconIndex { xsd:integer },
+                     attribute Name { xsd:NCName },
+                     attribute PublishedHash { text }
+                   }
+                 }))
+           }
+           | element ns1:UserProperties {
+               attribute Name { xsd:NCName }
+             }
+         }
+       }
+     | element ns1:Target {
+         attribute AfterTargets { xsd:NCName }?,
+         attribute BeforeTargets { xsd:NCName }?,
+         attribute Condition { text }?,
+         attribute Name { xsd:NCName },
+         attribute Outputs { text }?,
+         (ns1.PropertyGroup
+          | element ns1:Error {
+              attribute Condition { text },
+              attribute HelpKeyword { xsd:NCName },
+              attribute Text { text }
+            }*
+          | (ns1.ItemGroup
+             | element ns1:MakeDir {
+                 attribute Directories { text }
+               }
+             | element ns1:WriteCodeFragment {
+                 attribute AssemblyAttributes { text },
+                 attribute Language { text },
+                 attribute OutputFile { text }
+               })*),
+         (element ns1:Copy {
+            attribute ContinueOnError { xsd:boolean }?,
+            attribute DestinationFolder { text },
+            attribute OverwriteReadOnlyFiles { xsd:NCName },
+            attribute SourceFiles { text }
+          }
+          | element ns1:CreateItem {
+              attribute Exclude { text }?,
+              attribute Include { text },
+              ns1.Output
+            }
+          | element ns1:Delete {
+              attribute Files { text },
+              attribute TreatErrorsAsWarnings { xsd:NCName }
+            }
+          | element ns1:Exec {
+              attribute Command { text },
+              attribute WorkingDirectory { text }?
+            }
+          | element ns1:GetVersionParts {
+              attribute AssemblyPath { text },
+              ns1.Output+
+            }
+          | element ns1:Message {
+              attribute Importance { xsd:NCName }?,
+              attribute Text { text }
+            }
+          | element ns1:TokenReplace {
+              attribute Condition { text }?,
+              attribute Destination { text },
+              attribute Path { text },
+              attribute Replacement { text },
+              attribute Token { text }
+            })*,
+         element ns1:CallTarget {
+           attribute Condition { text }?,
+           attribute Targets { xsd:NCName }
+         }?
+       }
+     | element ns1:UsingTask {
+         attribute AssemblyFile { text },
+         attribute TaskFactory { xsd:NCName },
+         attribute TaskName { xsd:NCName },
+         element ns1:ParameterGroup {
+           (element ns1:Path {
+              attribute ParameterType { xsd:NCName },
+              attribute Required { xsd:boolean }
+            },
+            element ns1:Destination {
+              attribute ParameterType { xsd:NCName },
+              attribute Required { xsd:boolean }
+            },
+            element ns1:Token {
+              attribute ParameterType { xsd:NCName },
+              attribute Required { xsd:boolean }
+            },
+            element ns1:Replacement {
+              attribute ParameterType { xsd:NCName },
+              attribute Required { xsd:boolean }
+            })
+           | (element ns1:AssemblyPath {
+                attribute ParameterType { xsd:NCName },
+                attribute Required { xsd:boolean }
+              },
+              element ns1:MajorVersion {
+                attribute Output { xsd:boolean },
+                attribute ParameterType { xsd:NCName }
+              },
+              element ns1:MinorVersion {
+                attribute Output { xsd:boolean },
+                attribute ParameterType { xsd:NCName }
+              },
+              element ns1:BuildVersion {
+                attribute Output { xsd:boolean },
+                attribute ParameterType { xsd:NCName }
+              },
+              element ns1:RevisionVersion {
+                attribute Output { xsd:boolean },
+                attribute ParameterType { xsd:NCName }
+              })
+         },
+         element ns1:Task {
+           element ns1:Using {
+             attribute Namespace { xsd:NCName }
+           }?,
+           element ns1:Code {
+             attribute Language { xsd:NCName },
+             attribute Type { xsd:NCName },
+             text
+           }
+         }
+       })+
+  }
+PropertyGroup =
+  element PropertyGroup {
+    attribute Condition { text }?,
+    attribute Label { xsd:NCName }?,
+    element TargetFrameworks { text }?,
+    (element DotnetMonoRepoVersion { xsd:NMTOKEN }
+     | (element CFBundleName { text },
+        element CFBundleDisplayName { text },
+        element CFBundleIdentifier { xsd:NCName },
+        element CFBundleVersion { xsd:NMTOKEN },
+        element CFBundleShortVersionString { xsd:NMTOKEN },
+        element CFBundlePackageType { xsd:NCName },
+        element CFBundleExecutable { xsd:NCName },
+        element CFBundleIconFile { xsd:NCName },
+        element NSPrincipalClass { xsd:NCName },
+        element NSHighResolutionCapable { xsd:boolean }))?,
+    (element SoAssemblyFileVersion {
+       attribute Condition { text },
+       xsd:NMTOKEN
+     },
+     element SoReleaseVersion {
+       attribute Condition { text },
+       text
+     })?,
+    (element AccelerateBuildsInVisualStudio { xsd:boolean }
+     | element AddLicenseAsEmbeddedResource { xsd:boolean }
+     | element AddNoticeAsEmbeddedResource { xsd:boolean }
+     | element AnalysisMode { xsd:NCName }
+     | element ApiName {
+         attribute Condition { text },
+         xsd:NCName
+       }
+     | element AppConfig { xsd:NCName }
+     | element AppendTargetFrameworkToOutputPath { xsd:boolean }
+     | element ApplicationIcon { text }
+     | element ApplicationManifest { xsd:NCName }
+     | element AspNetCoreHostingModel { xsd:NCName }
+     | element AssemblyName { text }
+     | element AssemblyOriginatorKeyFile { text }
+     | element AssemblyTitle { text }
+     | element AssemblyVersion { xsd:NMTOKEN }
+     | element Authors { text }
+     | element AutoGenerateBindingRedirects {
+         attribute Condition { text }?,
+         xsd:boolean
+       }
+     | element AzureFunctionsVersion { xsd:NCName }
+     | element BicepCompileAfterTargets { xsd:NCName }
+     | element BicepCompileBeforeTargets { xsd:NCName }
+     | element BootstrapperEnabled { xsd:boolean }
+     | element BuildOutputTargetFolder { xsd:NCName }
+     | element BuildServerSideRenderer { xsd:boolean }
+     | element BuiltInComInteropSupport { xsd:boolean }
+     | element CentralPackageTransitivePinningEnabled { xsd:boolean }
+     | element CodeAnalysisTreatWarningsAsErrors { xsd:boolean }
+     | element Company { text }
+     | element CopyLocalLockFileAssemblies { xsd:boolean }
+     | element Copyright { text }
+     | element DebugType {
+         attribute Condition { text }?,
+         xsd:NCName
+       }
+     | element DefaultItemExcludes { text }
+     | element DefineConstants { text }
+     | element DelaySign { xsd:boolean }
+     | element Description { text }
+     | element Deterministic { xsd:boolean }
+     | element DisableImplicitNuGetFallbackFolder { xsd:boolean }
+     | element DisableTransitiveProjectReferences { xsd:boolean }
+     | element DockerDefaultTargetOS { xsd:NCName }
+     | element DockerfileContext { text }
+     | element EmbedUntrackedSources { xsd:boolean }
+     | element EnableCompressionInSingleFile { xsd:boolean }
+     | element EnableDefaultCompileItems { xsd:boolean }
+     | element EnableDefaultEmbeddedResourceItems { xsd:boolean }
+     | element EnableMSTestRunner { xsd:boolean }
+     | element EnableNETAnalyzers { xsd:boolean }
+     | element EnableNuget { xsd:boolean }
+     | element EnableTrimAnalyzer { xsd:boolean }
+     | element EnforceCodeStyleInBuild { xsd:boolean }
+     | element ErrorReport { xsd:NCName }
+     | element FileVersion { xsd:NMTOKEN }
+     | element FindInvalidProjectReferences { xsd:boolean }
+     | element GenerateAssemblyInfo { xsd:boolean }
+     | element GenerateBindingRedirectsOutputType { xsd:boolean }
+     | element GenerateDocumentationFile { xsd:NCName }
+     | element GeneratePackageOnBuild { xsd:NCName }
+     | element GenerateResourceUsePreserializedResources { xsd:boolean }
+     | element ImplicitUsings { xsd:NCName }
+     | element IncludeNativeLibrariesForSelfExtract { xsd:boolean }
+     | element IncludeSymbols { xsd:boolean }
+     | element IsPackable { xsd:boolean }
+     | element LangVersion { xsd:NMTOKEN }
+     | element ManagePackageVersionsCentrally { xsd:boolean }
+     | element MapFileExtensions { xsd:boolean }
+     | element NoPackageAnalysis { xsd:boolean }
+     | element NoWarn { text }
+     | element Nullable { xsd:NCName }
+     | element Optimize { xsd:boolean }
+     | element OutputPath { text }
+     | element OutputType { xsd:NCName }
+     | element PackAsTool { xsd:boolean }
+     | element PackageIcon { text }
+     | element PackageIconUrl { empty }
+     | element PackageId { text }
+     | element PackageLicenseFile { xsd:NCName }
+     | element PackageProjectUrl { xsd:anyURI }
+     | element PackageReleaseNotes { text }
+     | element PackageTags { text }
+     | element PlatformTarget { xsd:NCName }
+     | element Platforms { text }
+     | element Prefer32Bit { xsd:boolean }
+     | element ProduceReferenceAssembly { xsd:NCName }
+     | element Product { text }
+     | element ProjectGuid { text }
+     | element PublishRepositoryUrl { xsd:boolean }
+     | element PublishSingleFile { xsd:boolean }
+     | element RepositoryType { empty }
+     | element RepositoryUrl { empty }
+     | element RestoreLockedMode {
+         attribute Condition { text },
+         xsd:boolean
+       }
+     | element RestorePackagesWithLockFile { xsd:boolean }
+     | element RestoreProjectStyle { xsd:NCName }
+     | element RootNamespace { text }
+     | element RunPostBuildEvent { xsd:NCName }
+     | element RunSettingsFilePath { text }
+     | element RuntimeIdentifier { xsd:NCName }
+     | element RuntimeIdentifiers {
+         attribute Condition { text }?,
+         text
+       }
+     | element SatelliteResourceLanguages { xsd:NCName }
+     | element SelfContained { xsd:boolean }
+     | element SignAssembly { xsd:NCName }
+     | element SoVersionOptions { xsd:NCName }
+     | element SpaRoot { text }
+     | element StartupObject { xsd:NCName }
+     | element Summary { text }
+     | element SupportedOSPlatformVersion { xsd:decimal }
+     | element SuppressTrimAnalysisWarnings { xsd:boolean }
+     | element SymbolPackageFormat { xsd:NCName }
+     | element TargetFramework { text }
+     | element Title { text }
+     | element ToolCommandName { xsd:NCName }
+     | element TreatWarningsAsErrors { xsd:boolean }
+     | element TrimMode { xsd:NCName }
+     | element TypeScriptCompileBlocked {
+         attribute Condition { text }?,
+         xsd:boolean
+       }
+     | element TypeScriptToolsVersion { xsd:NCName }
+     | element UseAppHost { xsd:boolean }
+     | element UseApplicationTrust { xsd:boolean }
+     | element UseWPF { xsd:boolean }
+     | element UseWindowsForms { xsd:boolean }
+     | element UserSecretsId { text }
+     | element Version {
+         attribute Condition { text }?,
+         text
+       }
+     | element WarningsAsErrors { text }
+     | element WarningsNotAsErrors { text }
+     | element WasmMainJSPath { text })*,
+    (element PackageRequireLicenseAcceptance { xsd:boolean }
+     | element _FunctionsSkipCleanOutput { xsd:boolean }
+     | (element OutDir { text },
+        element ExcludeXmlAssemblyFiles { xsd:boolean }))?,
+    element EnableUnsafeBinaryFormatterSerialization { xsd:boolean }?,
+    (element AssemblySearchPaths { text }
+     | element AvaloniaUseCompiledBindingsByDefault { xsd:boolean }
+     | element BaseOutputPath { text }
+     | element BicepOutputStyle { xsd:NCName }
+     | element ContinuousIntegrationBuild { xsd:boolean }
+     | element DebugSymbols { xsd:boolean }
+     | element DefaultDocumentationIncludeUndocumentedItems {
+         xsd:boolean
+       }
+     | element DscZipFile { text }
+     | element EnableNoticeInPublishOutput { xsd:boolean }
+     | element GenerateDocumentation { xsd:boolean }
+     | element IncludeAllContentForSelfExtract { xsd:boolean }
+     | element IsTestProject { xsd:boolean }
+     | element NetSdk { xsd:NCName }
+     | element ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch {
+         xsd:NCName
+       }
+     | element ShouldIncludeNativeSkiaSharp { xsd:NCName }
+     | element TargetsForTfmSpecificBuildOutput { text }
+     | (element SccProjectName { xsd:NCName },
+        element SccProvider { xsd:NCName },
+        element SccAuxPath { xsd:NCName },
+        element SccLocalPath { xsd:NCName })
+     | (element GenerateNoticePackageVersion { xsd:NMTOKEN },
+        element GenerateNoticeRetryCount { xsd:integer },
+        element GenerateNoticeBatchSize { xsd:integer },
+        element GenerateNoticeUseLocalFile {
+          attribute Condition { text },
+          xsd:boolean
+        },
+        element GenerateNoticeUpdateLocalFile {
+          attribute Condition { text },
+          xsd:boolean
+        })
+     | (element RunNswag { xsd:boolean },
+        element RunNodeBuild { xsd:boolean })
+     | (element PublishTrimmed { xsd:boolean },
+        element JsonSerializerIsReflectionEnabledByDefault {
+          xsd:boolean
+        })
+     | (element ApplicationId { xsd:NCName },
+        element ApplicationVersion { xsd:integer },
+        element ApplicationDisplayVersion { xsd:decimal },
+        element AndroidPackageFormat { xsd:NCName },
+        element AndroidEnableProfiledAot { xsd:NCName })
+     | (element DefaultDocumentationFolder { text },
+        element DefaultDocumentationLinksBaseUrl { text },
+        element DefaultDocumentationLinksOutputFile { text },
+        element DefaultDocumentationExternLinksFiles { text },
+        element DefaultDocumentationConfigurationFile { text }))?,
+    element ServiceName { xsd:NCName }?,
+    (element RazorLangVersion { xsd:decimal }
+     | (element WebRoot { text },
+        element WebProjectFile { text },
+        element WebOutputPath { text }))?,
+    element ClientName { text }?,
+    element DisableDataAnnotationsParam { text }?,
+    (element AvaloniaVersion { xsd:NMTOKEN }
+     | element ContinuePackingAfterGeneratingNuspec { xsd:boolean }
+     | ((element NSwagGenerateExceptionClasses { xsd:boolean }
+         | element WrapResponseMethods { text })+,
+        element NSwagOptions { text })
+     | (element DeployDefaultTargetFrameworkVersion { xsd:decimal },
+        element VisualStudioVersion {
+          attribute Condition { text },
+          xsd:decimal
+        }))?
+  }
+ItemGroup =
+  element ItemGroup {
+    attribute Condition { text }?,
+    (element ApiClientGen {
+       attribute Include { xsd:NCName }
+     }
+     | element AvaloniaXaml {
+         attribute Remove { text }
+       }
+     | element BuildOutputInPackage {
+         attribute Include { text },
+         attribute TargetPath { text }
+       }
+     | element InternalsVisibleTo {
+         attribute Condition { text },
+         attribute Include { text }
+       }
+     | element ProjectsToPublish {
+         attribute Include { text }
+       }
+     | element Service {
+         attribute Include { text }
+       }
+     | element _ReferenceCopyLocalPaths {
+         attribute Include { text }
+       }
+     | element ClaimsRequirement {
+         attribute Include { xsd:NCName }
+       }*),
+    element WCFMetadata {
+      attribute Include { text }
+    }?,
+    (element AdditionalFiles {
+       attribute Remove { text }
+     }
+     | element SourceRoot {
+         attribute Include { text }
+       }
+     | element ApiClient {
+         attribute Include { xsd:NCName }
+       }*),
+    element FrameworkReference {
+      attribute Include { xsd:NCName }
+    }?,
+    (element COMReference {
+       attribute Include { xsd:NCName },
+       element Guid { text },
+       element VersionMajor { xsd:integer },
+       element VersionMinor { xsd:integer },
+       element Lcid { xsd:integer },
+       element WrapperTool { xsd:NCName },
+       element Isolated { xsd:NCName },
+       EmbedInteropTypes
+     }
+     | element TrimmerRootDescriptor {
+         attribute Include { xsd:NCName }
+       }
+     | element Watch {
+         attribute Exclude { text }?,
+         attribute Include { text }?,
+         attribute Remove { text }?
+       }*
+     | element AvaloniaResource {
+         attribute Include { text }?,
+         attribute Remove { text }?
+       }*
+     | element OpenApiReference {
+         attribute ClassName { text }?,
+         attribute Include { text },
+         attribute Namespace { text }?,
+         attribute Options { text }?,
+         element CodeGenerator { xsd:NCName }?
+       }*),
+    element Bicep {
+      attribute Exclude { text }?,
+      attribute Include { text }?,
+      attribute NoBuild { xsd:boolean }?,
+      attribute OutputFile { text }?,
+      attribute Update { text }?,
+      element OutputFile { text }?
+    }*,
+    (element Folder {
+       attribute Include { text }
+     }*
+     | element BicepParam {
+         attribute Include { text }
+       }*),
+    (element Compile {
+       attribute Include { text }?,
+       attribute Link { xsd:NCName }?,
+       attribute Remove { text }?,
+       attribute Update { text }?,
+       Link?,
+       (DependentUpon
+        | element AutoGen { xsd:NCName }
+        | element DesignTime { xsd:NCName })*,
+       (SubType
+        | element DesignTimeSharedInput { xsd:NCName })?
+     }
+     | element Content {
+         attribute CopyToOutputDirectory { xsd:NCName }?,
+         attribute CopyToPublishDirectory { xsd:NCName }?,
+         attribute Exclude { text }?,
+         attribute Include { text }?,
+         attribute Link { text }?,
+         attribute PackagePath { text }?,
+         attribute Remove { text }?,
+         attribute Update { text }?,
+         Link?,
+         (CopyToOutputDirectory
+          | CopyToPublishDirectory
+          | DependentUpon
+          | ExcludeFromSingleFile
+          | SubType)*
+       }
+     | element EmbeddedResource {
+         attribute Condition { text }?,
+         attribute Include { text }?,
+         attribute Link { text }?,
+         attribute LogicalName { text }?,
+         attribute Remove { text }?,
+         attribute Update { text }?,
+         attribute WithCulture { xsd:boolean }?,
+         CopyToOutputDirectory?,
+         element CustomToolNamespace { xsd:NCName }?,
+         element LogicalName { text }?,
+         (Generator | LastGenOutput)*,
+         SubType?,
+         Link?,
+         (DependentUpon
+          | element WithCulture { xsd:boolean })?
+       }
+     | element None {
+         attribute CopyToOutputDirectory { xsd:NCName }?,
+         attribute CopyToPublishDirectory { xsd:NCName }?,
+         attribute Exclude { text }?,
+         attribute Include { text }?,
+         attribute Link { xsd:NCName }?,
+         attribute Pack { xsd:boolean }?,
+         attribute PackagePath { text }?,
+         attribute Remove { text }?,
+         attribute Update { text }?,
+         Generator?,
+         (LastGenOutput
+          | SubType
+          | (element Pack { xsd:NCName }
+             | element PackagePath { empty })*),
+         CopyToOutputDirectory?,
+         (CopyToPublishDirectory | DependentUpon)?
+       }
+     | element Resource {
+         attribute Include { text }
+       }
+     | element WCFMetadataStorage {
+         attribute Include { text }
+       })*,
+    (element AndroidResource {
+       attribute Include { xsd:NCName },
+       Link
+     }
+     | element DesignData {
+         attribute Include { text }
+       }
+     | element WasmExtraFilesToDeploy {
+         attribute Include { text }
+       }
+     | element Using {
+         attribute Alias { xsd:NCName }?,
+         attribute Include { xsd:NCName }
+       }*
+     | element DocumentName {
+         attribute Include { xsd:NCName }
+       }*
+     | (element PackageDownload {
+          attribute Include { xsd:NCName },
+          attribute Version { text }
+        }
+        | element PackageReference {
+            attribute Condition { text }?,
+            attribute ExcludeAssets { xsd:NCName }?,
+            attribute Include { text },
+            attribute PrivateAssets { xsd:NCName }?,
+            attribute Version { text }?,
+            (element IncludeAssets { text }
+             | element PrivateAssets { xsd:NCName })*
+          }
+        | element ProjectReference {
+            attribute Include { text }?,
+            attribute PrivateAssets { xsd:NCName }?,
+            attribute Remove { xsd:NCName }?,
+            (element Properties { text }
+             | (Project,
+                element Name { xsd:NCName }))?
+          }
+        | element Reference {
+            attribute Include { text },
+            (EmbedInteropTypes
+             | element HintPath {
+                 attribute Condition { text }?,
+                 text
+               }
+             | element Private { xsd:NCName }
+             | element SpecificVersion { xsd:NCName })*
+          })*
+     | (element DistFiles {
+          attribute Condition { text }?,
+          attribute Include { text }
+        }+,
+        element ResolvedFileToPublish {
+          attribute Exclude { text },
+          attribute Include { text },
+          element RelativePath { text },
+          CopyToPublishDirectory,
+          ExcludeFromSingleFile?
+        })
+     | element TypeScriptCompile {
+         attribute Include { text }?,
+         attribute Remove { text }?,
+         DependentUpon?
+       }*
+     | element Page {
+         attribute Generator { xsd:NMTOKEN }?,
+         attribute Include { text }?,
+         attribute Remove { text }?,
+         attribute SubType { xsd:NCName }?
+       }*)
+  }
+ns1.PropertyGroup =
+  element ns1:PropertyGroup {
+    attribute Condition { text }?,
+    (element ns1:NugetFolder { text },
+     element ns1:BuildFolder { text })?,
+    element ns1:SoReleaseVersion { text }?,
+    (element ns1:ApplicationManifest { xsd:NCName }
+     | element ns1:ErrorText { text }
+     | element ns1:__paket__NETStandard_Library_targets { text })?,
+    element ns1:PreBuildEvent {
+      attribute Condition { text }?,
+      text
+    }?,
+    element ns1:__paket__MSTest_TestFramework_targets { text }?,
+    element ns1:SoLegacyVersion { xsd:NCName }?,
+    element ns1:SoBetaTag { empty }?,
+    element ns1:ComputerName { text }?,
+    element ns1:__paket__MSTest_TestAdapter_props { text }?,
+    element ns1:__paket__MSTest_TestAdapter_targets { text }?,
+    element ns1:MinimumVisualStudioVersion { xsd:decimal }?,
+    (element ns1:AppDesignerFolder { xsd:NCName }
+     | element ns1:ApplicationRevision { xsd:integer }
+     | element ns1:ApplicationVersion { text }
+     | element ns1:AssemblyName { xsd:NCName }
+     | element ns1:AssemblyOriginatorKeyFile { text }
+     | element ns1:AutoGenerateBindingRedirects { xsd:boolean }
+     | element ns1:AutoIncrementApplicationRevision { xsd:boolean }
+     | element ns1:BootstrapperEnabled { xsd:boolean }
+     | element ns1:CodeAnalysisRuleSet { text }
+     | element ns1:Configuration {
+         attribute Condition { text },
+         xsd:NCName
+       }
+     | element ns1:DebugSymbols { xsd:boolean }
+     | element ns1:DebugType { xsd:NCName }
+     | element ns1:DefineConstants { text }
+     | element ns1:DependsOnNETStandard { xsd:NCName }
+     | element ns1:Deterministic { xsd:boolean }
+     | element ns1:DocumentationFile { text }
+     | element ns1:EnableUnmanagedDebugging { xsd:boolean }
+     | element ns1:ErrorReport { xsd:NCName }
+     | element ns1:FileAlignment { xsd:integer }
+     | element ns1:FileUpgradeFlags { empty }
+     | element ns1:FindInvalidProjectReferences { xsd:boolean }
+     | element ns1:FriendlyName { xsd:NCName }
+     | element ns1:GenerateBindingRedirectsOutputType { xsd:boolean }
+     | element ns1:IISExpressAnonymousAuthentication { empty }
+     | element ns1:IISExpressSSLPort { text }
+     | element ns1:IISExpressUseClassicPipelineMode { empty }
+     | element ns1:IISExpressWindowsAuthentication { empty }
+     | element ns1:Install { xsd:boolean }
+     | element ns1:InstallFrom { xsd:NCName }
+     | element ns1:InstallUrl { empty }
+     | element ns1:IsCodedUITest { xsd:NCName }
+     | element ns1:IsWebBootstrapper { xsd:NCName }
+     | element ns1:LoadBehavior { xsd:integer }
+     | element ns1:ManifestCertificateThumbprint { text }
+     | element ns1:ManifestKeyFile { text }
+     | element ns1:MapFileExtensions { xsd:boolean }
+     | element ns1:NoStandardLibraries { xsd:boolean }
+     | element ns1:NoWarn { text }
+     | element ns1:NuGetPackageImportStamp { empty }
+     | element ns1:NugetExe { text }
+     | element ns1:OfficeApplicationDescription { empty }
+     | element ns1:OldToolsVersion { xsd:decimal }
+     | element ns1:Optimize { xsd:boolean }
+     | element ns1:OutputPath { text }
+     | element ns1:OutputType { xsd:NCName }
+     | element ns1:PackageDestinationDirectory { text }
+     | element ns1:Platform {
+         attribute Condition { text },
+         xsd:NCName
+       }
+     | element ns1:PlatformTarget { xsd:NCName }
+     | element ns1:Prefer32Bit { xsd:boolean }
+     | element ns1:ProductName { xsd:NCName }
+     | element ns1:ProductVersion { text }
+     | element ns1:ProjectGuid { text }
+     | element ns1:ProjectTypeGuids { text }
+     | element ns1:PublishUrl { text }
+     | element ns1:PublisherName { empty }
+     | element ns1:ReferencePath { text }
+     | element ns1:RestorePackages { xsd:boolean }
+     | element ns1:RootNamespace { xsd:NCName }
+     | element ns1:RunPostBuildEvent { xsd:NCName }
+     | element ns1:SccAuxPath { xsd:anyURI }
+     | element ns1:SccLocalPath { xsd:NMTOKEN }
+     | element ns1:SccProjectName { text }
+     | element ns1:SccProvider { text }
+     | element ns1:SchemaVersion { xsd:decimal }
+     | element ns1:SignAssembly { xsd:boolean }
+     | element ns1:SignManifests { xsd:boolean }
+     | element ns1:SolutionDir {
+         attribute Condition { text },
+         text
+       }
+     | element ns1:StartupObject { empty }
+     | element ns1:SupportUrl { empty }
+     | element ns1:TargetCulture { xsd:NCName }
+     | element ns1:TargetFrameworkProfile { text }
+     | element ns1:TargetFrameworkVersion { xsd:NCName }
+     | element ns1:TargetVsixContainerName { xsd:NCName }
+     | element ns1:TestProjectType { xsd:NCName }
+     | element ns1:TypeScriptCompileBlocked { xsd:boolean }
+     | element ns1:TypeScriptToolsVersion { xsd:decimal }
+     | element ns1:UpdateEnabled { xsd:boolean }
+     | element ns1:UpdateInterval { xsd:integer }
+     | element ns1:UpdateIntervalUnits { xsd:NCName }
+     | element ns1:UpdateMode { xsd:NCName }
+     | element ns1:UpdatePeriodically { xsd:boolean }
+     | element ns1:UpdateRequired { xsd:boolean }
+     | element ns1:UpgradeBackupLocation { empty }
+     | element ns1:Use64BitIISExpress { empty }
+     | element ns1:UseApplicationTrust { xsd:boolean }
+     | element ns1:UseGlobalApplicationHostFile { empty }
+     | element ns1:UseIISExpress { xsd:boolean }
+     | element ns1:UseVSHostingProcess { xsd:boolean }
+     | element ns1:VSTO_TrustAssembliesLocation { xsd:boolean }
+     | element ns1:VSToolsPath {
+         attribute Condition { text },
+         text
+       }
+     | element ns1:VisualStudioVersion {
+         attribute Condition { text },
+         xsd:decimal
+       }
+     | element ns1:WarningLevel { xsd:integer }
+     | element ns1:WcfConfigValidationEnabled { xsd:NCName })*,
+    element ns1:UseCodebase { xsd:boolean }?,
+    element ns1:GeneratePkgDefFile { xsd:boolean }?,
+    (element ns1:CopyBuildOutputToOutputDirectory { xsd:boolean }
+     | element ns1:CopyOutputSymbolsToOutputDirectory { xsd:boolean }
+     | element ns1:CopyVsixManifestToOutput { xsd:boolean }
+     | element ns1:CreateVsixContainer { xsd:boolean }
+     | element ns1:DeployExtension { xsd:boolean }
+     | element ns1:DeployVSTemplates { xsd:boolean }
+     | element ns1:IncludeAssemblyInVSIXContainer { xsd:boolean }
+     | element ns1:IncludeDebugSymbolsInLocalVSIXDeployment {
+         xsd:boolean
+       }
+     | element ns1:IncludeDebugSymbolsInVSIXContainer { xsd:boolean }
+     | element ns1:RuntimeIdentifier { xsd:NCName })*,
+    (element ns1:ApplicationIcon { xsd:NCName }
+     | element ns1:OfficeApplication { xsd:NCName }
+     | element ns1:PostBuildEvent {
+         attribute Condition { text }?,
+         text
+       }*
+     | (element ns1:StartAction { xsd:NCName },
+        element ns1:StartProgram {
+          attribute Condition { text },
+          text
+        },
+        element ns1:StartArguments { text },
+        element ns1:EnableNoticeInVisualStudioVsix { xsd:boolean }))
+  }
+ns1.ItemGroup =
+  element ns1:ItemGroup {
+    (element ns1:AssemblyAttributes {
+       attribute Include { xsd:NCName },
+       element ns1:_Parameter1 { text }
+     }
+     | element ns1:COMReference {
+         attribute Include { xsd:NCName },
+         element ns1:Guid { text },
+         element ns1:VersionMajor { xsd:integer },
+         element ns1:VersionMinor { xsd:integer },
+         element ns1:Lcid { xsd:integer },
+         element ns1:WrapperTool { xsd:NCName },
+         element ns1:Isolated { xsd:NCName },
+         ns1.EmbedInteropTypes
+       }
+     | element ns1:WCFMetadata {
+         attribute Include { text }
+       }
+     | element ns1:ProjectReference {
+         attribute Include { text },
+         ns1.Project,
+         element ns1:Name { xsd:NCName },
+         (ns1.VSIXSubPath,
+          element ns1:ReferenceOutputAssembly { xsd:boolean })?,
+         element ns1:IncludeOutputGroupsInVSIX { text }?,
+         element ns1:IncludeOutputGroupsInVSIXLocalOnly { text }?
+       }*
+     | element ns1:Folder {
+         attribute Include { text }
+       }*),
+    element ns1:VSTemplate {
+      attribute Include { xsd:NCName },
+      element ns1:OutputSubPath { xsd:NCName }?,
+      ns1.SubType
+    }*,
+    (element ns1:CodeAnalysisDependentAssemblyPaths {
+       attribute Condition { text },
+       attribute Include { text },
+       element ns1:Visible { xsd:NCName }
+     }
+     | element ns1:PackageSourceDirectory {
+         attribute Include { text }
+       }
+     | element ns1:WebReferences {
+         attribute Include { text }
+       }
+     | element ns1:Page {
+         attribute Include { text },
+         ns1.Generator,
+         ns1.SubType
+       }*
+     | element ns1:Reference {
+         attribute Include { text },
+         element ns1:RequiredTargetFramework { xsd:decimal }?,
+         element ns1:SpecificVersion { xsd:NCName }?,
+         ns1.EmbedInteropTypes?,
+         element ns1:HintPath { text }?,
+         element ns1:Private { xsd:NCName }?,
+         ns1.Paket?
+       }*
+     | element ns1:VSIXSourceItem {
+         attribute Exclude { text }?,
+         attribute Include { text },
+         attribute VSIXSubPath { xsd:NCName }?,
+         ns1.VSIXSubPath?
+       }*
+     | element ns1:PackageReference {
+         attribute Include { xsd:NCName },
+         attribute Version { text }?,
+         element ns1:Version { xsd:NMTOKEN }?,
+         element ns1:IncludeAssets { text }?,
+         element ns1:PrivateAssets { xsd:NCName }?
+       }*
+     | element ns1:Analyzer {
+         attribute Include { text },
+         ns1.Paket
+       }*),
+    element ns1:ApplicationDefinition {
+      attribute Include { xsd:NCName },
+      ns1.Generator,
+      ns1.SubType
+    }?,
+    (element ns1:Compile {
+       attribute Include { text },
+       element ns1:AutoGen { xsd:NCName }?,
+       ns1.Link?,
+       (ns1.DependentUpon
+        | element ns1:DesignTime { xsd:NCName }
+        | element ns1:DesignTimeSharedInput { xsd:NCName })*,
+       ns1.SubType?
+     }
+     | element ns1:Content {
+         attribute Include { text },
+         element ns1:IncludeInVSIX { xsd:boolean }?,
+         (ns1.CopyToOutputDirectory | ns1.DependentUpon | ns1.SubType)?
+       }
+     | element ns1:EmbeddedResource {
+         attribute Include { text },
+         (ns1.Generator, ns1.LastGenOutput)?,
+         (ns1.DependentUpon | ns1.SubType)?
+       }
+     | element ns1:EntityDeploy {
+         attribute Include { xsd:NCName },
+         ns1.Generator,
+         ns1.LastGenOutput
+       }
+     | element ns1:None {
+         attribute Include { text },
+         (ns1.Generator, ns1.LastGenOutput)?,
+         (ns1.DependentUpon | ns1.Link)?,
+         ns1.CopyToOutputDirectory?,
+         ns1.SubType?
+       }
+     | element ns1:Resource {
+         attribute Include { text }
+       })*,
+    (element ns1:AppDesigner {
+       attribute Include { text }
+     }
+     | element ns1:Service {
+         attribute Include { text }
+       }*)
+  }
+ns1.Output =
+  element ns1:Output {
+    attribute ItemName { xsd:NCName }?,
+    attribute PropertyName { xsd:NCName }?,
+    attribute TaskParameter { xsd:NCName }
+  }
+EmbedInteropTypes = element EmbedInteropTypes { xsd:NCName }
+Generator = element Generator { text }
+SubType = element SubType { text }
+LastGenOutput = element LastGenOutput { xsd:NCName }
+CopyToOutputDirectory = element CopyToOutputDirectory { xsd:NCName }
+DependentUpon = element DependentUpon { text }
+CopyToPublishDirectory = element CopyToPublishDirectory { xsd:NCName }
+Link = element Link { text }
+ExcludeFromSingleFile = element ExcludeFromSingleFile { xsd:boolean }
+ns1.VSIXSubPath = element ns1:VSIXSubPath { xsd:NCName }
+ns1.EmbedInteropTypes = element ns1:EmbedInteropTypes { xsd:NCName }
+ns1.SubType = element ns1:SubType { xsd:NCName }
+ns1.Generator = element ns1:Generator { xsd:NMTOKEN }
+ns1.Paket = element ns1:Paket { xsd:NCName }
+ns1.LastGenOutput = element ns1:LastGenOutput { xsd:NCName }
+ns1.DependentUpon = element ns1:DependentUpon { xsd:NCName }
+ns1.Link = element ns1:Link { text }
+ns1.CopyToOutputDirectory =
+  element ns1:CopyToOutputDirectory { xsd:NCName }
diff --git a/etc/schema/nuget.rnc b/etc/schema/nuget.rnc
new file mode 100644
index 00000000000..ab7052e91d1
--- /dev/null
+++ b/etc/schema/nuget.rnc
@@ -0,0 +1,25 @@
+default namespace = ""
+
+start =
+  element configuration {
+    element packageRestore { add+ }?,
+    (element config { add }
+     | element packageSourceMapping {
+         element packageSource {
+           attribute key { xsd:NCName },
+           element package {
+             attribute pattern { text }
+           }
+         }+
+       }
+     | element packageSources {
+         element clear { empty },
+         add+
+       })+
+  }
+add =
+  element add {
+    attribute key { xsd:NCName },
+    attribute protocolVersion { xsd:integer }?,
+    attribute value { xsd:anyURI }
+  }
diff --git a/etc/schema/nuspec.rnc b/etc/schema/nuspec.rnc
new file mode 100644
index 00000000000..a4332f84fc0
--- /dev/null
+++ b/etc/schema/nuspec.rnc
@@ -0,0 +1,100 @@
+namespace a = "http://relaxng.org/ns/compatibility/annotations/1.0"
+default namespace mstns = "http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"
+namespace rng = "http://relaxng.org/ns/structure/1.0"
+
+dependency =
+  attribute id { xsd:string },
+  attribute version { xsd:string }?,
+  attribute include { xsd:string }?,
+  attribute exclude { xsd:string }?
+dependencyGroup =
+  element dependency { dependency }*,
+  attribute targetFramework { xsd:string }?
+reference = attribute file { xsd:string }
+contentFileEntries =
+  attribute include { xsd:string },
+  attribute exclude { xsd:string }?,
+  attribute buildAction { xsd:string }?,
+  attribute copyToOutput { xsd:boolean }?,
+  attribute flatten { xsd:boolean }?
+referenceGroup =
+  element reference { reference }+,
+  attribute targetFramework { xsd:string }?
+frameworkReference = attribute name { xsd:string }
+frameworkReferenceGroup =
+  element frameworkReference { frameworkReference }*,
+  attribute targetFramework { xsd:string }
+start |= starting_package
+starting_package =
+  element package {
+    element metadata {
+      (element id { xsd:string }
+       & element version { xsd:string }
+       & element title { xsd:string }?
+       & element authors { xsd:string }
+       & element owners { xsd:string }?
+       & element licenseUrl { xsd:anyURI }?
+       & element projectUrl { xsd:anyURI }?
+       & element iconUrl { xsd:anyURI }?
+       & element requireLicenseAcceptance { xsd:boolean }?
+       & element developmentDependency { xsd:boolean }?
+       & element description { xsd:string }
+       & element summary { xsd:string }?
+       & element releaseNotes { xsd:string }?
+       & (element copyright { xsd:string }?)
+         >> a:documentation [
+              "\x{a}" ~
+              "            default value is : en-US"
+            ]
+       & element language { xsd:string }?
+       & element tags { xsd:string }?
+       & element serviceable { xsd:boolean }?
+       & element icon { xsd:string }?
+       & element readme { xsd:string }?
+       & element repository {
+           attribute type { xsd:string }?,
+           attribute url { xsd:anyURI }?,
+           attribute branch { xsd:string }?,
+           attribute commit { xsd:string }?
+         }?
+       & element license {
+           xsd:string,
+           attribute type { xsd:string },
+           attribute version { xsd:string }?
+         }?
+       & element packageTypes {
+           element packageType {
+             attribute name { xsd:string },
+             attribute version { xsd:string }?
+           }*
+         }?
+       & element dependencies {
+           (element dependency { dependency }
+            | element group { dependencyGroup })*
+         }?
+       & element frameworkAssemblies {
+           element frameworkAssembly {
+             attribute assemblyName { xsd:string },
+             attribute targetFramework { xsd:string }?
+           }*
+         }?
+       & element frameworkReferences {
+           element group { frameworkReferenceGroup }*
+         }?
+       & element references {
+           (element reference { reference }
+            | element group { referenceGroup })*
+         }?
+       & element contentFiles {
+           (element files { contentFileEntries })*
+         }?),
+      attribute minClientVersion { xsd:string }?
+    },
+    element files {
+      element file {
+        attribute src { xsd:string },
+        attribute target { xsd:string }?,
+        attribute exclude { xsd:string }?
+      }*
+    }?
+  }
diff --git a/etc/schema/schemas.xml b/etc/schema/schemas.xml
index f04bba849b4..be0dacd6ecf 100644
--- a/etc/schema/schemas.xml
+++ b/etc/schema/schemas.xml
@@ -66,4 +66,31 @@
   <typeId id="LibreOffice" uri="OpenDocument-schema-v1.3+libreoffice.rnc"/>
   <typeId id="OpenDocument Manifest" uri="od-manifest-schema-v1.2-os.rnc"/>
 
+  <!-- .net development related schemas -->
+  <uri pattern="nuget.config" typeId="Nuget Config" />
+  <typeId id="Nuget Config" uri="nuget.rnc" />
+
+  <uri pattern="*.nuspec" typeId="Nuget Spec" />
+  <namespace ns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd" typeId="Nuget Spec" />
+  <typeId id="Nuget Spec" uri="nuspec.rnc" />
+
+  <uri pattern="web.config" typeId="Dotnet App Config" />
+  <uri pattern="app.config" typeId="Dotnet App Config" />
+  <namespace ns="http://schemas.microsoft.com/.NetConfiguration/v2.0" typeId="Dotnet App Config" />
+  <typeId id="Dotnet App Config" uri="dotnet-appconfig.rnc" />
+
+  <uri pattern="Directory.Packages.props" typeId="Dotnet Packages Props" />
+  <typeId id="Dotnet Packages Props" uri="dotnet-packages-props.rnc" />
+
+  <uri pattern="packages.config" typeId="Dotnet Packages Config" />
+  <typeId id="Dotnet Packages Config" uri="dotnet-packages-config.rnc" />
+
+  <uri pattern="*.resx" typeId="Dotnet Resx" />
+  <typeId id="Dotnet Resx" uri="dotnet-resx.rnc" />
+
+  <uri pattern="*.*proj" typeId="MSBuild" />
+  <uri pattern="Directory.Build.props" typeId="MSBuild" />
+  <documentElement localName="Project" typeId="MSBuild"/>
+  <typeId id="MSBuild" uri="msbuild.rnc" />
+
 </locatingRules>
-- 
2.39.3 (Apple Git-145)


[-- Attachment #3: Type: text/plain, Size: 2987 bytes --]



—
Kind Regards
Jostein Kjønigsen

> On 22 Feb 2024, at 16:13, Jostein Kjønigsen <jostein@secure.kjonigsen.net> wrote:
> 
> 
> 
>> On 21 Feb 2024, at 04:01, Stefan Kangas <stefankangas@gmail.com> wrote:
>> 
>>> Basically as a minimum make sure it works for more people than just me.
>> 
>> What happens if it doesn't "work" in this context?  Can it hurt or is it
>> just an extra feature that they won't benefit from?
> 
> In terms of “working" I would consider the following:
> 
> * The appropriate schemas are activated for the appropriate and expected files.
> * The schemas, when activated, do not create warnings for correctly formatted XML-files (according to that schema).
> 
> In terms of NOT working, I would consider the following:
> 
> * A schema is activated for a file which it is not appropriate for.
> * A schema, when activated for an appropriate file-type, flags correctly formatted XML-elements within that file as erroneous.
> 
>> - I think this should also come with updates to etc/schemas/README
>>  describing the copyright and legal status of these new schemas.
>>  See that file to get an idea of what's needed.
> 
> I didn't know about that one. Will look into it!
> 
>> - Does "Dotnet" also include "Mono" (or some other free software
>>  replacement)?  If yes, I think the commit message should say so
>>  explicitly, so that we mention both but advertise mainly the free
>>  version.  I.e. it should say "Mono/Dotnet" rather than "Dotnet/Mono".
> 
> Not going to go for a technical deep dive here, but in short:
> 
> - .NET Framework was a closed-source Windows only development platform created by Microsoft
> - Mono is a open-source cross-platform reimplementation of .NET Framework
> 
> Today when one refers to .NET when typically refers to the “new” modern .NET project (with no “framework” suffix), which is both open-source and cross-platform. Modern .NET supersedes .NET Framework, and in many ways Mono as well.
> 
> While all file-types covered by schemas submitted here are relevant/applicable to all those three development platforms, as they all work on the same type of source-files and build-systems… I would argue that the “main” development target these days for any developer working on up to date tooling is going to be .NET, not Mono. As such, I think just referring to it as dotnet is appropriate.
> 
>> - Should this be called out in NEWS?
> 
> It could. I have no opinion on how “big” a feature/change has to be before it’s considered newsworthy.
> 
> I’ll let more seasoned Emacs-contributors decide that, if that’s OK.
> 
>> - (This should also have a proper ChangeLog in the commit message, of
>>  course.)
> 
> 
> I thought I added a pretty decent one in my commit… Was that not included in the patch?
> 
> Or do you mean adding it to a ChangeLog file of some sort? If so, which one?
> 
> 
> —
> Kind Regards
> Jostein Kjønigsen


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] Adding new schemas to nxml-mode
  2024-02-23 14:25         ` Jostein Kjønigsen
@ 2024-05-18 19:48           ` Stefan Kangas
  0 siblings, 0 replies; 7+ messages in thread
From: Stefan Kangas @ 2024-05-18 19:48 UTC (permalink / raw)
  To: Jostein Kjønigsen; +Cc: emacs-devel

Jostein Kjønigsen <jostein@secure.kjonigsen.net> writes:

> This latest patch addresses the copyright/readme issue, and also
> tweaks the schemas slightly after I've found a few inconsistencies
> locally.

Since there have been no further comments within 3 months, I have now
pushed this to master (e75921a1dcd).  Please note the ChangeLog entry
that I've added to the commit message, according to the guidelines
detailed in the CONTRIBUTE file.

I've also announced the change in etc/NEWS in a followup commit
(e74eedaa2e3).

Thanks for your contribution!



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2024-05-18 19:48 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-02-18 20:12 Adding new schemas to nxml-mode. Am I doing it right? Jostein Kjønigsen
2024-02-19 22:20 ` Stefan Kangas
2024-02-20 20:02   ` [PATCH] Adding new schemas to nxml-mode Jostein Kjønigsen
2024-02-21  3:01     ` Stefan Kangas
2024-02-22 15:13       ` Jostein Kjønigsen
2024-02-23 14:25         ` Jostein Kjønigsen
2024-05-18 19:48           ` Stefan Kangas

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.