summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Sommerseth <davids@redhat.com>2013-03-13 19:56:22 +0100
committerDavid Sommerseth <davids@redhat.com>2013-03-13 19:56:22 +0100
commit99253169b347346a96cc08d767f04dea615db79d (patch)
treebbf4ecc2bf54f234f27013e121f61ff48dc909d7
parent27783aa01e41bce0e2b7b6e3db5d4b453f438ffe (diff)
downloadrteval-99253169b347346a96cc08d767f04dea615db79d.tar.gz
rteval-99253169b347346a96cc08d767f04dea615db79d.tar.xz
rteval-99253169b347346a96cc08d767f04dea615db79d.zip
Migrated from libxslt to lxml
To avoid depending on libxslt-python, use the more standard Python lxml module for XSLT processing. Signed-off-by: David Sommerseth <davids@redhat.com>
-rw-r--r--README7
-rw-r--r--doc/installing.txt10
-rwxr-xr-xrteval-cmd27
-rw-r--r--rteval.spec7
-rw-r--r--rteval/sysinfo/dmi.py33
-rw-r--r--rteval/xmlout.py49
6 files changed, 90 insertions, 43 deletions
diff --git a/README b/README
index feabf10..eb034c2 100644
--- a/README
+++ b/README
@@ -25,12 +25,15 @@ python-schedtils
python-ethtools
git://git.kernel.org/pub/scm/linux/kernel/git/acme/python-ethtool.git
-libxslt-python
- http://xmlsoft.org/XSLT/python.html
+python-lxml
+ http://lxml.de/
python-dmidecode
http://www.ohloh.net/p/python-dmidecode
+libxml2-python
+ http://xmlsoft.org/
+
rt-tests
git://git.kernel.org/pub/scm/linux/kernel/git/clrkwllms/rt-tests.git
diff --git a/doc/installing.txt b/doc/installing.txt
index c202902..c592e9c 100644
--- a/doc/installing.txt
+++ b/doc/installing.txt
@@ -9,14 +9,18 @@ python-ethtool
A python library to query network interfaces
git://git.kernel.org/pub/scm/linux/kernel/git/acme/python-ethtool.git
-libxslt-python
- A python library to parse XSLT stylesheets
- http://www.xmlsoft.org/XSLT/python.html
+python-lxml
+ A python library to parse XML files and XSLT stylesheets
+ http://lxml.de/
python-dmidecode
A python library used to access DMI table information
http://www.autonomy.net.au/display/pydmi/Home
+libxml2-python
+ A python library to parse XML files
+ http://xmlsoft.org/
+
rt-tests
A collection of programs used to measure real-time behavior
git://git.kernel.org/pub/scm/linux/kernel/git/clrkwllms/rt-tests.git
diff --git a/rteval-cmd b/rteval-cmd
index 13003a7..4111e03 100755
--- a/rteval-cmd
+++ b/rteval-cmd
@@ -35,7 +35,7 @@
#
import sys, os, time, optparse, tempfile
-import libxml2, libxslt
+import libxml2, lxml.etree
from datetime import datetime
from rteval.Log import Log
from rteval import RtEval, rtevalConfig
@@ -68,25 +68,24 @@ def summarize(repfile, xslt):
isarchive = True
# Load the XSLT template
- xsltdoc = libxml2.parseFile(xslt)
- xsltprs = libxslt.parseStylesheetDoc(xsltdoc)
+ xsltfp = open(xslt, "r")
+ xsltdoc = lxml.etree.parse(xsltfp)
+ xsltprs = lxml.etree.XSLT(xsltdoc)
+ xsltfp.close()
# Load the summay.xml report - with some simple sanity checks
- xmldoc = libxml2.parseFile(summaryfile)
- if xmldoc.name != summaryfile:
- raise RuntimeError("Failed to load the report")
- if xmldoc.children.name != 'rteval':
- raise RuntimeError("The report doesn't seem like a rteval summary report")
+ xmlfp = open(summaryfile, "r")
+ xmldoc = lxml.etree.parse(xmlfp)
+ xmlfp.close()
- # Parse the report through the XSLT template - preserve proper encoding
- resdoc = xsltprs.applyStylesheet(xmldoc, None)
- report = xsltprs.saveResultToString(resdoc).encode(xsltprs.encoding())
+ if xmldoc.docinfo.root_name != 'rteval':
+ raise RuntimeError("The report doesn't seem like a rteval summary report")
- # Dump the report to stdout - as UTF-8
- print report.encode('UTF-8')
+ # Parse and print the report through the XSLT template - preserve proper encoding
+ resdoc = xsltprs(xmldoc)
+ print unicode(resdoc).encode('UTF-8')
# Clean up
- del report
del resdoc
del xmldoc
del xsltprs
diff --git a/rteval.spec b/rteval.spec
index 6a27b9c..da8ab65 100644
--- a/rteval.spec
+++ b/rteval.spec
@@ -3,7 +3,7 @@
Name: rteval
Version: 2.1
-Release: 1%{?dist}
+Release: 2%{?dist}
Summary: Utility to evaluate system suitability for RT Linux
Group: Development/Tools
@@ -14,7 +14,7 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: python
Requires: python
-Requires: python-schedutils python-ethtool libxslt-python >= 1.1.17
+Requires: python-schedutils python-ethtool python-lxml
Requires: python-dmidecode >= 3.10
Requires: rt-tests >= 0.65
Requires: rteval-loads >= 1.2
@@ -89,6 +89,9 @@ rm -rf $RPM_BUILD_ROOT
/usr/bin/rteval
%changelog
+* Tue Mar 12 2013 David Sommerseth <davids@redhat.com> - 2.1-2
+- Migrated from libxslt-python to python-lxml
+
* Fri Jan 18 2013 David Sommerseth <davids@redhat.com> - 2.1-1
- Made some log lines clearer
- cyclictest: Added --cyclictest-breaktrace feature
diff --git a/rteval/sysinfo/dmi.py b/rteval/sysinfo/dmi.py
index b3cea0d..84ca97f 100644
--- a/rteval/sysinfo/dmi.py
+++ b/rteval/sysinfo/dmi.py
@@ -26,8 +26,8 @@
#
import sys, os
-import libxml2, libxslt
-from rteval import rtevalConfig
+import libxml2, lxml.etree
+from rteval import rtevalConfig, xmlout
from rteval.Log import Log
try:
@@ -64,7 +64,7 @@ class DMIinfo(object):
'''class used to obtain DMI info via python-dmidecode'''
def __init__(self, config, logger):
- self.__version = '0.4'
+ self.__version = '0.5'
if not dmidecode_loaded:
logger.log(Log.DEBUG|Log.WARN, "No dmidecode module found, ignoring DMI tables")
@@ -74,17 +74,23 @@ class DMIinfo(object):
self.__fake = False
self.__dmixml = dmidecode.dmidecodeXML()
- xsltdoc = self.__load_xslt('rteval_dmi.xsl')
- self.xsltparser = libxslt.parseStylesheetDoc(xsltdoc)
+ self.__xsltparser = self.__load_xslt('rteval_dmi.xsl')
def __load_xslt(self, fname):
- if os.path.isfile(fname):
- return libxml2.parseFile(fname)
+ xsltfile = None
+ if os.path.exists(fname):
+ xsltfile = open(fname, "r")
elif rtevalConfig.default_config_search([fname], os.path.isfile):
- return libxml2.parseFile(rtevalConfig.default_config_search([fname], os.path.isfile))
- else:
- raise RuntimeError('Could not locate XSLT template for DMI data (%s/%s)' % (fname))
+ xsltfile = open(rtevalConfig.default_config_search([fname], os.path.isfile), "r")
+
+ if xsltfile:
+ xsltdoc = lxml.etree.parse(xsltfile)
+ ret = lxml.etree.XSLT(xsltdoc)
+ xsltfile.close()
+ return ret
+
+ raise RuntimeError, 'Could not locate XSLT template for DMI data (%s)' % (self.sharedir + '/' + fname)
def MakeReport(self):
@@ -95,8 +101,9 @@ class DMIinfo(object):
rep_n.newProp("not_available", "1")
else:
self.__dmixml.SetResultType(dmidecode.DMIXML_DOC)
- resdoc = self.xsltparser.applyStylesheet(self.__dmixml.QuerySection('all'), None)
- dmi_n = resdoc.getRootElement().copyNode(1)
+ dmiqry = xmlout.convert_libxml2_to_lxml_doc(self.__dmixml.QuerySection('all'))
+ resdoc = self.__xsltparser(dmiqry)
+ dmi_n = xmlout.convert_lxml_to_libxml2_nodes(resdoc.getroot())
rep_n.addChild(dmi_n)
return rep_n
@@ -107,7 +114,7 @@ def unit_test(rootdir):
class unittest_ConfigDummy(object):
def __init__(self, rootdir):
- self.config = {'installdir': '%s/rteval'}
+ self.config = {'installdir': '/usr/share/rteval'}
self.__update_vars()
def __update_vars(self):
diff --git a/rteval/xmlout.py b/rteval/xmlout.py
index 454a452..ddc2964 100644
--- a/rteval/xmlout.py
+++ b/rteval/xmlout.py
@@ -26,11 +26,35 @@
import os
import sys
import libxml2
-import libxslt
+import lxml.etree
import codecs
import re
from string import maketrans
+
+def convert_libxml2_to_lxml_doc(inxml):
+ "Converts a libxml2.xmlDoc into a lxml.etree document object"
+
+ if not isinstance(inxml, libxml2.xmlDoc):
+ raise TypeError('Function requires an libxml2.xmlDoc as input')
+
+ root = inxml.getRootElement()
+ ret = lxml.etree.XML(root.serialize('UTF-8'))
+ del root
+ return ret
+
+
+
+def convert_lxml_to_libxml2_nodes(inlxml):
+ "Converts a lxml.etree elements tree into a libxml2.xmlNode object"
+
+ if not isinstance(inlxml,lxml.etree._Element) and not isinstance(inlxml, lxml.etree._XSLTResultTree):
+ raise TypeError('Function requires an lxml.etree object as input')
+
+ return libxml2.parseDoc(lxml.etree.tostring(inlxml)).getRootElement()
+
+
+
class XMLOut(object):
'''Class to create XML output'''
def __init__(self, roottag, version, attr = None, encoding='UTF-8'):
@@ -171,6 +195,7 @@ class XMLOut(object):
self.status = 2 # Confirm that we have loaded a report from file
+
def Write(self, filename, xslt = None):
if self.status != 2 and self.status != 3:
raise RuntimeError, "XMLOut: XML document is not closed"
@@ -181,8 +206,10 @@ class XMLOut(object):
return
else:
# Load XSLT file and prepare the XSLT parser
- xsltdoc = libxml2.parseFile(xslt)
- parser = libxslt.parseStylesheetDoc(xsltdoc)
+ xsltfile = open(xslt, 'r')
+ xsltdoc = lxml.etree.parse(xsltfile)
+ parser = lxml.etree.XSLT(xsltdoc)
+ xsltfile.close()
# imitate libxml2's filename interpretation
if filename != "-":
@@ -192,18 +219,22 @@ class XMLOut(object):
#
# Parse XML+XSLT and write the result to file
#
- resdoc = parser.applyStylesheet(self.xmldoc, None)
- # Decode the result string according to the charset declared in the XSLT file
- xsltres = parser.saveResultToString(resdoc).decode(parser.encoding())
+ xmldoc = convert_libxml2_to_lxml_doc(self.xmldoc)
+ resdoc = parser(xmldoc)
+
# Write the file with the requested output encoding
- dstfile.write(xsltres.encode(self.encoding))
+ dstfile.write(unicode(resdoc).encode(self.encoding))
if dstfile != sys.stdout:
dstfile.close()
# Clean up
- resdoc.freeDoc()
- xsltdoc.freeDoc()
+ del resdoc
+ del xsltdoc
+ del parser
+ del xsltfile
+ del xmldoc
+
def GetXMLdocument(self):
if self.status != 2 and self.status != 3: