* support for multiple xml implementations
* inform other modules that autoxml has been factored out
This commit is contained in:
+2
-1
@@ -41,7 +41,8 @@ _ = __trans.ugettext
|
||||
# PiSi
|
||||
import pisi
|
||||
# TODO: find the appropriate xmlext implementation and import from there
|
||||
from pisi.xmlextmdom import *
|
||||
from pisi.xmlext import *
|
||||
from pisi.xmlfile import XmlFile
|
||||
import pisi.context as ctx
|
||||
import pisi.util as util
|
||||
import pisi.oo as oo
|
||||
|
||||
+7
-7
@@ -21,18 +21,18 @@ _ = __trans.ugettext
|
||||
import pisi.context as ctx
|
||||
import pisi.packagedb as packagedb
|
||||
from pisi.version import Version
|
||||
import pisi.xmlfile as xmlfile
|
||||
import pisi.autoxml as autoxml
|
||||
from pisi.util import Checks
|
||||
|
||||
class Dependency:
|
||||
|
||||
__metaclass__ = xmlfile.autoxml
|
||||
__metaclass__ = autoxml.autoxml
|
||||
|
||||
s_Package = [xmlfile.String, xmlfile.mandatory]
|
||||
a_versionFrom = [xmlfile.String, xmlfile.optional]
|
||||
a_versionTo = [xmlfile.String, xmlfile.optional]
|
||||
a_releaseFrom = [xmlfile.String, xmlfile.optional]
|
||||
a_releaseTo = [xmlfile.String, xmlfile.optional]
|
||||
s_Package = [autoxml.String, autoxml.mandatory]
|
||||
a_versionFrom = [autoxml.String, autoxml.optional]
|
||||
a_versionTo = [autoxml.String, autoxml.optional]
|
||||
a_releaseFrom = [autoxml.String, autoxml.optional]
|
||||
a_releaseTo = [autoxml.String, autoxml.optional]
|
||||
|
||||
def __str__(self):
|
||||
s = self.package
|
||||
|
||||
+9
-9
@@ -15,32 +15,32 @@
|
||||
|
||||
# Authors: Eray Ozkural <eray@uludag.org.tr>
|
||||
|
||||
import pisi.xmlfile as xmlfile
|
||||
import pisi.autoxml as autoxml
|
||||
from pisi.util import Checks
|
||||
import pisi.lockeddbshelve as shelve
|
||||
|
||||
class File:
|
||||
"""File holds the information for a File node/tag in files.xml"""
|
||||
|
||||
__metaclass__ = xmlfile.autoxml
|
||||
__metaclass__ = autoxml.autoxml
|
||||
|
||||
t_Path = [ xmlfile.String, xmlfile.mandatory ]
|
||||
t_Type = [ xmlfile.String, xmlfile.mandatory ]
|
||||
t_Size = [ xmlfile.Long, xmlfile.optional ]
|
||||
t_Hash = [ xmlfile.String, xmlfile.optional, "SHA1Sum" ]
|
||||
t_Path = [ autoxml.String, autoxml.mandatory ]
|
||||
t_Type = [ autoxml.String, autoxml.mandatory ]
|
||||
t_Size = [ autoxml.Long, autoxml.optional ]
|
||||
t_Hash = [ autoxml.String, autoxml.optional, "SHA1Sum" ]
|
||||
|
||||
def __str__(self):
|
||||
s = "%s, type: %s, size: %s, sha1sum: %s" % (self.path, self.type,
|
||||
self.size, self.hash)
|
||||
return s
|
||||
|
||||
class Files(xmlfile.XmlFile):
|
||||
class Files(autoxml.XmlFile):
|
||||
|
||||
__metaclass__ = xmlfile.autoxml
|
||||
__metaclass__ = autoxml.autoxml
|
||||
|
||||
tag = "Files"
|
||||
|
||||
t_List = [ [File], xmlfile.optional, "File"]
|
||||
t_List = [ [File], autoxml.optional, "File"]
|
||||
|
||||
def append(self, fileinfo):
|
||||
self.list.append(fileinfo)
|
||||
|
||||
+4
-4
@@ -29,19 +29,19 @@ import pisi.packagedb as packagedb
|
||||
import pisi.util as util
|
||||
from pisi.package import Package
|
||||
from pisi.xmlfile import XmlFile
|
||||
import pisi.xmlfile as xmlfile
|
||||
import pisi.autoxml as autoxml
|
||||
from pisi.uri import URI
|
||||
|
||||
class Error(pisi.Error):
|
||||
pass
|
||||
|
||||
class Index(XmlFile):
|
||||
__metaclass__ = xmlfile.autoxml
|
||||
__metaclass__ = autoxml.autoxml
|
||||
|
||||
tag = "PISI"
|
||||
|
||||
t_Sources = [ [specfile.Source], xmlfile.optional, "Source"]
|
||||
t_Packages = [ [metadata.Package], xmlfile.optional, "Package"]
|
||||
t_Sources = [ [specfile.Source], autoxml.optional, "Source"]
|
||||
t_Packages = [ [metadata.Package], autoxml.optional, "Package"]
|
||||
|
||||
def read_uri(self, filename, repo = None):
|
||||
"""Read PSPEC file"""
|
||||
|
||||
+17
-16
@@ -26,24 +26,25 @@ _ = __trans.ugettext
|
||||
import pisi.context as ctx
|
||||
import pisi.specfile as specfile
|
||||
import pisi.xmlfile as xmlfile
|
||||
import pisi.autoxml as autoxml
|
||||
import pisi.util as util
|
||||
|
||||
class Source:
|
||||
__metaclass__ = xmlfile.autoxml
|
||||
__metaclass__ = autoxml.autoxml
|
||||
|
||||
t_Name = [xmlfile.String, xmlfile.mandatory]
|
||||
t_Homepage = [xmlfile.String, xmlfile.optional]
|
||||
t_Packager = [specfile.Packager, xmlfile.mandatory]
|
||||
t_Name = [autoxml.String, autoxml.mandatory]
|
||||
t_Homepage = [autoxml.String, autoxml.optional]
|
||||
t_Packager = [specfile.Packager, autoxml.mandatory]
|
||||
|
||||
class Package(specfile.Package):
|
||||
__metaclass__ = xmlfile.autoxml
|
||||
__metaclass__ = autoxml.autoxml
|
||||
|
||||
t_Build = [ xmlfile.Integer, xmlfile.optional]
|
||||
t_Distribution = [ xmlfile.String, xmlfile.mandatory]
|
||||
t_DistributionRelease = [ xmlfile.String, xmlfile.mandatory]
|
||||
t_Architecture = [ xmlfile.String, xmlfile.mandatory]
|
||||
t_InstalledSize = [ xmlfile.Long, xmlfile.mandatory]
|
||||
t_PackageURI = [ xmlfile.String, xmlfile.optional]
|
||||
t_Build = [ autoxml.Integer, autoxml.optional]
|
||||
t_Distribution = [ autoxml.String, autoxml.mandatory]
|
||||
t_DistributionRelease = [ autoxml.String, autoxml.mandatory]
|
||||
t_Architecture = [ autoxml.String, autoxml.mandatory]
|
||||
t_InstalledSize = [ autoxml.Long, autoxml.mandatory]
|
||||
t_PackageURI = [ autoxml.String, autoxml.optional]
|
||||
|
||||
def decode_hook(self, node, errs, where):
|
||||
self.version = self.history[0].version
|
||||
@@ -57,17 +58,17 @@ class Package(specfile.Package):
|
||||
(self.architecture, self.installedSize)
|
||||
return s
|
||||
|
||||
class MetaData(xmlfile.XmlFile):
|
||||
class MetaData(autoxml.XmlFile):
|
||||
"""Package metadata. Metadata is composed of Specfile and various
|
||||
other information. A metadata has two parts, Source and Package."""
|
||||
|
||||
__metaclass__ = xmlfile.autoxml
|
||||
__metaclass__ = autoxml.autoxml
|
||||
|
||||
tag = "PISI"
|
||||
|
||||
t_Source = [ Source, xmlfile.mandatory]
|
||||
t_Package = [ Package, xmlfile.mandatory]
|
||||
#t_History = [ [Update], xmlfile.mandatory]
|
||||
t_Source = [ Source, autoxml.mandatory]
|
||||
t_Package = [ Package, autoxml.mandatory]
|
||||
#t_History = [ [Update], autoxml.mandatory]
|
||||
|
||||
def from_spec(self, src, pkg):
|
||||
self.source.name = src.name
|
||||
|
||||
+55
-55
@@ -26,8 +26,8 @@ _ = __trans.ugettext
|
||||
from os.path import basename
|
||||
|
||||
# pisi modules
|
||||
import pisi.xmlfile as xmlfile
|
||||
from pisi.xmlfile import XmlFile
|
||||
import pisi.autoxml as autoxml
|
||||
import pisi.context as ctx
|
||||
from pisi.dependency import Dependency
|
||||
import pisi.dependency
|
||||
@@ -37,12 +37,12 @@ import pisi.util as util
|
||||
class Error(pisi.Error):
|
||||
pass
|
||||
|
||||
__metaclass__ = xmlfile.autoxml
|
||||
__metaclass__ = autoxml.autoxml
|
||||
|
||||
class Packager:
|
||||
|
||||
t_Name = [xmlfile.Text, xmlfile.mandatory]
|
||||
t_Email = [xmlfile.String, xmlfile.mandatory]
|
||||
t_Name = [autoxml.Text, autoxml.mandatory]
|
||||
t_Email = [autoxml.String, autoxml.mandatory]
|
||||
|
||||
def __str__(self):
|
||||
s = "%s <%s>" % (self.name, self.email)
|
||||
@@ -51,9 +51,9 @@ class Packager:
|
||||
|
||||
class AdditionalFile:
|
||||
|
||||
s_Filename = [xmlfile.String, xmlfile.mandatory]
|
||||
a_target = [xmlfile.String, xmlfile.mandatory]
|
||||
a_permission = [xmlfile.String, xmlfile.optional]
|
||||
s_Filename = [autoxml.String, autoxml.mandatory]
|
||||
a_target = [autoxml.String, autoxml.mandatory]
|
||||
a_permission = [autoxml.String, autoxml.optional]
|
||||
|
||||
def __str__(self):
|
||||
s = "%s -> %s " % (self.filename, self.target)
|
||||
@@ -64,10 +64,10 @@ class AdditionalFile:
|
||||
|
||||
class Patch:
|
||||
|
||||
s_Filename = [xmlfile.String, xmlfile.mandatory]
|
||||
a_compressionType = [xmlfile.String, xmlfile.optional]
|
||||
a_level = [xmlfile.Integer, xmlfile.optional]
|
||||
a_target = [xmlfile.String, xmlfile.optional]
|
||||
s_Filename = [autoxml.String, autoxml.mandatory]
|
||||
a_compressionType = [autoxml.String, autoxml.optional]
|
||||
a_level = [autoxml.Integer, autoxml.optional]
|
||||
a_target = [autoxml.String, autoxml.optional]
|
||||
|
||||
#FIXME: what's the cleanest way to give a default value for reading level?
|
||||
#def decode_hook(self, node, errs, where):
|
||||
@@ -87,10 +87,10 @@ class Patch:
|
||||
|
||||
class Update:
|
||||
|
||||
a_release = [xmlfile.String, xmlfile.mandatory]
|
||||
t_Date = [xmlfile.String, xmlfile.mandatory]
|
||||
t_Version = [xmlfile.String, xmlfile.mandatory]
|
||||
t_Type = [xmlfile.String, xmlfile.optional]
|
||||
a_release = [autoxml.String, autoxml.mandatory]
|
||||
t_Date = [autoxml.String, autoxml.mandatory]
|
||||
t_Version = [autoxml.String, autoxml.mandatory]
|
||||
t_Type = [autoxml.String, autoxml.optional]
|
||||
|
||||
def __str__(self):
|
||||
s = self.date
|
||||
@@ -103,8 +103,8 @@ class Update:
|
||||
|
||||
class Path:
|
||||
|
||||
s_Path = [xmlfile.String, xmlfile.mandatory]
|
||||
a_fileType = [xmlfile.String, xmlfile.optional]
|
||||
s_Path = [autoxml.String, autoxml.mandatory]
|
||||
a_fileType = [autoxml.String, autoxml.optional]
|
||||
|
||||
def __str__(self):
|
||||
s = self.path
|
||||
@@ -114,8 +114,8 @@ class Path:
|
||||
|
||||
class ComarProvide:
|
||||
|
||||
s_om = [xmlfile.String, xmlfile.mandatory]
|
||||
a_script = [xmlfile.String, xmlfile.mandatory]
|
||||
s_om = [autoxml.String, autoxml.mandatory]
|
||||
a_script = [autoxml.String, autoxml.mandatory]
|
||||
|
||||
def __str__(self):
|
||||
# FIXME: descriptive enough?
|
||||
@@ -126,9 +126,9 @@ class ComarProvide:
|
||||
|
||||
class Archive:
|
||||
|
||||
s_uri = [ xmlfile.String, xmlfile.mandatory ]
|
||||
a_type =[ xmlfile.String, xmlfile.mandatory ]
|
||||
a_sha1sum =[ xmlfile.String, xmlfile.mandatory ]
|
||||
s_uri = [ autoxml.String, autoxml.mandatory ]
|
||||
a_type =[ autoxml.String, autoxml.mandatory ]
|
||||
a_sha1sum =[ autoxml.String, autoxml.mandatory ]
|
||||
|
||||
def decode_hook(self, node, errs, where):
|
||||
self.name = basename(self.uri)
|
||||
@@ -140,38 +140,38 @@ class Archive:
|
||||
|
||||
class Source:
|
||||
|
||||
t_Name = [xmlfile.String, xmlfile.mandatory]
|
||||
t_Homepage = [xmlfile.String, xmlfile.optional]
|
||||
t_Packager = [Packager, xmlfile.mandatory]
|
||||
t_Summary = [xmlfile.LocalText, xmlfile.mandatory]
|
||||
t_Description = [xmlfile.LocalText, xmlfile.mandatory]
|
||||
t_IsA = [ [xmlfile.String], xmlfile.mandatory]
|
||||
t_PartOf = [xmlfile.String, xmlfile.mandatory]
|
||||
t_Icon = [ xmlfile.String, xmlfile.optional]
|
||||
t_License = [ [xmlfile.String], xmlfile.mandatory]
|
||||
t_Archive = [Archive, xmlfile.mandatory ]
|
||||
t_Patches = [ [Patch], xmlfile.optional]
|
||||
t_BuildDependencies = [ [Dependency], xmlfile.optional]
|
||||
t_Version = [ xmlfile.String, xmlfile.optional]
|
||||
t_Release = [ xmlfile.String, xmlfile.optional]
|
||||
t_Name = [autoxml.String, autoxml.mandatory]
|
||||
t_Homepage = [autoxml.String, autoxml.optional]
|
||||
t_Packager = [Packager, autoxml.mandatory]
|
||||
t_Summary = [autoxml.LocalText, autoxml.mandatory]
|
||||
t_Description = [autoxml.LocalText, autoxml.mandatory]
|
||||
t_IsA = [ [autoxml.String], autoxml.mandatory]
|
||||
t_PartOf = [autoxml.String, autoxml.mandatory]
|
||||
t_Icon = [ autoxml.String, autoxml.optional]
|
||||
t_License = [ [autoxml.String], autoxml.mandatory]
|
||||
t_Archive = [Archive, autoxml.mandatory ]
|
||||
t_Patches = [ [Patch], autoxml.optional]
|
||||
t_BuildDependencies = [ [Dependency], autoxml.optional]
|
||||
t_Version = [ autoxml.String, autoxml.optional]
|
||||
t_Release = [ autoxml.String, autoxml.optional]
|
||||
|
||||
|
||||
class Package:
|
||||
|
||||
t_Name = [ xmlfile.String, xmlfile.mandatory ]
|
||||
t_Summary = [ xmlfile.LocalText, xmlfile.optional ]
|
||||
t_Description = [ xmlfile.LocalText, xmlfile.optional ]
|
||||
t_IsA = [ [xmlfile.String], xmlfile.optional]
|
||||
t_PartOf = [xmlfile.String, xmlfile.optional]
|
||||
t_License = [ [xmlfile.String], xmlfile.optional]
|
||||
t_Icon = [ xmlfile.String, xmlfile.optional]
|
||||
t_RuntimeDependencies = [ [Dependency], xmlfile.optional]
|
||||
t_Files = [ [Path], xmlfile.optional]
|
||||
t_Conflicts = [ [xmlfile.String], xmlfile.optional, "Conflicts/Package"]
|
||||
t_ProvidesComar = [ [ComarProvide], xmlfile.optional, "Provides/COMAR"]
|
||||
#t_RequiresComar = [ [xmlfile.String], xmlfile.mandatory, "Requires/COMAR"]
|
||||
t_AdditionalFiles = [ [AdditionalFile], xmlfile.optional]
|
||||
t_History = [ [Update], xmlfile.optional]
|
||||
t_Name = [ autoxml.String, autoxml.mandatory ]
|
||||
t_Summary = [ autoxml.LocalText, autoxml.optional ]
|
||||
t_Description = [ autoxml.LocalText, autoxml.optional ]
|
||||
t_IsA = [ [autoxml.String], autoxml.optional]
|
||||
t_PartOf = [autoxml.String, autoxml.optional]
|
||||
t_License = [ [autoxml.String], autoxml.optional]
|
||||
t_Icon = [ autoxml.String, autoxml.optional]
|
||||
t_RuntimeDependencies = [ [Dependency], autoxml.optional]
|
||||
t_Files = [ [Path], autoxml.optional]
|
||||
t_Conflicts = [ [autoxml.String], autoxml.optional, "Conflicts/Package"]
|
||||
t_ProvidesComar = [ [ComarProvide], autoxml.optional, "Provides/COMAR"]
|
||||
#t_RequiresComar = [ [autoxml.String], autoxml.mandatory, "Requires/COMAR"]
|
||||
t_AdditionalFiles = [ [AdditionalFile], autoxml.optional]
|
||||
t_History = [ [Update], autoxml.optional]
|
||||
|
||||
def pkg_dir(self):
|
||||
packageDir = self.name + '-' \
|
||||
@@ -198,18 +198,18 @@ class Package:
|
||||
|
||||
|
||||
class SpecFile(XmlFile):
|
||||
__metaclass__ = xmlfile.autoxml #needed when we specify a superclass
|
||||
__metaclass__ = autoxml.autoxml #needed when we specify a superclass
|
||||
|
||||
tag = "PISI"
|
||||
|
||||
t_Source = [ Source, xmlfile.mandatory]
|
||||
t_Packages = [ [Package], xmlfile.mandatory, "Package"]
|
||||
t_History = [ [Update], xmlfile.mandatory]
|
||||
t_Source = [ Source, autoxml.mandatory]
|
||||
t_Packages = [ [Package], autoxml.mandatory, "Package"]
|
||||
t_History = [ [Update], autoxml.mandatory]
|
||||
|
||||
#we're not doing this with the init hook right now
|
||||
#def init(self, tag = "PISI"):
|
||||
#ignore tag
|
||||
#XmlFile.__init__(self, tag)
|
||||
#autoxml.__init__(self, tag)
|
||||
|
||||
def read_hook(self, errs):
|
||||
"""Read PSPEC file"""
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2005, TUBITAK/UEKAE
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation; either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Please read the COPYING file.
|
||||
#
|
||||
# Authors: Eray Ozkural <eray@uludag.org.tr>
|
||||
|
||||
from xmlextmdom import *
|
||||
+8
-1
@@ -14,9 +14,16 @@
|
||||
# Gurer Ozen <gurer@uludag.org.tr>
|
||||
|
||||
"""
|
||||
some helper functions implemented with minidom
|
||||
xmlext is a helper module for accessing XML files using
|
||||
xml.dom.minidom.
|
||||
|
||||
XmlFile class further abstracts a dom object using the
|
||||
high-level dom functions provided in xmlext module (and sorely lacking
|
||||
in xml.dom :( )
|
||||
|
||||
function names are mixedCase for compatibility with minidom,
|
||||
an 'old library'
|
||||
|
||||
note: this is a particularly inefficient implementation of xmlext.
|
||||
"""
|
||||
|
||||
|
||||
@@ -0,0 +1,170 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2005, TUBITAK/UEKAE
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation; either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Please read the COPYING file.
|
||||
#
|
||||
# Authors: Eray Ozkural <eray@uludag.org.tr>
|
||||
# Baris Metin <baris@uludag.org.tr
|
||||
# Gurer Ozen <gurer@uludag.org.tr>
|
||||
|
||||
"""
|
||||
some helper functions for high-level access to XML structures
|
||||
|
||||
this implementation uses piksemel, a fast C-based XML library
|
||||
|
||||
function names are mixedCase for compatibility with minidom,
|
||||
an old library
|
||||
"""
|
||||
|
||||
import gettext
|
||||
__trans = gettext.translation('pisi', fallback=True)
|
||||
_ = __trans.ugettext
|
||||
|
||||
import pisi
|
||||
import piksemel as iks
|
||||
|
||||
class XmlError(pisi.Error):
|
||||
"named this way because the class if mostly used with an import *"
|
||||
pass
|
||||
|
||||
def getNodeAttribute(node, attrname):
|
||||
"""get named attribute from DOM node"""
|
||||
if not node.hasAttribute(attrname):
|
||||
return None
|
||||
return node.getAttribute(attrname)
|
||||
|
||||
def getChildElts(node):
|
||||
"""get only child elements"""
|
||||
return filter(lambda x:x.nodeType == x.ELEMENT_NODE, node.childNodes)
|
||||
|
||||
def getTagByName(parent, childName):
|
||||
return [x for x in parent.childNodes
|
||||
if x.nodeType == x.ELEMENT_NODE and x.tagName == childName]
|
||||
|
||||
def getNodeText(node, tagpath = ""):
|
||||
"""get the first child and expect it to be text!"""
|
||||
if tagpath!="":
|
||||
node = getNode(node, tagpath)
|
||||
try:
|
||||
child = node.childNodes[0]
|
||||
except IndexError:
|
||||
return None
|
||||
except AttributeError: # no node by that name
|
||||
return None
|
||||
if child.nodeType == child.TEXT_NODE:
|
||||
# in any case, strip whitespaces...
|
||||
return child.data.strip()
|
||||
else:
|
||||
raise XmlError(_("getNodeText: Expected text node, got something else!"))
|
||||
|
||||
def getChildText(node_s, tagpath):
|
||||
"""get the text of a child at the end of a tag path"""
|
||||
node = getNode(node_s, tagpath)
|
||||
if not node:
|
||||
return None
|
||||
return getNodeText(node)
|
||||
|
||||
def getNode(node, tagpath):
|
||||
"""returns the *first* matching node for given tag path."""
|
||||
|
||||
assert type(tagpath)==str
|
||||
tags = tagpath.split('/')
|
||||
assert len(tags)>0
|
||||
|
||||
# iterative code to search for the path
|
||||
for tag in tags:
|
||||
for child in node.childNodes:
|
||||
if child.nodeType == node.ELEMENT_NODE and child.tagName == tag:
|
||||
return child
|
||||
return None
|
||||
|
||||
def getAllNodes(node, tagPath):
|
||||
"""retrieve all nodes that match a given tag path."""
|
||||
|
||||
#FIXME: better tag split
|
||||
tags = tagPath.split('/')
|
||||
|
||||
if len(tags) == 0:
|
||||
return []
|
||||
|
||||
nodeList = [node] # basis case
|
||||
|
||||
for tag in tags:
|
||||
results = map(lambda x: getTagByName(x, tag), nodeList)
|
||||
nodeList = []
|
||||
for x in results:
|
||||
nodeList.extend(x)
|
||||
pass # emacs indentation error, keep it here
|
||||
|
||||
if len(nodeList) == 0:
|
||||
return []
|
||||
|
||||
return nodeList
|
||||
|
||||
def createTagPath(node, tags):
|
||||
"""create new child at the end of a tag chain starting from node
|
||||
no matter what"""
|
||||
if len(tags)==0:
|
||||
return node
|
||||
dom = node.ownerDocument
|
||||
for tag in tags:
|
||||
node = node.appendChild(dom.createElement(tag))
|
||||
return node
|
||||
|
||||
def addTagPath(node, tags, newnode=None):
|
||||
"""add newnode at the end of a tag chain, smart one"""
|
||||
node = createTagPath(node, tags)
|
||||
if newnode: # node to add specified
|
||||
node.appendChild(newnode)
|
||||
return node
|
||||
|
||||
def addNode(node, tagpath, newnode = None, branch=True):
|
||||
"""add a new node at the end of the tree and returns it
|
||||
if newnode is given adds that node, too."""
|
||||
|
||||
assert type(tagpath)==str
|
||||
tags = []
|
||||
if tagpath != "":
|
||||
tags = tagpath.split('/') # tag chain
|
||||
else:
|
||||
addTagPath(node, [], newnode)
|
||||
return node #FIXME: is this correct!?!?
|
||||
|
||||
assert len(tags)>0 # we want a chain
|
||||
|
||||
# iterative code to search for the path
|
||||
|
||||
if branch:
|
||||
rem = 1
|
||||
else:
|
||||
rem = 0
|
||||
|
||||
while len(tags) > rem:
|
||||
tag = tags.pop(0)
|
||||
nodeList = getTagByName(node, tag)
|
||||
if len(nodeList) == 0: # couldn't find
|
||||
tags.insert(0, tag) # put it back in
|
||||
return addTagPath(node, tags, newnode)
|
||||
else:
|
||||
node = nodeList[len(nodeList)-1] # discard other matches
|
||||
else:
|
||||
# had only one tag..
|
||||
return addTagPath(node, tags, newnode)
|
||||
|
||||
return node
|
||||
|
||||
def newNode(node, tag):
|
||||
return node.ownerDocument.createElement(tag)
|
||||
|
||||
def newTextNode(node, text):
|
||||
return node.ownerDocument.createTextNode(text)
|
||||
|
||||
def addText(node, tagPath, text, branch = True):
|
||||
newnode = newTextNode(node, text)
|
||||
addNode(node, tagPath, newnode, branch)
|
||||
@@ -0,0 +1,154 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2005, TUBITAK/UEKAE
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation; either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Please read the COPYING file.
|
||||
#
|
||||
# Authors: Eray Ozkural <eray@uludag.org.tr>
|
||||
# Baris Metin <baris@uludag.org.tr
|
||||
# Gurer Ozen <gurer@uludag.org.tr>
|
||||
|
||||
"""
|
||||
XmlFile class further abstracts a dom object using the
|
||||
high-level dom functions provided in xmlext module (and sorely lacking
|
||||
in xml.dom :( )
|
||||
|
||||
function names are mixedCase for compatibility with minidom,
|
||||
an 'old library'
|
||||
|
||||
note: this is a particularly inefficient implementation of xmlfile
|
||||
"""
|
||||
|
||||
import gettext
|
||||
__trans = gettext.translation('pisi', fallback=True)
|
||||
_ = __trans.ugettext
|
||||
|
||||
import pisi
|
||||
|
||||
class Error(pisi.Error):
|
||||
"named this way because the class if mostly used with an import *"
|
||||
pass
|
||||
|
||||
class XmlFile(object):
|
||||
"""A class to help reading and writing an XML file"""
|
||||
|
||||
def __init__(self, tag):
|
||||
self.rootTag = tag
|
||||
self.newDOM()
|
||||
|
||||
def newDOM(self):
|
||||
"""clear DOM"""
|
||||
impl = mdom.getDOMImplementation()
|
||||
self.dom = impl.createDocument(None, self.rootTag, None)
|
||||
|
||||
def unlink(self):
|
||||
"""deallocate DOM structure"""
|
||||
self.dom.unlink()
|
||||
|
||||
def rootNode(self):
|
||||
"""returns root document element"""
|
||||
return self.dom.documentElement
|
||||
|
||||
def readxml(self, fileName):
|
||||
try:
|
||||
self.dom = mdom.parse(fileName)
|
||||
except ExpatError, inst:
|
||||
raise XmlError(_("File '%s' has invalid XML: %s\n") % (fileName,
|
||||
str(inst)))
|
||||
|
||||
def writexml(self, fileName):
|
||||
f = codecs.open(fileName,'w', "utf-8")
|
||||
f.write(self.dom.toprettyxml())
|
||||
f.close()
|
||||
|
||||
def verifyRootTag(self):
|
||||
actual_roottag = self.rootNode().tagName
|
||||
if actual_roottag != self.rootTag:
|
||||
raise Error(_("Root tagname %s not identical to %s as expected") %
|
||||
(actual_roottag, self.rootTag) )
|
||||
|
||||
# construction helpers
|
||||
|
||||
def newNode(self, tag):
|
||||
return self.dom.createElement(tag)
|
||||
|
||||
def newTextNode(self, text):
|
||||
return self.dom.createTextNode(text)
|
||||
|
||||
def newAttribute(self, attr):
|
||||
return self.dom.createAttribute(attr)
|
||||
|
||||
# read helpers
|
||||
|
||||
def getNode(self, tagPath = ""):
|
||||
"""returns the *first* matching node for given tag path."""
|
||||
self.verifyRootTag()
|
||||
return getNode(self.dom.documentElement, tagPath)
|
||||
|
||||
def getNodeText(self, tagPath):
|
||||
"""returns the text of *first* matching node for given tag path."""
|
||||
node = self.getNode(tagPath)
|
||||
if not node:
|
||||
return None
|
||||
return getNodeText(node)
|
||||
|
||||
def getAllNodes(self, tagPath):
|
||||
"""returns all nodes matching a given tag path."""
|
||||
self.verifyRootTag()
|
||||
return getAllNodes(self.dom.documentElement, tagPath)
|
||||
|
||||
def getChildren(self, tagpath):
|
||||
""" returns the children of the given path"""
|
||||
node = self.getNode(tagpath)
|
||||
return node.childNodes
|
||||
|
||||
# get only elements of a given type
|
||||
#FIXME: this doesn't work
|
||||
def getChildrenWithType(self, tagpath, type):
|
||||
""" returns the children of the given path, only with given type """
|
||||
node = self.getNode(tagpath)
|
||||
return filter(lambda x:x.nodeType == type, node.childNodes)
|
||||
|
||||
# get only child elements
|
||||
def getChildElts(self, tagpath):
|
||||
""" returns the children of the given path, only with given type """
|
||||
node = self.getNode(tagpath)
|
||||
try:
|
||||
return filter(lambda x:x.nodeType == x.ELEMENT_NODE,
|
||||
node.childNodes)
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
# write helpers
|
||||
|
||||
def addNode(self, tagPath, newnode = None):
|
||||
"this adds the newnode under given tag path"
|
||||
self.verifyRootTag()
|
||||
return addNode(self.dom.documentElement, tagPath, newnode)
|
||||
|
||||
def addNodeUnder(self, node, tagPath, newnode = None):
|
||||
"this adds the new stuff under node and then following tag path"
|
||||
self.verifyRootTag()
|
||||
return addNode(node, tagPath, newnode)
|
||||
|
||||
def addChild(self, newnode):
|
||||
"add a new child node right under root element document"
|
||||
self.dom.documentElement.appendChild(newnode)
|
||||
|
||||
def addText(self, node, text):
|
||||
"add text to node"
|
||||
node.appendChild(self.newTextNode(text))
|
||||
|
||||
def addTextNode(self, tagPath, text):
|
||||
"add a text node with given tag path"
|
||||
node = self.addNode(tagPath, self.newTextNode(text))
|
||||
return node
|
||||
|
||||
def addTextNodeUnder(self, node, tagPath, text):
|
||||
"add a text node under given node with tag path (phew)"
|
||||
return self.addNodeUnder(node, tagPath, self.newTextNode(text))
|
||||
@@ -0,0 +1,150 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
#
|
||||
# Copyright (C) 2005, TUBITAK/UEKAE
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free
|
||||
# Software Foundation; either version 2 of the License, or (at your option)
|
||||
# any later version.
|
||||
#
|
||||
# Please read the COPYING file.
|
||||
#
|
||||
# Authors: Eray Ozkural <eray@uludag.org.tr>
|
||||
# Gurer Ozen <gurer@uludag.org.tr>
|
||||
# Baris Metin <baris@uludag.org.tr
|
||||
|
||||
"""
|
||||
XmlFile class further abstracts a dom object using the
|
||||
high-level dom functions provided in xmlext module
|
||||
|
||||
this implementation uses piksemel, a fast C-based XML library
|
||||
"""
|
||||
|
||||
import gettext
|
||||
__trans = gettext.translation('pisi', fallback=True)
|
||||
_ = __trans.ugettext
|
||||
|
||||
import pisi
|
||||
|
||||
class Error(pisi.Error):
|
||||
"named this way because the class if mostly used with an import *"
|
||||
pass
|
||||
|
||||
class XmlFile(object):
|
||||
"""A class to help reading and writing an XML file"""
|
||||
|
||||
def __init__(self, tag):
|
||||
self.rootTag = tag
|
||||
self.newDOM()
|
||||
|
||||
def newDOM(self):
|
||||
"""clear DOM"""
|
||||
impl = mdom.getDOMImplementation()
|
||||
self.dom = impl.createDocument(None, self.rootTag, None)
|
||||
|
||||
def unlink(self):
|
||||
"""deallocate DOM structure"""
|
||||
self.dom.unlink()
|
||||
|
||||
def rootNode(self):
|
||||
"""returns root document element"""
|
||||
return self.dom.documentElement
|
||||
|
||||
def readxml(self, fileName):
|
||||
try:
|
||||
self.dom = mdom.parse(fileName)
|
||||
except ExpatError, inst:
|
||||
raise XmlError(_("File '%s' has invalid XML: %s\n") % (fileName,
|
||||
str(inst)))
|
||||
|
||||
def writexml(self, fileName):
|
||||
f = codecs.open(fileName,'w', "utf-8")
|
||||
f.write(self.dom.toprettyxml())
|
||||
f.close()
|
||||
|
||||
def verifyRootTag(self):
|
||||
actual_roottag = self.rootNode().tagName
|
||||
if actual_roottag != self.rootTag:
|
||||
raise Error(_("Root tagname %s not identical to %s as expected") %
|
||||
(actual_roottag, self.rootTag) )
|
||||
|
||||
# construction helpers
|
||||
|
||||
def newNode(self, tag):
|
||||
return self.dom.createElement(tag)
|
||||
|
||||
def newTextNode(self, text):
|
||||
return self.dom.createTextNode(text)
|
||||
|
||||
def newAttribute(self, attr):
|
||||
return self.dom.createAttribute(attr)
|
||||
|
||||
# read helpers
|
||||
|
||||
def getNode(self, tagPath = ""):
|
||||
"""returns the *first* matching node for given tag path."""
|
||||
self.verifyRootTag()
|
||||
return getNode(self.dom.documentElement, tagPath)
|
||||
|
||||
def getNodeText(self, tagPath):
|
||||
"""returns the text of *first* matching node for given tag path."""
|
||||
node = self.getNode(tagPath)
|
||||
if not node:
|
||||
return None
|
||||
return getNodeText(node)
|
||||
|
||||
def getAllNodes(self, tagPath):
|
||||
"""returns all nodes matching a given tag path."""
|
||||
self.verifyRootTag()
|
||||
return getAllNodes(self.dom.documentElement, tagPath)
|
||||
|
||||
def getChildren(self, tagpath):
|
||||
""" returns the children of the given path"""
|
||||
node = self.getNode(tagpath)
|
||||
return node.childNodes
|
||||
|
||||
# get only elements of a given type
|
||||
#FIXME: this doesn't work
|
||||
def getChildrenWithType(self, tagpath, type):
|
||||
""" returns the children of the given path, only with given type """
|
||||
node = self.getNode(tagpath)
|
||||
return filter(lambda x:x.nodeType == type, node.childNodes)
|
||||
|
||||
# get only child elements
|
||||
def getChildElts(self, tagpath):
|
||||
""" returns the children of the given path, only with given type """
|
||||
node = self.getNode(tagpath)
|
||||
try:
|
||||
return filter(lambda x:x.nodeType == x.ELEMENT_NODE,
|
||||
node.childNodes)
|
||||
except AttributeError:
|
||||
return None
|
||||
|
||||
# write helpers
|
||||
|
||||
def addNode(self, tagPath, newnode = None):
|
||||
"this adds the newnode under given tag path"
|
||||
self.verifyRootTag()
|
||||
return addNode(self.dom.documentElement, tagPath, newnode)
|
||||
|
||||
def addNodeUnder(self, node, tagPath, newnode = None):
|
||||
"this adds the new stuff under node and then following tag path"
|
||||
self.verifyRootTag()
|
||||
return addNode(node, tagPath, newnode)
|
||||
|
||||
def addChild(self, newnode):
|
||||
"add a new child node right under root element document"
|
||||
self.dom.documentElement.appendChild(newnode)
|
||||
|
||||
def addText(self, node, text):
|
||||
"add text to node"
|
||||
node.appendChild(self.newTextNode(text))
|
||||
|
||||
def addTextNode(self, tagPath, text):
|
||||
"add a text node with given tag path"
|
||||
node = self.addNode(tagPath, self.newTextNode(text))
|
||||
return node
|
||||
|
||||
def addTextNodeUnder(self, node, tagPath, text):
|
||||
"add a text node under given node with tag path (phew)"
|
||||
return self.addNodeUnder(node, tagPath, self.newTextNode(text))
|
||||
Reference in New Issue
Block a user