title: Using Python and lxml to validate XML against an external DTD
body: <p>I'm trying to validate an XML file against an external DTD referenced in the doctype tag. Specifically:</p>
  
  <pre class="lang-xml prettyprint-override"><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;!DOCTYPE en-export SYSTEM "http://xml.evernote.com/pub/evernote-export3.dtd"&gt;
  ...the rest of the document...
  </code></pre>
  
  <p>I'm using Python 3.3 and the lxml module. From reading <a href="http://lxml.de/validation.html#validation-at-parse-time" rel="nofollow">http://lxml.de/validation.html#validation-at-parse-time</a>, I've thrown this together:</p>
  
  <pre class="lang-python prettyprint-override"><code>enexFile = open(sys.argv[2], mode="rb") # sys.argv[2] is the path to an XML file in local storage.
  enexParser = etree.XMLParser(dtd_validation=True)
  enexTree = etree.parse(enexFile, enexParser)
  </code></pre>
  
  <p>From what I understand of validation.html, the lxml library should now take care of retrieving the DTD and performing validation. But instead, I get this:</p>
  
  <pre class="lang-none prettyprint-override"><code>$ ./mapwrangler.py validate notes.enex
  Traceback (most recent call last):
    File "./mapwrangler.py", line 27, in &lt;module&gt;
      enexTree = etree.parse(enexFile, enexParser)
    File "lxml.etree.pyx", line 3239, in lxml.etree.parse (src/lxml/lxml.etree.c:69955)
    File "parser.pxi", line 1769, in lxml.etree._parseDocument (src/lxml/lxml.etree.c:102257)
    File "parser.pxi", line 1789, in lxml.etree._parseFilelikeDocument (src/lxml/lxml.etree.c:102516)
    File "parser.pxi", line 1684, in lxml.etree._parseDocFromFilelike (src/lxml/lxml.etree.c:101442)
    File "parser.pxi", line 1134, in lxml.etree._BaseParser._parseDocFromFilelike (src/lxml/lxml.etree.c:97069)
    File "parser.pxi", line 582, in lxml.etree._ParserContext._handleParseResultDoc (src/lxml/lxml.etree.c:91275)
    File "parser.pxi", line 683, in lxml.etree._handleParseResult (src/lxml/lxml.etree.c:92461)
    File "parser.pxi", line 622, in lxml.etree._raiseParseError (src/lxml/lxml.etree.c:91757)
  lxml.etree.XMLSyntaxError: Validation failed: no DTD found !, line 3, column 43
  </code></pre>
  
  <p>This surprises me, because if I turn off validation, then the document parses in just fine and I can do <code>print(enexTree.docinfo.doctype)</code> to get</p>
  
  <pre class="lang-none prettyprint-override"><code>$ ./mapwrangler.py validate notes.enex
  &lt;!DOCTYPE en-export SYSTEM "http://xml.evernote.com/pub/evernote-export3.dtd"&gt;
  </code></pre>
  
  <p>So it looks to me like there shouldn't be any problem finding the DTD.</p>
  
  <p>Thanks for your help.</p>