dotnet / msbuild

The Microsoft Build Engine (MSBuild) is the build platform for .NET and Visual Studio.
https://docs.microsoft.com/visualstudio/msbuild/msbuild
MIT License
5.24k stars 1.35k forks source link

No types defined for elements in XSD schema #10983

Open eZprava opened 2 days ago

eZprava commented 2 days ago

Issue Description

In XSD there are many elements which should likely have type="xs:string", but they have no type at all, thus ur-type. Is it a bug, or a design choice? E.g.: https://github.com/dotnet/msbuild/blob/6cd445d84e59a36c7fbb6f50b7a5a62767a6da51/src/MSBuild/MSBuild/Microsoft.Build.CommonTypes.xsd#L24

// Friendly display name (optional) ### Steps to Reproduce - ### Expected Behavior - ### Actual Behavior - ### Analysis _No response_ ### Versions & Configurations _No response_
KalleOlaviNiemitalo commented 2 days ago

The type of the item metadata elements cannot be just xs:string because at least the Condition attribute must be allowed, perhaps Label too. Syntax example:

<Project>
  <ItemGroup>
    <PackageReference Include="Microsoft.Data.SqlClient">
      <VersionOverride Condition="$(TargetFramework) == 'netstandard2.0'">1.2.3</VersionOverride>
    </PackageReference>
  </ItemGroup>
</Project>

I'm not sure about whether MSBuild allows child elements in item metadata elements. It allows them in PropertyGroup/* elements; see GenericPropertyType in the schema.

eZprava commented 1 day ago

So it could be type derived from string which allows any attribute? I don't understand why one would need child elements in e.g. Name.

KalleOlaviNiemitalo commented 1 day ago

Yeah, I don't think child elements are needed in Name metadata.

AFAIK, these schemata are intended for Intellisense and online help in the Visual Studio IDE. If the item metadata elements were given more restrictive types, then would that help for those purposes, or would the types be overridden by some Visual Studio feature anyway?

eZprava commented 1 day ago

I don't know about VS - I used XSD to generate C# classes from Microsoft.Build.xsd and found out that Name is object instead of string. So I was curious if there's some deeper reason why one element has type="msb:boolean" while other has ur-type.

KalleOlaviNiemitalo commented 1 day ago

If you want to read, modify, and write MSBuild project files programmatically in C#, the MSBuild API has classes like Microsoft.Build.Construction.ProjectRootElement; see also MSBuildLocator.

On the other hand, if your program does not need to build those projects, and needs to tolerate future extensions to MSBuild project syntax even when neither the program itself nor any installed version of MSBuild supports them, then System.Xml APIs (including deserialisation) may be a better choice than the MSBuild API.

KalleOlaviNiemitalo commented 1 day ago

The MSBuild XML schema files have targetNamespace="http://schemas.microsoft.com/developer/msbuild/2003", and when you generate C# source code from these schemas, I think XmlSerializer will then require this XML namespace. However, MSBuild itself does not require that namespace nowadays, and IIRC the project templates in .NET SDK do not have xmlns="http://schemas.microsoft.com/developer/msbuild/2003". This may make the XSD-generated code unusable for projects that were created from those templates.

The classes in the Microsoft.Build.Construction namespace do not have this problem.

eZprava commented 23 hours ago

Thanks, I'm not using XmlSerializer. I have my own library to generate C# classes and I used .NET Framework .csproj as test files, to see if it can be round-tripped using generated classes. I needed to add support for substitution groups, it's cleverly used in the schema, it was new to me. Now it works, I was just curious why the Name element has ur-type, that's all.