Skip to content

XMLFileAssociations: Comparing schemas but should compare files #1053

Closed

Description

@marrom18

In XMLFileAssociations (both add and remove) there is a lookup for existing schemas (systemId), instead there should be a lookup for existing files (or patterns)

Image

Activity

  1. DanielSchnabelDsl commented on Feb 11, 2025

    @DanielSchnabelDsl

    Let me elaborate a little bit on our use case. We want to use the extension interface of your XML extension to provide autocompletion for our XML-based format. Our problem right now is that we ship a different XSD file for each version of the schema. This makes it so, if the user picks the correct one, they know exactly which properties they can use and also allows us to the backward compatible with earlier schemas. In our vscode extension we would like to expand on this idea and automatically pick the correct schema for validation based on the version tag in the file. See this example:

    <Root schema-version="1.5">...

    Here, the schema-version is 1.5 which means that we would like to use schema-1.5.xsd for validation.

    Our idea is to use the addXMLFileAssociations method from our own VsCode extension to add a new association whenever the user opens a new document (or changes the current one). So if the user opens File1.myfile then we would parse the version number and then decide to add an association with pattern being "File1.myfile" and "systemId" being the path to schema-1.5.xsd. This doesn't work, however, because the addXMLFileAssociations function only allows a every systemId to be referenced only once. So we can't have two files which use the same XSD file for validation. One solution to this would be to allow the systemId to be used multiple times.

  2. angelozerr commented on Feb 11, 2025

    @angelozerr
    Contributor

    To be honest with you, I don't remember how XML file associations works on vscode-xml side (@datho7561 doyou remember)?

    Have you the capability to manage your usecase with Java, because lemminx, the XML language server is extensible and should manage this usecase.

  3. DanielSchnabelDsl commented on Feb 11, 2025

    @DanielSchnabelDsl

    To be honest with you, I don't remember how XML file associations works on vscode-xml side (@datho7561 doyou remember)?

    Have you the capability to manage your usecase with Java, because lemminx, the XML language server is extensible and should manage this usecase.

    I have looked at lemminx before and it looks like a great option. And, still, I think that it is a bit too complex for us right now to develop, maintain and distribute a java binary based on lemminx. It's possible that we'll end up going that route in the distant future but for now we'd love to use this XML extension as a base because that simplified all these areas.

  4. datho7561 commented on Feb 11, 2025

    @datho7561
    Contributor

    To be honest with you, I don't remember how XML file associations works on vscode-xml side (@datho7561 doyou remember)?

    The file associations feature allows you use globs and to specify which files attach to which schema. However, the schema (systemId) must be a static path. There is no mechanism to allow querying values of attributes of the XML document and adjusting the schema based on that.

    As Angelo mentioned, it's possible to associate the XML document with the schema by using a custom Java extension to lemminx that specifies this look up logic in the Java code. (This would be instead of using the fileAssociation feature).

    However, I personally think it's simplest to add a <?xml-model ... prologue instruction or a schemaAssociation to the XML document to specify the schema to use (if you are allowed to modify the document).

  5. DanielSchnabelDsl commented on Feb 11, 2025

    @DanielSchnabelDsl

    The file associations feature allows you use globs and to specify which files attach to which schema. However, the schema (systemId) must be a static path. There is no mechanism to allow querying values of attributes of the XML document and adjusting the schema based on that.

    We use our own extension to parse the XML file to figure out the schema we want to use. So it's not necessary for the redhat xml extension to provide any mechanism for that. I have an example here to show how we are trying to use the file association feature:

    function onFileOpenedOrChanged() {
      // get the file to the path using the VsCode extension API
      const filePath = ...;
      // find the version of the schema with RegEx or something else
      const version = ...;
      // find the path to the correct xsd
      const schemaPath = `/path/to/schema-${version}.xsd`;
    
      // start talking to the redhat xml extension
      const ext = await vscode.extensions.getExtension('redhat.vscode-xml')?.activate();
      // register the schema for just that file
      ext.addXMLFileAssociations([
        {
          pattern: filePath,
          systemId: schemaPath,
        },
      ]);
    }

    This example here works, but it only works if we have a single file! The reason is that all the file associations must be unique by systemId (schemaPath). addXMLFileAssociations won't add a second association if one with the same systemId already exists. This is a little bit backwards to me, because I would assume that it works the other way around, that you can't have two file associations with the same pattern. Logically, there doesn't seem to be a problem with two different patterns using the same system id. I think that this could also be an issue for other extensions, it probably just hasn't happened. What we're suggesting is to allow adding multiple file associations with the same system id, that would fix this issue for us.

    However, I personally think it's simplest to add a <?xml-model ... prologue instruction or a schemaAssociation to the XML document to specify the schema to use (if you are allowed to modify the document).

    We could modify the document and insert a xsi:noNamespaceSchemaLocation="/path/to/schema.xsd. As I understand this is similar to the <?xml-model approach? This is also an option, but if we have to put a relative or absolute path to an xsd file there then that path might not be correct on someone elses system, because the files are located in a different place. It might making version management in git a little bit awkward in that regard.

  6. datho7561 commented on Feb 11, 2025

    @datho7561
    Contributor

    This example here works, but it only works if we have a single file! The reason is that all the file associations must be unique by systemId (schemaPath).

    Okay, I see. I misunderstood the original comment. This seems bad and something that we can address, I'll take a look at it.

    We could modify the document and insert a xsi:noNamespaceSchemaLocation="/path/to/schema.xsd. As I understand this is similar to the <?xml-model approach?

    Yes this is correct.

    if we have to put a relative or absolute path to an xsd file there then that path might not be correct on someone elses system

    If you are able to host the .xsd files on the web (or company intranet or something) then you can point to a URL instead of relative/absolute path. Then the same location can be used on different systems. lemminx will download and cache the .xsd . I guess this isn't a great option if the .xsd are being modified fairly consistently, though.

  7. DanielSchnabelDsl commented on Feb 11, 2025

    @DanielSchnabelDsl

    If you are able to host the .xsd files on the web (or company intranet or something) then you can point to a URL instead of relative/absolute path. Then the same location can be used on different systems. lemminx will download and cache the .xsd . I guess this isn't a great option if the .xsd are being modified fairly consistently, though.

    That definitely sounds like a good alternative since our xsd files don't get modified after we release them. I'm a little bit worried that our customers might have proxy issues when the files get downloaded (they might have some aggressive company policies regarding that) but we can figure that out!

  8. angelozerr commented on Feb 11, 2025

    @angelozerr
    Contributor

    If you are able to host the .xsd files on the web (or company intranet or something) then you can point to a URL instead of relative/absolute path. Then the same location can be used on different systems. lemminx will download and cache the .xsd . I guess this isn't a great option if the .xsd are being modified fairly consistently, though.

    That definitely sounds like a good alternative since our xsd files don't get modified after we release them. I'm a little bit worried that our customers might have proxy issues when the files get downloaded (they might have some aggressive company policies regarding that) but we can figure that out!

    @DanielSchnabel2 I am not against to do some changes on vscode-xml side if it doesnt break the existing file association support.

    I suggest that you create a PR with your expected behaviour

  9. DanielSchnabelDsl commented on Feb 12, 2025

    @DanielSchnabelDsl

    Just as an additonal note, I searched for usages of of the addXMLFileAssociations globally on GitHub and it appears that someone else has run into the same issue already. They got around it by making the paths unique by including "/./" multiple times in the path.

    https://github.com/Desdaemon/odoo-lsp/blob/cb3267708ec67ddc09527bf0b9ff9d4cbd5940bc/client/src/xml.ts#L18-L39

    xmlApi.addXMLFileAssociations([
      // HACK: systemId must be unique
      {
        systemId: `${context.extensionUri}/odoo.rng`,
        pattern: "views/*.xml",
      },
      {
        systemId: `${context.extensionUri}/./odoo.rng`,
        pattern: "data/*.xml",
      },
      // ...
    ]);

    We'll try to come up with a solution for this that's backwards compatible and create a PR.

  10. added a commit that references this issue on Feb 12, 2025
    6bbc6ed
  11. datho7561 commented on Feb 12, 2025

    @datho7561
    Contributor

    @DanielSchnabel2 @marrom18 I made a quick PR with the changes you suggested. I tested it with a local dummy extension that adds two file associations with the same system id, and it seems to be working.

  12. marrom18 commented on Mar 3, 2025

    @marrom18
    Author

    @angelozerr Could you please review the pull request, so we can go on further with the bug fix.

  13. added a commit that references this issue on Mar 3, 2025
    5a4cbb1
  14. self-assigned this
    on Mar 3, 2025
  15. added this to the 0.28.0 milestone on Mar 3, 2025
  16. marrom18 commented on Mar 4, 2025

    @marrom18
    Author

    When do you release the extension with the bug fix?

  17. datho7561 commented on Mar 4, 2025

    @datho7561
    Contributor

    When do you release the extension with the bug fix?

    There should be a pre-release version of the extension available if you switch to "prereleases" in VS Code. This will contain the fix, since we build these nightly.

    @angelozerr @rgrunber the last release we did was in November. We have a few important changes we've made (fix for binary on older CPUs, move to Java 11, and this change). It might be interesting to perform a release. However, we might want to go through the PR queue in lemminx first.

  18. angelozerr commented on Mar 4, 2025

    @angelozerr
    Contributor

    When do you release the extension with the bug fix?

    There should be a pre-release version of the extension available if you switch to "prereleases" in VS Code. This will contain the fix, since we build these nightly.

    @angelozerr @rgrunber the last release we did was in November. We have a few important changes we've made (fix for binary on older CPUs, move to Java 11, and this change). It might be interesting to perform a release. However, we might want to go through the PR queue in lemminx first.

    If you have time to do the release of lemminx and vscode-xml it would be very nice!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions