diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/xmlValidator/CMakeLists.txt | 1 | ||||
-rw-r--r-- | tools/xmlValidator/README.md | 73 | ||||
-rwxr-xr-x | tools/xmlValidator/xmlValidator.py | 109 |
3 files changed, 183 insertions, 0 deletions
diff --git a/tools/xmlValidator/CMakeLists.txt b/tools/xmlValidator/CMakeLists.txt new file mode 100644 index 0000000..78519f4 --- /dev/null +++ b/tools/xmlValidator/CMakeLists.txt @@ -0,0 +1 @@ +INSTALL(PROGRAMS xmlValidator.py DESTINATION bin) diff --git a/tools/xmlValidator/README.md b/tools/xmlValidator/README.md new file mode 100644 index 0000000..adc7e12 --- /dev/null +++ b/tools/xmlValidator/README.md @@ -0,0 +1,73 @@ +# xmlValidator tool + +This tool can be used to check if the `.xml` files you have written are +following the `.xsd` schemas we provided you. +By doing so, you are *ensured* that your configuration is *fully compatible* with the `parameter-framework`. + +It scans all directories and subdirectories for `.xml` files and checks them +with `.xsd` from a *schemas* directory you specified for the script. + +## Usage +To run xmlValidator, just start it from the commandline with: + + python xmlValidator.py <xmlRootDirectory> <xsdDirectory> + +where: + +* `<xmlRootDirectory>` is a path to a directory containing: + - `.xml` files + - subdirectories containing `.xml` files +* `<xsdDirectory>` is a path to a directory containing: + - `.xsd` files (also called *schemas*) + +## Example of usage + +### File structure + +In the example, we have the following files: + + ├── ParameterFrameworkConfiguration.xml + ├── Schemas + │ ├── ComponentLibrary.xsd + │ ├── ComponentTypeSet.xsd + │ ├── ConfigurableDomains.xsd + │ ├── FileIncluder.xsd + │ ├── ParameterFrameworkConfiguration.xsd + │ ├── ParameterSettings.xsd + │ ├── Parameter.xsd + │ ├── Subsystem.xsd + │ └── SystemClass.xsd + ├── Settings + │ └── FS + │ └── Genres.xml + └── Structure + └── FS + ├── MusicLibraries.xml + └── my_music.xml + +### Command +We are in the directory which contains the structure detailed previously. +To check the validity, we just run: + + ../../tools/xmlValidator/xmlValidator.py . Schemas + +### Results +And we will get the following output on the commandline: + + [*] Validate xml files in /home/lab/MusicLibrary/ with /home/lab/MusicLibrary/Schemas + Attempt to validate ParameterFrameworkConfiguration.xml with ParameterFrameworkConfiguration.xsd + ParameterFrameworkConfiguration.xml is valid + Attempt to validate my_music.xml with Subsystem.xsd + my_music.xml is valid + Attempt to validate MusicLibraries.xml with SystemClass.xsd + MusicLibraries.xml is valid + Attempt to validate Genres.xml with ConfigurableDomains.xsd + Genres.xml is valid + + +## Install requirements +In order to use this tool, you must have the following packages installed: + +* `python` +* `python-lxml` +* `libpython2.7` diff --git a/tools/xmlValidator/xmlValidator.py b/tools/xmlValidator/xmlValidator.py new file mode 100755 index 0000000..ccf4bd0 --- /dev/null +++ b/tools/xmlValidator/xmlValidator.py @@ -0,0 +1,109 @@ +#! /usr/bin/python + +# Copyright (c) 2014, Intel Corporation +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation and/or +# other materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its contributors +# may be used to endorse or promote products derived from this software without +# specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +from lxml import etree +from os import path +from os import walk +from sys import argv + +class PrintColor(): + @staticmethod + def success(stringToPrint): + green=32 + PrintColor._printColor(green, stringToPrint) + + @staticmethod + def error(stringToPrint): + red=31 + PrintColor._printColor(red, stringToPrint) + + @staticmethod + def _printColor(color, stringToPrint): + """prints strings in color via ascii escape sequence""" + print("\033[%sm%s\033[0m" % (str(color), stringToPrint)) + +def getSchemaFilenameFromXmlFile(xmlFilePath): + """getSchemaFileNameFromXmlFile + + The pfw considers that the .xsd file has the same name as the + root element name of the .xml. + With of this knowledge, we may easily find the + schema file we need. + + Args: + xmlFilePath: the xml file. + + Returns: + str: the corresponding .schema name + """ + xmlTree = etree.parse(xmlFilePath) + rootElement = xmlTree.getroot() + return rootElement.tag + '.xsd' + +def validateXmlWithSchema(xmlFilePath, schemaFilePath): + """validateXmlWithSchema + + Validates an .xml file based on his corresponding schema. + + Args: + xmlFilePath (str): the absolute path to the xml file. + schemaFilePath (str): the absolute path to the schema. + """ + baseXmlName = path.basename(xmlFilePath) + baseSchemaName = path.basename(schemaFilePath) + print 'Attempt to validate', baseXmlName, 'with', baseSchemaName + + schemaContent = etree.parse(schemaFilePath) + schema = etree.XMLSchema(schemaContent) + xmlContent = etree.parse(xmlFilePath) + xmlContent.xinclude() + + if schema.validate(xmlContent): + PrintColor.success('%s is valid' % str(baseXmlName)) + else: + PrintColor.error('Error: %s' % str(schema.error_log)) + +# handle main arguments +if len(argv) != 3: + PrintColor.error('Error: usage %s xmlDirectory schemaDirectory' % str(argv[0])) + exit(1) + +xmlDirectory = argv[1] +schemaDirectory = argv[2] + +print('[*] Validate xml files in %s with %s' % (xmlDirectory, schemaDirectory)) + +for rootPath, _, files in walk(xmlDirectory): + for filename in files: + if filename.endswith('.xml'): + xmlFilePath = path.join(rootPath, filename) + schemaFileName = getSchemaFilenameFromXmlFile(xmlFilePath) + schemaFilePath = path.join(schemaDirectory, schemaFileName) + validateXmlWithSchema(xmlFilePath, schemaFilePath) |