~~ Licensed to the Apache Software Foundation (ASF) under one or more
~~ contributor license agreements.  See the NOTICE file distributed with
~~ this work for additional information regarding copyright ownership.
~~ The ASF licenses this file to You under the Apache License, Version 2.0
~~ (the "License"); you may not use this file except in compliance with
~~ the License.  You may obtain a copy of the License at
~~
~~     http://www.apache.org/licenses/LICENSE-2.0
~~
~~ Unless required by applicable law or agreed to in writing, software
~~ distributed under the License is distributed on an "AS IS" BASIS,
~~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
~~ See the License for the specific language governing permissions and
~~ limitations under the License.

Get Started as a VXQuery Developer

  The following steps outline how to get up to speed with VXQuery developer community.
  These steps will connect you with the community and give you a place to start with developing for VXQuery.

  * Go through the community member steps.

    * {{{http://vxquery.apache.org/user_get_started.html}Community steps}}.

  * Setup your eclipse development environment.

    * {{{http://vxquery.apache.org/development_eclipse_setup.html}Setup instructions}}.

  * XQuery has a test suite to verify XQuery specifications.

    * Run the test suite for XQTS.

      * {{{http://vxquery.apache.org/user_running_tests.html}Testing instructions}}.

    * Review the test structure.

      * Code is found in the "VXQuery XTest" module.

  * Review open issues for the project.

    * {{{http://vxquery.apache.org/issue-tracking.html}Issues list}}.
