XML EDITOR WITH XSD BASED CODE COMPLETION

Hi,
I search a WinForms component with advanced XML editor functionality: code completion and validation should be performed based on a XSD file. Or at least it should be based on an object tree - our XML is the result of serializing an object.
I found the "XML Editor" sample: https://forum.alternetsoft.com/t/xml-editor/27/3
But this only shows basic code completion, which needs a lot of improvement ;-).
Do you have any plans to enhance the XML editor?
Best regards
Wolfgang
After thinking more about it: actually we don't need a XSD based code completion, but a code completion based on an object tree annotated with xml serialization attributes:
-The root object has the "XmlRoot" attribute.
-Allowed childs elements would be "XmlElement" and "XmlArray/XmlArrayItem".
-Attributes have "XmlAttribute".
So the trick would probably be to find the current position in the object tree according to the current selection (based on the parent element names of the currently selected element) and then decide which child elements/attributes are allowed.
This could probably done by starting with the code of the "XmlEditor" sample, but I would have to do more research.
Code completion should be done for:
-when entering the "<" char,
-for attributes: when entering a space inside xml elements.
-for attribute values: when entering a "="

And the final problem: how to validate it and show errors? One could probably use the .NET XmlValidator and create a xsd file based on the object tree. The validator provides error locations. Or is there a better way?

Best regards
Wolfgang
Hi Wolfgang,
We will look at what's required to support xsd-based code completion for XML parser.
One idea is to use LangServer.org approach, by using one of the following implementations:
eclipse/lemminx: XML Language Server (github.com)
XML - Visual Studio Marketplace
However it would require installing this server on a user machine (and they both require Java), which would make it quite heavy.
Another approach would be to do a custom implementation, similarly to what we've done for XAML and Python.
We will investigate both options.
Regards,
Andrew
Thanks, this sounds very promising!
I would prefer the approach which does not require a language server. This is a bit of an overkill for one small part of our application.
Best regards
Wolfgang
Hi Wolfgang,
We looked at it and implementing xsd-based code completion will require considerable effort.
Currently this feature is scheduled for the next major update.
Kind regards,
Dmitry
No problem - it is a "nice to have" feature for a small part of our application. So there is no hurry for this.
Best regards
Wolfgang

Hi Dmitry and Andrew,

just to make sure that our requirement is fulfilled when you finally release your parser: I created an XSD file and a sample XML: https://www.hg-online.de/downloads/AlternetXsdParserSample.zip
Could you keep this file in mind when implementing the parser ;-)?

There is not much special about it, the only relevant part is a bunch of attributes which have enumerated values. The are declared like this:

<simpleType name="TabAlignment">
	<restriction base="string">
		<enumeration value="Left"/> 
		<enumeration value="Center"/> 
		<enumeration value="Right"/> 
		<enumeration value="Decimal"/> 
		<enumeration value="Bar"/> 
		<enumeration value="List"/> 
		<enumeration value="Clear"/> 
	</restriction>
</simpleType>

The values should be listed in code completion.

I wrote code to create this XSD from a class, parsing the “XmlElement/XmlAttribute/XmlArray/XmlArrayItem” attributes.

I would like to add documentation which might be shown in the code completion popup or on mouse hover (by placing “Description” attributes on each property/class). Could this be implemented in your parser?

  <element name="xyz" type="string" minOccurs="0">
    <annotation>
      <documentation>This is a comment</documentation>
    </annotation>
  </element>

I need some place where I can define the XSD source (which might be generated on the fly when populating the editor), e.g. an implementation of “System.Xml.XmlResolver”

Best regards

Wolfgang

Hi Wolfgang,

Thank you for providing these details.

We will include LSP-based XML parser (one that relies on Java to be installed) in the coming release, and will work on own simplified version which will gather available code completion for xml tags and attributes from xsd file. Will look at providing QuickInfo with descriptions as well.
Once we have some preliminary results available, we can share it with you.

Regards,
Dmitry

Thanks! I am looking forward to do some beta testing ;-).

Best regards
Wolfgang

Just one more point: will it be possible to provide the XSD file by Stream? As it will be generated in memory, I don’t want to save it to disk.

Best regards
Wolfgang

We have implemented basic code completion for xml tags and parameters based on xsd schema. It can be supplied to the parser by properties Schema, SchemaName or SchemaURL (later one can be web-based).

The parser also picks up embedded schema definition declared by the following tag:

<?xml-model href="your.xsd"?>

I’ve uploaded a sample project here, please let us know if you see any problems with it or have any suggestions for the code completion feature.

https://drive.google.com/file/d/1vOmku6OyJJMdR-NilmxlIFHDp7P_jc8u/view?usp=sharing

Just to some this up: a lot of improvements were added after some mail discussion, and now I am awaiting the final release :wink:

Best regards

Wolfgang

I upgraded to the new version, and it works great. Thanks for adding this feature - it is a big step forward in one small part of your application, where we use XML to configure our report output.

For those who are also interested in this feature:
Our implementation creates the XSD “on the fly”, so it is not available on disc or on a web location. We use this code to load the XsdSchema from a string:

    public static XmlSchema LoadSchemaFromString(string _schema)
    {
      using (MemoryStream memStream = new MemoryStream())
      {
        using (StreamWriter sw = new StreamWriter(memStream))
        {
          sw.Write(_schema);
          sw.Flush();

          memStream.Seek(0, SeekOrigin.Begin);

          return XmlSchema.Read(memStream, null);
        }
      }
    }

This XmlSchema is then set to the parser:

      XmlParserWithSchema parser = new XmlParserWithSchema();
      this.codeEditor.Source.Lexer = parser;
      parser.Schema = LoadSchemaFromString(...);

The xml snippet that we place in the editor has to declare a “xmlns” attribute, which must have the value of the “targetNamespace” attribute in the XSD.

   <myxml xmlns="mynamespace">

If you don’t provide the schema through your own code, you can use those two approaches:

  • First: use “xml-model”:
<?xml-model href="myschema.xsd"?>
  • Second: use “schemaLocation”:
<myxml xmlns="mynamespace" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
              xsi:schemaLocation="mynamespace http://www.mycompany.com/myschema.xsd">

And one bonus caveat: by default, the parser will not do code completion. You have to activate it yourself:

      XmlParserWithSchema parser = new XmlParserWithSchema();
      this.codeEditor.Source.Lexer = parser;
      parser.Options |= SyntaxOptions.CodeCompletion | SyntaxOptions.QuickInfoTips;

Hi Wolfgang,

Thank you for sharing your feedback, much appreciated!

We must have overlooked setting code completion default option - this will be fixed in the next update.

Regards,
Dmitry