[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen-unstable] Replace pyxml/xmlproc-based XML validator with lxml based one



# HG changeset patch
# User Stephan Peijnik <spe@xxxxxxxxx>
# Date 1286816093 -3600
# Node ID b8cc53d22545706b28c7a26dffd24f192a76541a
# Parent  fbce8e403470db8c9e580a5efd9d717cd2260c1f
Replace pyxml/xmlproc-based XML validator with lxml based one

Pyxml/xmlproc is being used in tools/xen/xm/xenapi_create.py but is
unmaintained for several years now. xmlproc is used only for validating
XML documents against a DTD file.

This patch replaces the pyxml/xmlproc based XML validation with code
based on lxml, which is actively maintained.

Signed-off-by: Stephan Peijnik <spe@xxxxxxxxx>
Signed-off-by: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
committer: Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
---
 README                               |   12 ++--
 tools/python/xen/xm/xenapi_create.py |   95 +++++++++++++++++------------------
 2 files changed, 55 insertions(+), 52 deletions(-)

diff -r fbce8e403470 -r b8cc53d22545 README
--- a/README    Mon Oct 11 10:22:24 2010 +0100
+++ b/README    Mon Oct 11 17:54:53 2010 +0100
@@ -107,12 +107,15 @@ Xend (the Xen daemon) has the following 
 Xend (the Xen daemon) has the following runtime dependencies:
 
     * Python 2.3 or later.
-      In many distros, the XML-aspects to the standard library
+      In some distros, the XML-aspects to the standard library
       (xml.dom.minidom etc) are broken out into a separate python-xml package.
       This is also required.
+      In more recent versions of Debian and Ubuntu the XML-aspects are included
+      in the base python package however (python-xml has been removed
+      from Debian in squeeze and from Ubuntu in intrepid).
 
           URL:    http://www.python.org/
-          Debian: python, python-xml
+          Debian: python
 
     * For optional SSL support, pyOpenSSL:
           URL:    http://pyopenssl.sourceforge.net/
@@ -123,8 +126,9 @@ Xend (the Xen daemon) has the following 
           Debian: python-pam
 
     * For optional XenAPI support in XM, PyXML:
-          URL:    http://pyxml.sourceforge.net
-          YUM:    PyXML
+          URL:    http://codespeak.net/lxml/
+         Debian: python-lxml
+          YUM:    python-lxml
 
 
 Intel(R) Trusted Execution Technology Support
diff -r fbce8e403470 -r b8cc53d22545 tools/python/xen/xm/xenapi_create.py
--- a/tools/python/xen/xm/xenapi_create.py      Mon Oct 11 10:22:24 2010 +0100
+++ b/tools/python/xen/xm/xenapi_create.py      Mon Oct 11 17:54:53 2010 +0100
@@ -14,13 +14,15 @@
 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 #============================================================================
 # Copyright (C) 2007 Tom Wilkie <tom.wilkie@xxxxxxxxx>
+# Copyright (C) 2010 ANEXIA Internetdienstleistungs GmbH
+#   Author: Stephan Peijnik <spe@xxxxxxxxx>
 #============================================================================
 """Domain creation using new XenAPI
 """
 
 from xen.xm.main import server, get_default_SR
 from xml.dom.minidom import parse, getDOMImplementation
-from xml.parsers.xmlproc import xmlproc, xmlval, xmldtd
+from lxml import etree
 from xen.xend import sxp
 from xen.xend.XendAPIConstants import XEN_API_ON_NORMAL_EXIT, \
      XEN_API_ON_CRASH_BEHAVIOUR
@@ -35,6 +37,7 @@ from os.path import join
 from os.path import join
 import traceback
 import re
+import warnings # Used by lxml-based validator
 
 def log(_, msg):
     #print "> " + msg
@@ -118,61 +121,57 @@ class xenapi_create:
         Use this if possible as it gives nice
         error messages
         """
-        dtd = xmldtd.load_dtd(self.dtd)
-        parser = xmlproc.XMLProcessor()
-        parser.set_application(xmlval.ValidatingApp(dtd, parser))
-        parser.dtd = dtd
-        parser.ent = dtd
-        parser.parse_resource(file)
-
+        try:
+            dtd = etree.DTD(open(self.dtd, 'r'))
+        except IOError:
+            # The old code did neither raise an exception here, nor
+            # did it report an error. For now we issue a warning.
+            # TODO: How to handle a missing dtd file?
+            # --sp
+            warnings.warn('DTD file %s not found.' % (self.dtd),
+                          UserWarning)
+            return
+        
+        tree = etree.parse(file)
+        root = tree.getroot()
+        if not dtd.validate(root):
+            self.handle_dtd_errors(dtd)
+            
     def check_dom_against_dtd(self, dom):
         """
         Check DOM again DTD.
         Doesn't give as nice error messages.
         (no location info)
         """
-        dtd = xmldtd.load_dtd(self.dtd)
-        app = xmlval.ValidatingApp(dtd, self)
-        app.set_locator(self)
-        self.dom2sax(dom, app)
-
-    # Get errors back from ValidatingApp       
-    def report_error(self, number, args=None):
-        self.errors = xmlproc.errors.english
         try:
-            msg = self.errors[number]
-            if args != None:
-                msg = msg % args
-        except KeyError:
-            msg = self.errors[4002] % number # Unknown err msg :-)
-        print msg 
+            dtd = etree.DTD(open(self.dtd, 'r'))
+        except IOError:
+            # The old code did neither raise an exception here, nor
+            # did it report an error. For now we issue a warning.
+            # TODO: How to handle a missing dtd file?
+            # --sp
+            warnings.warn('DTD file %s not found.' % (self.dtd),
+                          UserWarning)
+            return
+
+        # XXX: This may be a bit slow. Maybe we should use another way
+        # of getting an etree root element from the minidom DOM tree...
+        # -- sp
+        root = etree.XML(dom.toxml())
+        if not dtd.validate(root):
+            self.handle_dtd_errors(dtd)
+
+    # Do the same that was done in report_error before. This is directly
+    # called by check_dtd and check_dom_against_dtd.
+    # We are using sys.stderr instead of print though (python3k clean).
+    def handle_dtd_errors(self, dtd):
+        # XXX: Do we really want to bail out here?
+        # -- sp
+        for err in dtd.error_log:
+            err_str = 'ERROR: %s\n' % (str(err),)
+            sys.stderr.write(err_str)
+        sys.stderr.flush()
         sys.exit(-1)
-
-    # Here for compatibility with ValidatingApp
-    def get_line(self):
-        return -1
-
-    def get_column(self):
-        return -1
-
-    def dom2sax(self, dom, app):
-        """
-        Take a dom tree and tarverse it,
-        issuing SAX calls to app.
-        """
-        for child in dom.childNodes:
-            if child.nodeType == child.TEXT_NODE:
-                data = child.nodeValue
-                app.handle_data(data, 0, len(data))
-            else:
-                app.handle_start_tag(
-                    child.nodeName,
-                    self.attrs_to_dict(child.attributes))
-                self.dom2sax(child, app)
-                app.handle_end_tag(child.nodeName)
-
-    def attrs_to_dict(self, attrs):
-        return dict(attrs.items())     
 
     #
     # Checks which cannot be done with dtd

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.