# 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
|