ParsedAxisSpecifier.py :  » XML » 4Suite » 4Suite-XML-1.0.2 » Ft » Xml » XPath » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » XML » 4Suite 
4Suite » 4Suite XML 1.0.2 » Ft » Xml » XPath » ParsedAxisSpecifier.py
########################################################################
# $Header: /var/local/cvsroot/4Suite/Ft/Xml/XPath/ParsedAxisSpecifier.py,v 1.15 2005/02/09 11:10:54 mbrown Exp $
"""
A parsed token that represents an axis specifier.

Copyright 2004 Fourthought, Inc. (USA).
Detailed license and copyright information: http://4suite.org/COPYRIGHT
Project home, documentation, distributions: http://4suite.org/
"""

from xml.dom import Node

from Ft.Xml.XPath import NAMESPACE_NODE

def ParsedAxisSpecifier(axis):
    try:
        return g_classMap[axis](axis)
    except KeyError:
        raise SyntaxError("Invalid axis: %s" % axis)


class AxisSpecifier:

    principalType = Node.ELEMENT_NODE

    def __init__(self, axis):
        self._axis = axis

    def select(self, context, nodeTest):
        """
        Always returns a node-set and 0 if forward, 1 if reverse.
        """
        return ([], 0)

    def descendants(self, context, nodeTest, node, nodeSet):
        """Select all of the descendants from the context node"""
        if context.node.nodeType != Node.ATTRIBUTE_NODE:
            for child in node.childNodes:
                if nodeTest(context, child, self.principalType):
                    nodeSet.append(child)
                if child.childNodes:
                    self.descendants(context, nodeTest, child, nodeSet)
        return (nodeSet, 0)

    def pprint(self, indent=''):
        print indent + str(self)

    def __str__(self):
        return '<AxisSpecifier at %x: %s>' % (id(self), repr(self))

    def __repr__(self):
        """Always displays verbose expression"""
        return self._axis


class ParsedAncestorAxisSpecifier(AxisSpecifier):
    def select(self, context, nodeTest):
        """Select all of the ancestors including the root"""
        nodeSet = []
        parent = ((context.node.nodeType == Node.ATTRIBUTE_NODE) and
                context.node.ownerElement or context.node.parentNode)
        while parent:
            if nodeTest(context, parent, self.principalType):
                nodeSet.append(parent)
            parent = parent.parentNode
        nodeSet.reverse()
        return (nodeSet, 1)


class ParsedAncestorOrSelfAxisSpecifier(AxisSpecifier):
    def select(self, context, nodeTest):
        """Select all of the ancestors including ourselves through the root"""
        node = context.node
        if nodeTest(context, node, self.principalType):
            nodeSet = [node]
        else:
            nodeSet = []
        parent = ((node.nodeType == Node.ATTRIBUTE_NODE) and
                node.ownerElement or node.parentNode)
        while parent:
            if nodeTest(context, parent, self.principalType):
                nodeSet.append(parent)
            parent = parent.parentNode
        nodeSet.reverse()
        return (nodeSet, 1)


class ParsedAttributeAxisSpecifier(AxisSpecifier):

    principalType = Node.ATTRIBUTE_NODE

    def select(self, context, nodeTest):
        """Select all of the attributes from the context node"""
        result = [ attr for attr in context.node.xpathAttributes
                   if nodeTest(context, attr, self.principalType) ]
        return (result, 0)


class ParsedChildAxisSpecifier(AxisSpecifier):
    def select(self, context, nodeTest):
        """Select all of the children of the context node"""
        result = [ node for node in context.node.childNodes
                   if nodeTest(context, node, self.principalType) ]
        return (result, 0)


class ParsedDescendantOrSelfAxisSpecifier(AxisSpecifier):
    def select(self, context, nodeTest):
        """Select the context node and all of its descendants"""
        if nodeTest(context, context.node, self.principalType):
            nodeSet = [context.node]
        else:
            nodeSet = []
        self.descendants(context, nodeTest, context.node, nodeSet)
        return (nodeSet, 0)


class ParsedDescendantAxisSpecifier(AxisSpecifier):
    def select(self, context, nodeTest):
        nodeSet = []
        self.descendants(context, nodeTest, context.node, nodeSet)
        return (nodeSet, 0)


class ParsedFollowingSiblingAxisSpecifier(AxisSpecifier):
    def select(self, context, nodeTest):
        """Select all of the siblings that follow the context node"""
        result = []
        sibling = context.node.nextSibling
        while sibling:
            if nodeTest(context, sibling, self.principalType):
                result.append(sibling)
            sibling = sibling.nextSibling
        return (result, 0)


class ParsedFollowingAxisSpecifier(AxisSpecifier):
    def select(self, context, nodeTest):
        """
        Select all of the nodes the follow the context node,
        not including descendants.
        """
        result = []
        curr = context.node
        while curr != (context.node.rootNode):
            sibling = curr.nextSibling
            while sibling:
                if nodeTest(context, sibling, self.principalType):
                    result.append(sibling)
                self.descendants(context, nodeTest, sibling, result)
                sibling = sibling.nextSibling
            curr = ((curr.nodeType == Node.ATTRIBUTE_NODE) and
                    curr.ownerElement or curr.parentNode)
        return (result, 0)



class ParsedNamespaceAxisSpecifier(AxisSpecifier):

    principalType = NAMESPACE_NODE

    def select(self, context, nodeTest):
        """Select all of the namespaces from the context node."""
        result = [ xns for xns in context.node.xpathNamespaces
                   if nodeTest(context, xns, self.principalType) ]
        return (result, 0)


class ParsedParentAxisSpecifier(AxisSpecifier):
    def select(self, context, nodeTest):
        """Select the parent of the context node"""
        parent = ((context.node.nodeType == Node.ATTRIBUTE_NODE) and
                  context.node.ownerElement or context.node.parentNode)
        if parent and nodeTest(context, parent, self.principalType):
            result = [parent]
        else:
            result = []
        return (result, 1)


class ParsedPrecedingSiblingAxisSpecifier(AxisSpecifier):
    def select(self, context, nodeTest):
        """Select all of the siblings that precede the context node"""
        result = []
        sibling = context.node.previousSibling
        while sibling:
            if nodeTest(context, sibling, self.principalType):
                result.append(sibling)
            sibling = sibling.previousSibling
        # Put the list in document order
        result.reverse()
        return (result, 1)


class ParsedPrecedingAxisSpecifier(AxisSpecifier):
    def select(self, context, nodeTest):
        """Select all of the nodes the precede the context node, not including ancestors"""
        # Create a list of lists of descendants of the nodes
        # that precede the context node. (reverse doc order)
        doc_list = []
        curr = context.node
        while curr:
            sib = curr.previousSibling
            while sib:
                result = []
                if nodeTest(context, sib, self.principalType):
                    result = [sib]
                self.descendants(context, nodeTest, sib, result)
                doc_list.append(result)
                sib = sib.previousSibling
            curr = curr.nodeType == Node.ATTRIBUTE_NODE and curr.ownerElement or curr.parentNode

        # Create a single list in document order
        result = []
        for i in xrange(1, len(doc_list)+1):
            result.extend(doc_list[-i])
        return (result, 1)


class ParsedSelfAxisSpecifier(AxisSpecifier):
    def select(self, context, nodeTest):
        """Select the context node"""
        if nodeTest(context, context.node, self.principalType):
            return ([context.node], 0)
        return ([], 0)


g_classMap = {
    'ancestor' : ParsedAncestorAxisSpecifier,
    'ancestor-or-self' : ParsedAncestorOrSelfAxisSpecifier,
    'child' : ParsedChildAxisSpecifier,
    'parent' : ParsedParentAxisSpecifier,
    'descendant' : ParsedDescendantAxisSpecifier,
    'descendant-or-self' : ParsedDescendantOrSelfAxisSpecifier,
    'attribute' : ParsedAttributeAxisSpecifier,
    'following' : ParsedFollowingAxisSpecifier,
    'following-sibling' : ParsedFollowingSiblingAxisSpecifier,
    'preceding' : ParsedPrecedingAxisSpecifier,
    'preceding-sibling' : ParsedPrecedingSiblingAxisSpecifier,
    'namespace' : ParsedNamespaceAxisSpecifier,
    'self' : ParsedSelfAxisSpecifier,
    }

www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.