Add check-xml hook.
diff --git a/.travis.yml b/.travis.yml
index 39d83d3..720eec7 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -5,6 +5,7 @@
     - TOXENV=py33
     - TOXENV=py34
     - TOXENV=pypy
+    - TOXENV=pypy3
 install: pip install coveralls tox --use-mirrors
 script: tox
 # Special snowflake.  Our tests depend on making real commits.
diff --git a/README.md b/README.md
index 82e48fd..7b9604b 100644
--- a/README.md
+++ b/README.md
@@ -27,6 +27,7 @@
 - `check-case-conflict` - Check for files that would conflict in case-insensitive filesystems.
 - `check-docstring-first` - Checks a common error of defining a docstring after code.
 - `check-json` - Attempts to load all json files to verify syntax.
+- `check-xml` - Attempts to load all xml files to verify syntax.
 - `check-yaml` - Attempts to load all yaml files to verify syntax.
 - `debug-statements` - Check for pdb / ipdb / pudb statements in code.
 - `end-of-file-fixer` - Makes sure files end in a newline and only a newline.
diff --git a/hooks.yaml b/hooks.yaml
index 4e31f98..d575170 100644
--- a/hooks.yaml
+++ b/hooks.yaml
@@ -31,6 +31,12 @@
     entry: check-json
     language: python
     files: \.json$
+-   id: check-xml
+    name: Check Xml
+    description: This hook checks xml files for parseable syntax.
+    entry: check-xml
+    language: python
+    files: \.xml$
 -   id: check-yaml
     name: Check Yaml
     description: This hook checks yaml files for parseable syntax.
diff --git a/pre_commit_hooks/check_xml.py b/pre_commit_hooks/check_xml.py
new file mode 100644
index 0000000..926f6e9
--- /dev/null
+++ b/pre_commit_hooks/check_xml.py
@@ -0,0 +1,28 @@
+from __future__ import absolute_import
+from __future__ import print_function
+from __future__ import unicode_literals
+
+import argparse
+import io
+import sys
+import xml.sax
+
+
+def check_xml(argv=None):
+    parser = argparse.ArgumentParser()
+    parser.add_argument('filenames', nargs='*', help='XML filenames to check.')
+    args = parser.parse_args(argv)
+
+    retval = 0
+    for filename in args.filenames:
+        try:
+            with io.open(filename, 'rb') as xml_file:
+                xml.sax.parse(xml_file, xml.sax.ContentHandler())
+        except xml.sax.SAXException as exc:
+            print('{0}: Failed to xml parse ({1})'.format(filename, exc))
+            retval = 1
+    return retval
+
+
+if __name__ == '__main__':
+    sys.exit(check_xml())
diff --git a/requirements-dev.txt b/requirements-dev.txt
index b3a7721..97343d5 100644
--- a/requirements-dev.txt
+++ b/requirements-dev.txt
@@ -1,5 +1,6 @@
 -e .
 
+astroid<1.3.3
 coverage
 flake8
 mock
diff --git a/setup.py b/setup.py
index 3addc42..4ed93f8 100644
--- a/setup.py
+++ b/setup.py
@@ -41,6 +41,7 @@
             'check-case-conflict = pre_commit_hooks.check_case_conflict:main',
             'check-docstring-first = pre_commit_hooks.check_docstring_first:main',
             'check-json = pre_commit_hooks.check_json:check_json',
+            'check-xml = pre_commit_hooks.check_xml:check_xml',
             'check-yaml = pre_commit_hooks.check_yaml:check_yaml',
             'debug-statement-hook = pre_commit_hooks.debug_statement_hook:debug_statement_hook',
             'end-of-file-fixer = pre_commit_hooks.end_of_file_fixer:end_of_file_fixer',
diff --git a/testing/resources/bad_xml.notxml b/testing/resources/bad_xml.notxml
new file mode 100644
index 0000000..e6edcc7
--- /dev/null
+++ b/testing/resources/bad_xml.notxml
@@ -0,0 +1 @@
+<im><not><terminated><lol>
diff --git a/testing/resources/ok_xml.xml b/testing/resources/ok_xml.xml
new file mode 100644
index 0000000..134f37c
--- /dev/null
+++ b/testing/resources/ok_xml.xml
@@ -0,0 +1,4 @@
+<document>
+    <hello>Hi</hello>
+    <world>Earth</world>
+</document>
diff --git a/tests/check_xml_test.py b/tests/check_xml_test.py
new file mode 100644
index 0000000..99b0902
--- /dev/null
+++ b/tests/check_xml_test.py
@@ -0,0 +1,13 @@
+import pytest
+
+from pre_commit_hooks.check_xml import check_xml
+from testing.util import get_resource_path
+
+
+@pytest.mark.parametrize(('filename', 'expected_retval'), (
+    ('bad_xml.notxml', 1),
+    ('ok_xml.xml', 0),
+))
+def test_check_xml(filename, expected_retval):
+    ret = check_xml([get_resource_path(filename)])
+    assert ret == expected_retval
diff --git a/tox.ini b/tox.ini
index 4b043ba..b37a773 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,7 +1,7 @@
 [tox]
 project = pre_commit_hooks
 # These should match the travis env list
-envlist = py26,py27,py33,py34,pypy
+envlist = py26,py27,py33,py34,pypy,pypy3
 
 [testenv]
 install_command = pip install --use-wheel {opts} {packages}