Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Private Member Fields Missing due to Duplicate/Overlapping Name #374

Closed
flennic opened this issue Mar 7, 2023 · 8 comments
Closed

Private Member Fields Missing due to Duplicate/Overlapping Name #374

flennic opened this issue Mar 7, 2023 · 8 comments

Comments

@flennic
Copy link

flennic commented Mar 7, 2023

Given the sequence:

<xs:sequence>
    <xs:element ref="A001:header"   minOccurs="0" maxOccurs="unbounded"/>
    <xs:element ref="T001:document" minOccurs="0" maxOccurs="unbounded"/>
    <xs:element ref="T002:document" minOccurs="0" maxOccurs="unbounded"/>
    <xs:element ref="T003:document" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>

This leads to the problem that the private member field is named _document for all three T* namespaces (so the namespace name is not included). This results in only the first T-entry T001 (and the A entry) are to be found in the generated C# class file.

Is this a know issue and / or any way for a workaround?

If it is a known issue but no fix is yet available, can you point me to where in the code I find the private member name generation? I think it would be useful to somehow include the namespace in the member name to prevent this issue. I suppose this might introduce additional issues as the namespace can probably begin with characters which are not allowed in C#.

Would be grateful for any input on this as we really would like to use this tool for a larger project where we unfortunately are encountering this issue.

Thanks in advance,
flennic

@mganss
Copy link
Owner

mganss commented Mar 10, 2023

I've pushed a rather hacky fix to the DuplicatePropertyNames branch. Can you test that for your use case?

@flennic
Copy link
Author

flennic commented Mar 11, 2023

That was quick, thanks! I will test it in the beginning of next week and will let you know how it looks like.

Regards,
flennic

@flennic
Copy link
Author

flennic commented Mar 13, 2023

It seems the issue still persists. By quickly looking at your changes I can unfortunately not see what exactly is happening, I think I would have to debug step by step to get an understanding for myself :) For me it seems that it should create document1, document2 and so on; is that correct?

Assuming it would be working and my assumption is correct, it might still be hard to guess that e.g. document5 refers to T0077 when working with the model, so maybe it is a good idea to include the namespace (if clashes are detected) so that it ends up with _t001_document or _t001Document depending on the formatting.

I also have to keep in mind that we are not solving my specific case, but that we need a more general solution. So please do not hesitate to let me know if my suggestions are too specific :)

@mganss
Copy link
Owner

mganss commented Mar 13, 2023

Yes, it should create Document1, Document2 etc.

Currently, the property names are disambiguated using a generic algorithm. Let's get this to work first for your use case, then try and make the naming more specific.

Can you attach a sample schema here?

@flennic
Copy link
Author

flennic commented Mar 13, 2023

Unfortunately I cannot provide the original files, but I created a minimal example for reproducing the issue.

First, I wanted to give a step-by-step manual for how to produce the output files, but I do not get the tool to work on macOS with an M1* ARM processor. I can build and install the tool, however, when running the last command xscgen main-schema.xsd . I receive the following error:

Unhandled exception. System.UnauthorizedAccessException: Access to the path 'XXX' is denied.
 ---> System.IO.IOException: Permission denied
   --- End of inner exception stack trace ---
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String path, OpenFlags flags, Int32 mode)
   at Microsoft.Win32.SafeHandles.SafeFileHandle.Open(String fullPath, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
   at System.IO.Strategies.OSFileStreamStrategy..ctor(String path, FileMode mode, FileAccess access, FileShare share, FileOptions options, Int64 preallocationSize)
   at System.IO.Strategies.FileStreamHelpers.ChooseStrategy(FileStream fileStream, String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options, Int64 preallocationSize)
   at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize)
   at System.Xml.XmlDownloadManager.GetStream(Uri uri, ICredentials credentials, IWebProxy proxy)
   at System.Xml.XmlUrlResolver.GetEntity(Uri absoluteUri, String role, Type ofObjectToReturn)
   at System.Xml.XmlTextReaderImpl.FinishInitUriString()
   at System.Xml.XmlTextReaderImpl..ctor(String uriStr, XmlReaderSettings settings, XmlParserContext context, XmlResolver uriResolver)
   at System.Xml.XmlReaderSettings.CreateReader(String inputUri, XmlParserContext inputContext)
   at System.Xml.XmlReader.Create(String inputUri, XmlReaderSettings settings)
   at XmlSchemaClassGenerator.Generator.<>c__DisplayClass144_0.<Generate>b__0(String f) in C:\projects\xmlschemaclassgenerator\XmlSchemaClassGenerator\Generator.cs:line 330
   at System.Linq.Enumerable.SelectListIterator`2.MoveNext()
   at XmlSchemaClassGenerator.Generator.Generate(IEnumerable`1 files) in C:\projects\xmlschemaclassgenerator\XmlSchemaClassGenerator\Generator.cs:line 343
   at XmlSchemaClassGenerator.Console.Program.Main(String[] args) in C:\projects\xmlschemaclassgenerator\XmlSchemaClassGenerator.Console\Program.cs:line 238
[1]    86245 abort      xscgen main-schema.xsd .

Weirdly, there is a Windows path printed. I have no idea where C:\projects\xmlschemaclassgenerator\XmlSchemaClassGenerator.Console\Program.cs is coming from. Can it be that the project runs only on Windows as it used Microsoft.Win32.SafeHandles.SafeFileHandle.Open? I am missing something here. On my work computer — using Windows — the following steps actually work. However, this is a secondary issue we do not have to solve. Here are the steps:

  • mkdir xsd-demo
  • cd xsd-demo
  • git clone https://github.com/mganss/XmlSchemaClassGenerator
  • cd XmlSchemaClassGenerator
  • git pull origin DuplicatePropertyNames && git checkout DuplicatePropertyNames
  • dotnet pack -c Release
  • dotnet tool install --global --add-source xscgen/bin/Release dotnet-xscgen
  • cd ..
  • Create the 4 given files main-schema.xsd, schema_T0050.xsd, schema_T0051.xsd and schema_T0052.xsd in the current folder
  • xscgen main-schema.xsd .

And here the minimal files for reproducing the issue:

main-schema.xsd

<xs:schema xmlns="http://github.com/schemas"
           xmlns:xs="http://www.w3.org/2001/XMLSchema"
           xmlns:T0050="https://github.com/template/T0050"
           xmlns:T0051="https://github.com/template/T0051"
           xmlns:T0052="https://github.com/template/T0052"
           targetNamespace="http://github.com/schemas"
           elementFormDefault="qualified"
           version="1.0">
    <xs:import namespace="https://github.com/template/T0050" schemaLocation="schema_T0050.xsd"/>
    <xs:import namespace="https://github.com/template/T0051" schemaLocation="schema_T0051.xsd"/>
    <xs:import namespace="https://github.com/template/T0052" schemaLocation="schema_T0052.xsd"/>
    <xs:element name="output">
        <xs:complexType>
            <xs:sequence>
                <xs:element name="document" maxOccurs="unbounded">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element ref="T0050:documentpart" minOccurs="0" maxOccurs="unbounded"/>
                            <xs:element ref="T0051:documentpart" minOccurs="0" maxOccurs="unbounded"/>
                            <xs:element ref="T0052:documentpart" minOccurs="0" maxOccurs="unbounded"/>
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

schema_T0050.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="https://github.com/template/T0050"
           elementFormDefault="qualified">
    <xs:element name="documentpart">
        <xs:complexType>
            <xs:attribute name="templateid" use="required">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:length value="4"/>
                        <xs:pattern value="0050"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
        </xs:complexType>
    </xs:element>
</xs:schema>

schema_T0051.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="https://github.com/template/T0051"
           elementFormDefault="qualified">
    <xs:element name="documentpart">
        <xs:complexType>
            <xs:attribute name="templateid" use="required">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:length value="4"/>
                        <xs:pattern value="0010"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
        </xs:complexType>
    </xs:element>
</xs:schema>

schema_T0052.xsd

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="https://github.com/template/T0052"
           elementFormDefault="qualified">
    <xs:element name="documentpart">
        <xs:complexType>
            <xs:attribute name="templateid" use="required">
                <xs:simpleType>
                    <xs:restriction base="xs:string">
                        <xs:length value="4"/>
                        <xs:pattern value="0020"/>
                    </xs:restriction>
                </xs:simpleType>
            </xs:attribute>
        </xs:complexType>
    </xs:element>
</xs:schema>

@mganss
Copy link
Owner

mganss commented Mar 14, 2023

Thanks for creating the example schemas.

Regarding the exception I have a feeling that it's a permissions issue. The Win32 in the call stack is misleading, I think it's a .NET framework relic. Also, I have a feeling you're not using the locally built .NET tool, but the one from NuGet. C:\projects is probably the path on the CI build machine (AppVeyor). Perhaps try executing the binary from the project folder directly instead of installing the .NET tool.

It works for me using the schemas above. I see 3 private fields named _documentpart, _documentpart1, and _documentpart2 as well as 3 properties named Documentpart, Documentpart1, and Documentpart2.

@flennic
Copy link
Author

flennic commented Mar 14, 2023

Hm, maybe that is indeed the case that I am actually installing the version from NuGet. Actually a bit stupid of me for not checking the version after the installation... (I was very distracted with some weird macOS permission issues :o)

However, as you tested with the files above, we know that your branch fixes the issue. So I'd say let's ignore the problem on my side because I doubt it will add any further value to your fix.

As an information, we also tried the official xsd.exe tool and there the issue is solved in the same way, it adds numbers to the field names, but does not infer anything from the namespace. So your solution is at least on pair with the official version which I'd say it good.

Thanks four your time! I just saw you are also involved in the HtmlSanitizer I used some time ago, so special thanks for that project as well!

@mganss
Copy link
Owner

mganss commented Mar 16, 2023

I've merged the branch. Closing this for now.

@mganss mganss closed this as completed Mar 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants