# Fast-XML-Lint
## What is this
`Fast-XML-Lint` is a c-program/library which implements a linter for XML. It is based on `libxml2` and compiled from `c` to `javascript` via `emscripten`. The main advantage over using `xml.js` from kripken is that you need to parse+load the schema only once and then use that evaluated schema to verify your XML-document over and over again.

The second feature is the `schemainfoCreator.js`. It can be used to convert a relaxNG-schema-files into a schemaInfo-Object. The schemaInfo-Object is used to implement an autocompletion feature.

This all is packed together with code mirror into an editor for xml documents. For more details have a look at our demos.

# Linter
Using `fastXmlLint.js` is simple. Use one of the `setSchema(string)` functions to set a schema. After a schema is successfully set any given xml file can be validated with `validate(string)`.
The return value will be a JSON-string. The top element is an array which can contain multiple error Objects. If the returned array is empty no errors where found. Each error Object contains nearly all fields from the original libxml2 [xmlError struct](http://www.xmlsoft.org/html/libxml-xmlerror.html#xmlError):
```
struct xmlError {
  int     domain  : What part of the library raised this error
  int     code    : The error code, e.g. an xmlParserError
  char*   message : human-readable informative error message
  int     level   : how consequent is the error
  char*   file    : the filename
  int     line    : the line number if available
  char*   str1    : extra string information
  char*   str2    : extra string information
  char*   str3    : extra string information
  int     int1    : extra number information
  int     int2    : error column # or 0 if N/A
}
```


## Functions
This is a list of all functions provided by :

* `setSchema(string)` sets a xsd schema given by a string
* `setSchemaFile(string)` sets a xsd schemaFile from a given path (the file has to be laoded into the virtual file system)
* `validate(string)` validates a given string with the latest set xsd schema. Returns an array with error-objects.


* `setRelaxNGSchema(string)` sets an relaxNG schema given by a string
* `setRelaxNGSchemaFile(string)` sets a relaxNG schemaFile from a given path (the file has to be laoded into the virtual file system)
* `validateNG(string)` validates a given string with the latest set relaxNG schema. Returns an array with error-objects.

* `EM_XMLonRuntimeInitialized` can but must not be set as a callback function that is called as soon as this library has finished loading

If you want to know more have a look at our demo section.  A good starting example would be `DemoRelaxNG.js`.

# Autocompletion
For autocompletion use the `schemainfoCreator.js` library.

Only one function call is needed for the Autocompletion: `toSchemaInfo(XMLDocument)`
This function converts a relaxNG-schma-file into an schemaInfo-Objects which can be used by codemirror for autocompletion.
The XMLDocument has to be parsed. For example this can be done with `jQuery.parseXML(txtString)`.
Here is a short example:
```
$(document).ready(function() {
  var txt = "an unparsed RelaxNG schema";
  var xml = jQuery.parseXML(txt);
  var schemaInfo = toSchemaInfo(xml);

  editor = CodeMirror.fromTextArea(document.getElementById(id), {
    mode: "xml",
    hintOptions: {schemaInfo: schemaInfo},
    extraKeys: {
      "'<'": "completeAfter",
      "'/'": "completeIfAfterLt",
      "' '": "completeIfInTag",
      "'='": "completeIfInTag",
      "Ctrl-Space": "autocomplete"
    }
  }
}
```

For more details have a look at the `DemoAutocomplete.js` file.

# Demos
This repo contains multiple demonstrations:

* `DemoAutoComplete.xhtml` how to use the autocompletion feature
* `DemoRelaxNG.xhtml` how to use the linter
* `DemoMultifile.xhtml` how to use a multi-file schema for the linter
* `DemoRelaxNGAsync.xhtml` how to use the linter with a webworker
* `DemoUltimate.xhtml` linter + autocompletion + in an webworker


# Build
This tool was developed with and for [Nix](https://nixos.org/nix/). If you want to compile it yourself it is very easy using Nix. Just clone the repo and run:

`nix-shell -A emEnv` or `nix-shell -A nativeEnv` will build the required dependencies like:

  * `json-c`, 
  * `xml.js` and
  * `libz`

using either a native toolchain or the emscripten toolchain depending on which `-A` argument was given.

## Emscripten toolchain
```
git clone https://gitlab.com/odfplugfest/xmlmirror
cd xmlmirror
nix-shell -A emEnv
make
```

This uses `Makefile.emEnv`. If `make` fails, the emcc cache may be invalid. Try `emcc --clear-cache` and then run `make` again.

Note: you might want to use `nix-shell -A emEnv --pure` to not mix `x86_64` lib versions with emscripten `javascript` based versions.

## Native toolchain

```
git clone https://gitlab.com/odfplugfest/xmlmirror
cd xmlmirror
nix-shell -A nativeEnv
make
```

Note: this uses `Makefile.nativeEnv`

## nixpkgs based toolchain

xmlmirror is now also available via [nixpkgs](https://github.com/NixOS/nixpkgs/pull/16208).

# schemaInfo development

This project contains a javascript/browser based implementation of a **single file RelaxNG schema** to **schemaInfo** converter. If you want to hack on that or test if your browser is fit for executing this code try this:

    nix-shell -A nativeEnv
    make closure
    make schemainfo-test

You can manually open `schemainfoCreator-test.html` in your browser. If you are using chromium you might have to use the alias 's' defined in the `default.nix` or start the python webserver manually with:

    python -m SimpleHTTPServer

And only then load the html document in chrome. This is neccessary as it requires AJAX calls.


# Contact
This library was developed by the [nixcloud](https://nixcloud.io) team

Bugs/issues should be filed here:

* https://gitlab.com/odfplugfest/xmlmirror/issues

If you want to get in contact with one of the leading developers:

* Paul Seitz (paul.m.seitz@gmail.com)
* Joachim Schiele (js@lastlog.de)

# Licence

**Where not explicitly stated otherwise, the license below applies. Exceptions are bundled libraries/tools or code from stackoverflow (for which we linked the posting above the code).**

The MIT License (MIT)

Copyright (c) 2016 Paul Seitz & Joachim Schiele

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
