def Test(tester):

    tester.startGroup('Node-set Expressions')

    tester.startTest('Creating test environment')

    from Ft.Xml.XPath import ParsedExpr
    from Ft.Xml.XPath import ParsedPredicateList

    DomTree = tester.test_data['tree']

    import DummyExpr
    from DummyExpr import boolT, boolF
    from DummyExpr import num3, numN4, num4p5
    from DummyExpr import strPi, strText
    
    nodeset0 = DummyExpr.DummyNodeSetExpr([])
    nodeset1 = DummyExpr.DummyNodeSetExpr([DomTree.ROOT])
    nodeset2 = DummyExpr.DummyNodeSetExpr([DomTree.ROOT, DomTree.CHILD1])
    nodeset3 = DummyExpr.DummyNodeSetExpr([DomTree.CHILD1])
    nodeset4 = DummyExpr.DummyNodeSetExpr([DomTree.CHILD3])

    from Ft.Xml.XPath import Context
    context1 = Context.Context(DomTree.CHILD1,1,2)
    context2 = Context.Context(DomTree.CHILD2,2,2)
    plT = ParsedPredicateList.ParsedPredicateList([boolT])
    plF = ParsedPredicateList.ParsedPredicateList([boolF])

    tests = {ParsedExpr.ParsedFilterExpr : [((nodeset2, plT), context1, list(nodeset2.val)),
                                            ((nodeset2, plF), context1, []),
                                            ],
             ParsedExpr.ParsedPathExpr : [((0, nodeset2, nodeset1), context1, list(nodeset1.val)),
                                          ],
             ParsedExpr.ParsedUnionExpr : [((nodeset2, nodeset1), context1, list(nodeset2.val)),
                                           ],

             }

    tester.testDone()

    for (expr, boolTests) in tests.items():
        for (args, context, expected) in boolTests:
            p = apply(expr, args)
            tester.startTest('Comparing %s' % repr(p))
            result = p.evaluate(context)
            tester.compare(result, expected)
            tester.testDone()

    tester.groupDone()
def Test(tester):

    tester.startGroup('Location path expressions')

    tester.startTest('Creating test environment')
    from Ft.Xml.XPath.ParsedAbbreviatedAbsoluteLocationPath import ParsedAbbreviatedAbsoluteLocationPath
    from Ft.Xml.XPath.ParsedAbbreviatedRelativeLocationPath import ParsedAbbreviatedRelativeLocationPath
    from Ft.Xml.XPath.ParsedAbsoluteLocationPath import ParsedAbsoluteLocationPath
    from Ft.Xml.XPath.ParsedRelativeLocationPath import ParsedRelativeLocationPath
    from Ft.Xml.XPath import ParsedStep
    from Ft.Xml.XPath import ParsedNodeTest
    from Ft.Xml.XPath import ParsedAxisSpecifier
    from Ft.Xml.XPath import Context

    DomTree = tester.test_data['tree']

    nt = ParsedNodeTest.ParsedNameTest('*')
    as = ParsedAxisSpecifier.ParsedAxisSpecifier('child')
    step = ParsedStep.ParsedStep(as,nt,None)
    # [(expression, context, expected)...]
    tests = [(ParsedAbbreviatedAbsoluteLocationPath(step),
              Context.Context(DomTree.CHILD2, 1, 1),
              # all element children
              [DomTree.ROOT, DomTree.CHILD1] + DomTree.GCHILDREN1 +
              [DomTree.CHILD2] + DomTree.GCHILDREN2 + [DomTree.CHILD3] +
              [DomTree.LANG] + DomTree.LCHILDREN),
             (ParsedAbbreviatedRelativeLocationPath(step, step),
              Context.Context(DomTree.ROOT, 1, 1),
              # all element grand children
              DomTree.GCHILDREN1 + DomTree.GCHILDREN2 + DomTree.LCHILDREN),
             (ParsedAbsoluteLocationPath(None),
              Context.Context(DomTree.CHILD1, 1, 1),
              [DomTree.DOM]),
             (ParsedAbsoluteLocationPath(step),
              Context.Context(DomTree.CHILD1, 1, 1),
              [DomTree.ROOT]),
             (ParsedRelativeLocationPath(step, step),
              Context.Context(DomTree.ROOT, 1, 1),
              DomTree.GCHILDREN1 + DomTree.GCHILDREN2 + DomTree.LCHILDREN),
             ]
    tester.testDone()

    for (location, context, expected) in tests:
        tester.startTest(repr(location))
        actual = location.select(context)
        tester.compare(expected, actual)
        tester.testDone()

    return tester.groupDone()
Beispiel #3
0
def Test(tester):
    tester.startGroup('Exercise namespace nodes')

    isrc = InputSource.DefaultFactory.fromString(SRC_1,
                                                 Uri.OsPathToUri(os.getcwd()))
    doc = NonvalidatingReader.parse(isrc)
    con = Context.Context(doc, 1, 1)

    EXPR = '//namespace::node()'
    expr = Compile(EXPR)
    #expr is <AbbreviatedAbsoluteLocationPath: /descendant-or-self::node()/namespace::node()>
    #expr._rel is <Step: namespace::node()>
    #expr._step is <Step: descendant-or-self::node()>
    tester.startTest(EXPR)
    actual = expr.evaluate(con)
    tester.compare(7, len(actual))
    tester.testDone()

    EXPR = '//node()/namespace::node()'
    expr = Compile(EXPR)
    tester.startTest(EXPR)
    EXPECTED = []
    actual = expr.evaluate(con)
    tester.compare(7, len(actual))
    tester.testDone()

    EXPR = '//*/namespace::node()'
    expr = Compile(EXPR)
    tester.startTest(EXPR)
    EXPECTED = []
    actual = expr.evaluate(con)
    tester.compare(7, len(actual))
    tester.testDone()

    EXPR = '/*/*/namespace::node()'
    expr = Compile(EXPR)
    tester.startTest(EXPR)
    EXPECTED = []
    actual = expr.evaluate(con)
    tester.compare(6, len(actual))
    tester.testDone()

    EXPR = '/*/namespace::node()|/*/*/namespace::node()'
    expr = Compile(EXPR)
    tester.startTest(EXPR)
    EXPECTED = []
    actual = expr.evaluate(con)
    tester.compare(7, len(actual))
    tester.testDone()

    EXPR = '//*'
    expr = Compile(EXPR)
    #expr is <AbbreviatedAbsoluteLocationPath: /descendant-or-self::node()/child::*>
    tester.startTest(EXPR)
    EXPECTED = []
    actual = expr.evaluate(con)
    tester.compare(4, len(actual))
    tester.testDone()

    return tester.groupDone()
Beispiel #4
0
def Test(tester):

    context = Context.Context(tester.test_data['tree'].CHILD1, 1, 3)

    tester.startGroup('String Literals')

    tester.startTest('Parse string literal expression tokens')
    setupStringLiterals()
    tester.testDone()

    tester.startGroup('Evaluate parsed string literal expression tokens')
    global StringLiterals
    for parsedexpr, expected in StringLiterals.values():
        tester.startTest(repr(parsedexpr))
        tester.compare(expected, parsedexpr.evaluate(context))
        tester.testDone()
    tester.groupDone()

    tester.groupDone()

    tester.startGroup('Number Literals')

    tester.startTest('Parse numeric literal expression tokens')
    setupNumberLiterals()
    tester.testDone()

    tester.startGroup('Evaluate parsed numeric literal expression tokens')
    global NumberLiterals
    for parsedexpr, expected in NumberLiterals.values():
        tester.startTest(repr(parsedexpr))
        tester.compare(expected, parsedexpr.evaluate(context))
        tester.testDone()
    tester.groupDone()

    tester.groupDone()
Beispiel #5
0
 def execute(self, node, xupdate, variables=None, extFunctionMap=None):
     variables = variables or {}
     context = Context.Context(node,
                               varBindings=variables,
                               extFunctionMap=extFunctionMap)
     self.visit(context, xupdate, 0)
     #xupdate.instantiate(context, self)
     return node
Beispiel #6
0
    def execute(self, node, xupdate, variables=None, processorNss=None):
        if variables is None:
            variables = {}
        if processorNss is None:
            processorNss = {}

        context = Context.Context(node, varBindings=variables,
                                  processorNss=processorNss)
        self.visit(context, xupdate, 0)
        return node
Beispiel #7
0
    def _xu_append(self, context, element, preserveSpace):
        select = element.getAttributeNS(EMPTY_NAMESPACE, u'select')
        if not select:
            raise XUpdateException(XUpdateException.NO_SELECT)

        child = element.getAttributeNS(EMPTY_NAMESPACE, u'child') or u'last()'

        oldNss = context.processorNss
        context.processorNss = Domlette.GetAllNs(element)

        nodeset = self.evaluateExpression(context, select)
        if not isinstance(nodeset, Types.NodesetType) or not nodeset:
            # Error if not a node-set or empty node-set
            raise XUpdateException(XUpdateException.INVALID_SELECT,
                                   expr=select)

        for refnode in nodeset:
            self.pushDomResult(refnode.ownerDocument)
            # A wrapper element is used in case attributes are being added
            wrapper_localName = 'wrapper'
            wrapper_namespace = EMPTY_NAMESPACE
            try:
                self.writers[-1].startElement(wrapper_localName,
                                              wrapper_namespace)
                for node in element.childNodes:
                    self.visit(context, node, preserveSpace)
            finally:
                self.writers[-1].endElement(wrapper_localName,
                                            wrapper_namespace)
                result = self.popResult()

            size = len(refnode.childNodes)
            con = Context.Context(refnode, 1, size,
                                  processorNss={'xupdate': XUPDATE_NS})
            # Python lists is 0-indexed counting, node-sets 1-indexed
            position = self.evaluateExpression(con, child)
            position = int(Conversions.NumberValue(position))

            wrapper = result.childNodes[0]
            if wrapper.attributes and hasattr(refnode, 'setAttributeNodeNS'):
                for attr in wrapper.attributes.values():
                    refnode.setAttributeNodeNS(attr)

            # we operate on a shallow copy of the child nodes here to avoid
            # modifying the membership of the sequence we're interating over.
            for node in tuple(wrapper.childNodes):
                if position >= size:
                    refnode.appendChild(node)
                else:
                    refnode.insertBefore(node, refnode.childNodes[position])

        context.processorNss = oldNss
        return
Beispiel #8
0
def Test(tester):

    tester.startGroup('Predicate List')

    tester.startTest('Checking syntax')
    from Ft.Xml.XPath import ParsedPredicateList
    from Ft.Xml.XPath import ParsedExpr
    from Ft.Xml.XPath import Context
    from Ft.Xml.XPath import Evaluate
    import DummyExpr
    DomTree = tester.test_data['tree']
    tester.testDone()

    tester.startTest('Creating test environment')
    t = DummyExpr.DummyBooleanExpr(1)
    f = DummyExpr.DummyBooleanExpr(0)
    a = ParsedExpr.ParsedAndExpr(t, f)
    o = ParsedExpr.ParsedOrExpr(t, f)
    context = Context.Context(DomTree.ROOT, 1, 1)
    tester.testDone()

    p = ParsedPredicateList.ParsedPredicateList([a, t])
    tester.startTest('Filter of "%s"' % repr(p))
    result = p.filter([context.node], context, 0)
    tester.compare(0, len(result))
    tester.testDone()

    p = ParsedPredicateList.ParsedPredicateList([o, t])
    tester.startTest('Filter of "%s"' % repr(p))
    result = p.filter([context.node], context, 0)
    tester.compare([DomTree.ROOT], result)
    tester.testDone()

    dom = Domlette.NonvalidatingReader.parseString(source_1, '.')

    expected = filter(lambda x: x.nodeType == Node.ELEMENT_NODE,
                      dom.documentElement.childNodes)[-1]

    tests = [
        ("//element[descendant::y[.='z']]", [expected]),
        ("//element[descendant::y[.='z']][1]", [expected]),
        ("//element[descendant::y[.='z']][2]", []),
    ]

    for (expr, expected) in tests:
        tester.startTest(expr)
        actual = Evaluate(expr, contextNode=dom)
        tester.compare(expected, actual)
        tester.testDone()

    return tester.groupDone()
Beispiel #9
0
def Test(tester):
    tester.startGroup('CDATA sections in doc')

    isrc = InputSource.DefaultFactory.fromString(SRC_1,
                                                 Uri.OsPathToUri(os.getcwd()))
    doc = NonvalidatingReader.parse(isrc)
    con = Context.Context(doc, 1, 1)

    EXPR = '/doc/elem/text()'
    expr = Compile(EXPR)
    tester.startTest(EXPR)
    actual = [node.data for node in expr.evaluate(con)]
    tester.compare(actual, ["abc"] * 3)
    tester.testDone()

    return tester.groupDone()
Beispiel #10
0
def Test(tester):

    tester.startTest("Evaluate on a HTML Document")

    if HtmlLib is None:
        tester.warning("Requires PyXML to be installed")
        tester.testDone()
        return

    xml_dom = HtmlLib.FromHtml(html)

    p = Ft.Xml.XPath.parser.new()
    exp = p.parse("/HTML/HEAD")

    c=Context.Context(xml_dom,0,0)
    result=exp.evaluate(c)

    
    st = cStringIO.StringIO()
    Print(result[0],st)
    tester.compare(expected_1,st.getvalue())

    tester.testDone()
class sax2dom_chunker(sax.ContentHandler):
    """
    Note: Ignores nodes prior to the document element, such as PIs and
    text nodes.  Collapses CDATA sections into plain text
    Only designed to work if you set the feature
      sax.handler.feature_namespaces
    to 1 on the parser you use.

    xpatterns - list of XPatterns.  Only portions of the
        tree within these patterns will be instantiated as DOM (as
        chunks fed to chunk_consumer in sequence)
        If None (the default, a DOM node will be created representing
        the entire tree.

    nss - a dictionary of prefix -> namespace name mappings used to
        interpret XPatterns
    
    chunk_consumer - a callable object taking a DOM node.  It will be
        invoked as each DOM chunk is prepared.
    
    domimpl - DOM implemention to build, e.g. mindom (the default)
        or cDomlette or pxdom (if you have the right third-party
        packages installed).
    
    owner_doc - for advanced uses, if you want to use an existing
        DOM document object as the owner of all created nodes.
        
    """
    def __init__(
        self,
        xpatterns=None,
        nss=None,
        chunk_consumer=None,
        domimpl=Domlette.implementation,
        owner_doc=None,
    ):
        nss = nss or {}
        #HINT: To use minidom
        #domimpl = xml.dom.minidom.getDOMImplementation()
        self._impl = domimpl
        if isinstance(xpatterns, str) or isinstance(xpatterns, unicode):
            xpatterns = [xpatterns]
        #print xpatterns
        if owner_doc:
            self._owner_doc = owner_doc
        else:
            try:
                dt = self._impl.createDocumentType(DUMMY_DOCELEM, None, u'')
            except AttributeError:
                #Domlette doesn't need createDocumentType
                dt = None
            self._owner_doc = self._impl.createDocument(
                DUMMY_DOCELEM, DUMMY_DOCELEM, dt)
        #Create a docfrag to hold all the generated nodes.
        root_node = self._owner_doc.createDocumentFragment()
        self._nodeStack = [root_node]
        self.state_machine = xpattern_state_manager(xpatterns, nss)
        self._chunk_consumer = chunk_consumer
        return

    def get_root_node(self):
        """
        Only useful if the user does not register trim paths
        If so, then after SAX processing the user can call this
        method to retrieve resulting DOM representing the entire
        document
        """
        return self._nodeStack[0]

    #Overridden ContentHandler methods
    def startDocument(self):
        self.state_machine.event(1, None, None)
        return

    def endDocument(self):
        self.state_machine.event(0, None, None)
        return

    def startElementNS(self, (ns, local), qname, attribs):
        self.state_machine.event(1, ns, local)
        if not self.state_machine.status():
            for attrtest in self.state_machine.attribute_tests:
                e = self._owner_doc.createElementNS(ns, qname or local)
                for (ns, local), value in attribs.items():
                    e.setAttributeNS(ns, attribs.getQNameByName((ns, local)),
                                     value)
                #e = dummy_element(qname, attribs, self._nodeStack[0])
                matched = attrtest.evaluate(Context.Context(e))
                if matched:
                    #Feed the consumer
                    #self._nodeStack[TOP].appendChild(matched[0]) #"xml.dom.HierarchyRequestErr: Ft.Xml.cDomlette.Attr nodes cannot be a child of Ft.Xml.cDomlette.DocumentFragment nodes"
                    self._chunk_consumer(matched[0])
                    #Start over with new doc frag so old memory can be reclaimed
                    root_node = self._owner_doc.createDocumentFragment()
                    self._nodeStack = [root_node]
            return

        new_element = self._owner_doc.createElementNS(ns, qname or local)

        for (attr_ns, lname) in attribs:
            value = attribs[(attr_ns, lname)]
            if attr_ns is not None:
                attr_qname = attribs.getQNameByName((attr_ns, lname))
            else:
                attr_qname = lname
            attr = self._owner_doc.createAttributeNS(attr_ns, attr_qname)
            attr_qname = attribs.getQNameByName((attr_ns, lname))
            attr.value = value
            new_element.setAttributeNodeNS(attr)

        self._nodeStack.append(new_element)
        return
Beispiel #12
0
    def visit(self, context, node, preserveSpace):
        #FIXME: We should improve this function from this ugly-ass
        #switch thingie to dynamic dispatch
        if node.nodeType == Node.ELEMENT_NODE:
            xml_space = node.getAttributeNS(XML_NAMESPACE, 'space')
            if xml_space == 'preserve':
                preserveSpace = 1
            elif xml_space == 'default':
                preserveSpace = 0
            # else, no change

            if node.namespaceURI != XUPDATE_NS:
                self.writers[-1].startElement(node.nodeName, node.namespaceURI)

                # Process the attributes

                oldNss = context.processorNss
                context.processorNss = Domlette.GetAllNs(node)

                for attr in node.attributes.values():
                    value = self.parseAVT(attr.value)
                    value = value.evaluate(context)
                    self.writers[-1].attribute(attr.nodeName, value,
                                               attr.namespaceURI)

                context.processorNss = oldNss
                # Now the children
                for child in node.childNodes:
                    context = self.visit(context, child, preserveSpace)
                self.writers[-1].endElement(node.nodeName)
                return context

            # XUpdate elements
            try:
                restoreGraphContext = False
                graphURI = node.getAttributeNS(EMPTY_NAMESPACE, u'to-graph')
                if graphURI:
                    graphURI = self.parseAVT(graphURI)
                    oldNss = context.processorNss
                    context.processorNss = Domlette.GetAllNs(node)
                    graphURI = graphURI.evaluate(context)
                    context.processorNss = oldNss

                    context.node.ownerDocument.pushContext(graphURI)
                    restoreGraphContext = True

                if node.localName == 'modifications':
                    for n in node.childNodes:
                        self.visit(context, n, preserveSpace)
                elif node.localName == 'remove':
                    select = node.getAttributeNS(EMPTY_NAMESPACE, u'select')
                    #import sys
                    #print >>sys.stderr, 'removing', select
                    if not select:
                        raise XUpdateException(XUpdateException.NO_SELECT)
                    _select = self.parseExpression(select)
                    oldNss = context.processorNss
                    context.processorNss = Domlette.GetAllNs(node)
                    nodeset = _select.evaluate(context)
                    if nodeset:
                        #change from 4Suite -- why did it only delete the first node in the nodeset?
                        #that's not in the spec or very intuitive
                        #refnode = nodeset[0]
                        for refnode in nodeset:
                            if refnode.nodeType == Node.ATTRIBUTE_NODE:
                                parent = refnode.ownerElement
                                parent.removeAttributeNode(refnode)
                            else:
                                parent = refnode.parentNode
                                if parent is None:
                                    parent = refnode.ownerDocument
                                parent.removeChild(refnode)
                    context.processorNss = oldNss
                elif node.localName in ['insert-after', 'insert-before']:
                    select = node.getAttributeNS(EMPTY_NAMESPACE, u'select')
                    if not select:
                        raise XUpdateException(XUpdateException.NO_SELECT)
                    _select = self.parseExpression(select)
                    oldNss = context.processorNss
                    context.processorNss = Domlette.GetAllNs(node)

                    nodeset = _select.evaluate(context)
                    if not nodeset:
                        raise XUpdateException(XUpdateException.INVALID_SELECT)
                    refnode = nodeset[0]

                    self.pushDomResult(refnode.ownerDocument)
                    try:
                        for child in node.childNodes:
                            context = self.visit(context, child, preserveSpace)
                    finally:
                        result = self.popResult()

                    if node.localName == 'insert-before':
                        refnode.parentNode.insertBefore(result, refnode)
                    elif node.localName == 'insert-after':
                        # if arg 2 is None, insertBefore behaves like appendChild
                        refnode.parentNode.insertBefore(
                            result, refnode.nextSibling)
                    context.processorNss = oldNss
                elif node.localName == 'element':
                    name = node.getAttributeNS(EMPTY_NAMESPACE, 'name')
                    if not name:
                        raise XUpdateException(XUpdateException.NO_NAME)
                    _name = self.parseAVT(name)

                    namespace = node.getAttributeNS(EMPTY_NAMESPACE,
                                                    'namespace')
                    _namespace = self.parseAVT(namespace)

                    oldNss = context.processorNss
                    context.processorNss = Domlette.GetAllNs(node)
                    name = _name.evaluate(context)

                    namespace = _namespace and _namespace.evaluate(context)

                    (prefix, local) = SplitQName(name)
                    if not namespace:
                        if prefix:
                            namespace = context.processorNss[prefix]
                        else:
                            namespace = EMPTY_NAMESPACE

                    self.writers[-1].startElement(name, namespace)
                    for child in node.childNodes:
                        context = self.visit(context, child, preserveSpace)
                    self.writers[-1].endElement(name)
                    context.processorNss = oldNss
                elif node.localName == 'attribute':
                    name = node.getAttributeNS(EMPTY_NAMESPACE, 'name')
                    if not name:
                        raise XUpdateException(XUpdateException.NO_NAME)
                    _name = self.parseAVT(name)

                    namespace = node.getAttributeNS(EMPTY_NAMESPACE,
                                                    'namespace')
                    _namespace = self.parseAVT(namespace)

                    oldNss = context.processorNss
                    context.processorNss = Domlette.GetAllNs(node)
                    name = _name.evaluate(context)
                    namespace = _namespace and _namespace.evaluate(context)

                    (prefix, local) = SplitQName(name)
                    if not namespace:
                        if prefix:
                            namespace = context.processorNss[prefix]
                        else:
                            namespace = EMPTY_NAMESPACE
                    self.pushStringResult()
                    try:
                        for child in node.childNodes:
                            context = self.visit(context, child, preserveSpace)
                    finally:
                        result = self.popResult()

                    self.writers[-1].attribute(name, result, namespace)
                    context.processorNss = oldNss
                elif node.localName == 'append':
                    select = node.getAttributeNS(EMPTY_NAMESPACE, u'select')
                    if not select:
                        raise XUpdateException(XUpdateException.NO_SELECT)
                    _select = self.parseExpression(select)

                    child = node.getAttributeNS(EMPTY_NAMESPACE,
                                                u'child') or u'last()'
                    _child = self.parseExpression(child)

                    oldNss = context.processorNss
                    context.processorNss = Domlette.GetAllNs(node)

                    nodeset = _select.evaluate(context)
                    if not nodeset:
                        raise XUpdateException(XUpdateException.INVALID_SELECT,
                                               select)
                    refnode = nodeset[0]
                    self.pushDomResult(refnode.ownerDocument)
                    try:
                        for child in node.childNodes:
                            context = self.visit(context, child, preserveSpace)
                    finally:
                        result = self.popResult()
                    size = len(refnode.childNodes)
                    con = Context.Context(refnode,
                                          1,
                                          size,
                                          processorNss={'xupdate': XUPDATE_NS})
                    # Python lists is 0-indexed counting, node-sets 1-indexed
                    position = int(
                        Conversions.NumberValue(_child.evaluate(con)))
                    if position >= size:
                        refnode.appendChild(result)
                    else:
                        refnode.insertBefore(result,
                                             refnode.childNodes[position])
                    context.processorNss = oldNss
                elif node.localName == 'replace':
                    select = node.getAttributeNS(EMPTY_NAMESPACE, u'select')
                    if not select:
                        raise XUpdateException(XUpdateException.NO_SELECT)
                    try:
                        _select = self.parseExpression(select)
                    except SyntaxError, e:
                        raise SyntaxError("Select Expression %s: %s" %
                                          (select, str(e)))

                    oldNss = context.processorNss
                    context.processorNss = Domlette.GetAllNs(node)

                    nodeset = _select.evaluate(context)
                    if not nodeset:
                        raise XUpdateException(
                            XUpdateException.INVALID_SELECT,
                            node.getAttributeNS(EMPTY_NAMESPACE, u'select'))
                    refnode = nodeset[0]

                    self.pushDomResult(refnode.ownerDocument)
                    try:
                        for child in node.childNodes:
                            context = self.visit(context, child, preserveSpace)
                    finally:
                        result = self.popResult()

                    if refnode.nodeType == Node.ATTRIBUTE_NODE:
                        owner = refnode.parentNode
                        owner.removeAttributeNode(refnode)
                        owner.setAttributeNodeNS(result)
                    else:
                        refnode.parentNode.replaceChild(result, refnode)

                    context.processorNss = oldNss
                elif node.localName == 'update':
                    select = node.getAttributeNS(EMPTY_NAMESPACE, u'select')
                    if not select:
                        raise XUpdateException(XUpdateException.NO_SELECT)
                    try:
                        _select = self.parseExpression(select)
                    except SyntaxError, e:
                        raise SyntaxError("Select Expression %s: %s" %
                                          (select, str(e)))

                    oldNss = context.processorNss
                    context.processorNss = Domlette.GetAllNs(node)

                    nodeset = _select.evaluate(context)
                    if not nodeset:
                        raise XUpdateException(
                            XUpdateException.INVALID_SELECT,
                            node.getAttributeNS(EMPTY_NAMESPACE, u'select'))
                    refnode = nodeset[0]

                    if refnode.nodeType == Node.ATTRIBUTE_NODE:
                        self.pushStringResult()
                        try:
                            for child in node.childNodes:
                                context = self.visit(context, child,
                                                     preserveSpace)
                        finally:
                            result = self.popResult()
                        refnode.nodeValue = refnode.value = result
                    else:
                        self.pushDomResult(refnode.ownerDocument)
                        try:
                            for child in node.childNodes:
                                context = self.visit(context, child,
                                                     preserveSpace)
                        finally:
                            result = self.popResult()

                        while refnode.firstChild:
                            #print 'remove', id(refnode), id(refnode.firstChild), len(refnode.childNodes)
                            refnode.removeChild(refnode.firstChild)

                        refnode.appendChild(result)

                    context.processorNss = oldNss
Beispiel #13
0
def Test(tester):

    tester.startGroup('Expression Parser')

    tester.startTest('Creating test environment')
    from Ft.Xml.XPath import Context
    DomTree = tester.test_data['tree']

    # not the root node, but the document element
    root = Context.Context(DomTree.ROOT,
                           1,
                           1,
                           varBindings={(None, 'foo'): [DomTree.ROOT]})
    child1 = Context.Context(DomTree.CHILD1,
                             1,
                             2,
                             processorNss={'x': 'http://spam.com'})
    child2 = Context.Context(DomTree.CHILD2, 2, 2)
    child3 = Context.Context(DomTree.CHILD3, 1, 1)
    text = Context.Context(DomTree.TEXT1, 3, 3)
    gchild11 = Context.Context(DomTree.GCHILD11, 1, 2)
    lang = Context.Context(DomTree.LANG, 1, 1)

    tests = [
        ('child::*', root, DomTree.CHILDREN),
        ('/child::*', child1, [DomTree.ROOT]),
        ('/*/*', child1, DomTree.CHILDREN),
        ('/child::*/*/child::GCHILD', child1,
         DomTree.GCHILDREN1 + DomTree.GCHILDREN2),
        ('//*', child1,
         ([DomTree.ROOT, DomTree.CHILD1] + DomTree.GCHILDREN1 +
          [DomTree.CHILD2] + DomTree.GCHILDREN2 + [DomTree.CHILD3] +
          [DomTree.LANG] + DomTree.LCHILDREN)),
        ('//GCHILD', child1, DomTree.GCHILDREN1 + DomTree.GCHILDREN2),
        ('//@attr1', child1, [DomTree.ATTR1, DomTree.ATTR2]),
        ('x:GCHILD', child1, []),
        ('.//GCHILD', child2, DomTree.GCHILDREN2),
        ('.//GCHILD', root, DomTree.GCHILDREN1 + DomTree.GCHILDREN2),
        ('/', text, [DomTree.DOM]),
        ('//CHILD1/..', child1, [DomTree.ROOT]),
        ('.//foo:*', child3, []),
        ('CHILD1 | CHILD2', root, [DomTree.CHILD1, DomTree.CHILD2]),
        ('descendant::GCHILD[3]', root, [DomTree.GCHILD21]),
        ('descendant::GCHILD[parent::CHILD1]', root, DomTree.GCHILDREN1),
        ('descendant::GCHILD[position() > 1]', root,
         [DomTree.GCHILD12] + DomTree.GCHILDREN2),
        ('@attr1[.="val1"]', child1, [DomTree.ATTR1]),
        ('1', root, 1),
        ('00200', root, 200),
        ('3+4*7', root, 31),
        ('3-4*1', root, -1),
        ("string('1')", root, u"1"),
        ("concat('1', '2')", root, u"12"),
        ("true()", root, boolean.true),
        ("false()", root, boolean.false),
        ("1=3<4", root, boolean.true),
        ("1 or 2 and 3", root, boolean.true),
        ("1 and 2 = 3", root, boolean.false),
        ('-1 or 2', root, boolean.true),
        ('. or *', root, boolean.true),
        ("$foo[1]", root, [DomTree.ROOT]),
        ("text()", child3, []),
        ("processing-instruction('f')", root, []),
        ("$foo[1]/bar", root, []),
        ("$foo[1]//bar", root, []),
        ("$foo[1][3]", root, []),
        ('(child::*)', root, DomTree.CHILDREN),
        ('. * 0', root, nan),
        ('.. * 0', root, nan),
        ('/.. * 0', root, nan),
        ('CHILD2/@CODE', root, [DomTree.IDATTR2]),
        ('CHILD2/@CODE * 0', root, 0),
        (u'f\xf6\xf8', lang, [DomTree.NONASCIIQNAME]),
    ]
    tester.testDone()

    for (expr_str, context, expected) in tests:
        fromHere = context.node.nodeName
        tester.startTest('Evaluation of %r' % expr_str)
        message = 'Error while evaluating "%r" from <%r>' % (expr_str,
                                                             fromHere)
        for factory in _parsers:
            parser = factory.new()
            try:
                parsed_expr = parser.parse(expr_str)
            except:
                tester.error('Error while parsing "%r"' % expr_str,
                             traceLimit=None)
        node_set = parsed_expr.evaluate(context)
        tester.compare(expected, node_set, message)
        tester.testDone()

    tester.startTest("Syntax Exception")
    for factory in _parsers:
        parser = factory.new()
        tester.testException(parser.parse, ("\\", ), SyntaxError)
    tester.testDone()

    tester.startTest("Compiletime Exception")
    tester.testException(Compile, ("\\", ), CompiletimeException)
    tester.testDone()

    tester.startTest("Runtime Exception")
    tester.testException(Evaluate, ("$foo", DomTree.ROOT), RuntimeException)
    tester.testDone()

    return tester.groupDone()
def Test(tester):

    tester.startGroup('Node Tests')

    tester.startTest('Creating test environment')
    from Ft.Xml.XPath.ParsedNodeTest import ParsedNodeTest, ParsedNameTest
    from Ft.Xml.XPath import Context, Conversions
    from Ft.Lib.boolean import true, false

    DomTree = tester.test_data['tree']

    context = Context.Context(DomTree.ROOT, 1, 1, {},
                              {'bar': 'http://foo.com'})
    tests = [
        (ParsedNameTest('*'), [(DomTree.ROOT, true)]),
        (ParsedNameTest('bar:CHILD3'), [
            (DomTree.ROOT, false),
            (DomTree.CHILD1, false),
            (DomTree.CHILD3, true),
        ]),
        (ParsedNameTest('bar:*'), [
            (DomTree.ROOT, false),
            (DomTree.CHILD1, false),
            (DomTree.CHILD3, true),
        ]),
        (ParsedNodeTest('node'), [
            (DomTree.ROOT, true),
            (DomTree.TEXT1, true),
        ]),
        (ParsedNodeTest('text'), [
            (DomTree.ROOT, false),
            (DomTree.TEXT1, true),
        ]),
        (ParsedNodeTest('comment'), [
            (DomTree.ROOT, false),
            (DomTree.COMMENT, true),
        ]),
        (ParsedNodeTest('processing-instruction'), [
            (DomTree.ROOT, false),
            (DomTree.PI, true),
        ]),
        (ParsedNodeTest('processing-instruction', "'xml-stylesheet'"), [
            (DomTree.PI, true),
            (DomTree.PI2, false),
        ]),
    ]

    tester.testDone()

    for nt, nodeTests in tests:
        tester.startTest('Running %s' % repr(nt))
        for node, expected in nodeTests:
            # Use Booleans for display only
            result = Conversions.BooleanValue(nt.match(context, node))
            tester.compare(
                expected, result, 'Filter of "%s" against %s' % (
                    repr(nt),
                    node.nodeName,
                ))
        tester.testDone()

    return tester.groupDone()
Beispiel #15
0
def Test(tester):

    tester.startGroup('Steps')
    
    tester.startTest('Checking syntax')
    DomTree = tester.test_data['tree']
    from Ft.Xml.XPath import ParsedStep
    from Ft.Xml.XPath import ParsedNodeTest
    from Ft.Xml.XPath import ParsedExpr
    from Ft.Xml.XPath import ParsedPredicateList
    from Ft.Xml.XPath import ParsedAxisSpecifier
    from Ft.Xml.XPath import Context
    tester.testDone()
    
    tester.startTest('Creating test environment')
    rootContext = Context.Context(DomTree.ROOT,1,1)
    context = child1Context = Context.Context(DomTree.CHILD1,1,3)
    child2Context = Context.Context(DomTree.CHILD2,2,3)
    textContext = Context.Context(DomTree.TEXT1,3,3)
    
    tests = []

    # Test 1
    as = ParsedAxisSpecifier.ParsedAxisSpecifier('ancestor')
    nt = ParsedNodeTest.ParsedNameTest('*')
    s = ParsedStep.ParsedStep(as, nt)
    tests.append((s, [DomTree.ROOT]))
    
    # Test 2
    as = ParsedAxisSpecifier.ParsedAxisSpecifier('ancestor-or-self')
    s = ParsedStep.ParsedStep(as, nt, None)
    tests.append((s, [DomTree.ROOT, DomTree.CHILD1]))

    # Test 3
    as = ParsedAxisSpecifier.ParsedAxisSpecifier('descendant-or-self')
    nt = ParsedNodeTest.ParsedNameTest('GCHILD')
    s = ParsedStep.ParsedStep(as, nt)
    tests.append((s, DomTree.GCHILDREN1))
    
    # Test 4
    as = ParsedAxisSpecifier.ParsedAxisSpecifier('child')
    nt = ParsedNodeTest.ParsedNameTest('GCHILD')
    left = ParsedExpr.ParsedFunctionCallExpr('position', [])
    right = ParsedExpr.ParsedNLiteralExpr('1')
    exp = ParsedExpr.ParsedEqualityExpr('=', left, right)
    pl = ParsedPredicateList.ParsedPredicateList([exp])
    s = ParsedStep.ParsedStep(as, nt, pl)
    tests.append((s, [DomTree.GCHILD11]))

    # Test 5
    right = ParsedExpr.ParsedNLiteralExpr('1')
    pl = ParsedPredicateList.ParsedPredicateList([right])
    as = ParsedAxisSpecifier.ParsedAxisSpecifier('child')
    nt = ParsedNodeTest.ParsedNameTest('GCHILD')
    s = ParsedStep.ParsedStep(as,nt,pl)
    tests.append((s, [DomTree.GCHILD11]))
    
    tester.testDone()

    for step,expected in tests:
        tester.startTest('Select "%s"' % repr(step))
        node_set = step.select(context)
        if len(node_set) != len(expected):
            tester.error('Wrong size of node set. Expected %d, got %d' % (
                len(expected),
                len(node_set)
                ))
        results = map(lambda a,b: a == b, node_set, expected)
        if not reduce(lambda a,b: a and b, results, 1):
            tester.error('Invalid node in node set. Expected\n%s\ngot\n%s' % (
                str(expected),
                str(node_set),
                ))
        tester.testDone()
   

    return tester.groupDone()
def Test(tester):

    tester.startGroup('Core Function Library')

    tester.startTest('Creating test environment')

    from Ft.Lib import boolean, number
    from Ft.Xml import XPath
    from Ft.Xml.XPath import ParsedExpr, Context
    from Ft.Xml.XPath import XPathTypes as Types

    DomTree = tester.test_data['tree']
    context1 = Context.Context(DomTree.CHILD1, 1, 3)
    context2 = Context.Context(DomTree.CHILD2, 2, 3)
    contextLang1 = Context.Context(DomTree.LCHILD1, 1, 1)
    contextLang2 = Context.Context(DomTree.LCHILD2, 1, 1)

    import DummyExpr
    from DummyExpr import boolT, boolF
    from DummyExpr import num0, num0p5, numN0p5, num1, num1p5, num2, num2p6, num3, numN4, num4p5
    from DummyExpr import numN4p5, numN42, numInf, numNInf, numNan
    from DummyExpr import str12345, strPi, strText, strPiText, strSpace, strHelloWorld, strEmpty
    from DummyExpr import ONE_NODE_SET_DOC2, TWO_NODE_SET_DOC2, THREE_NODE_SET_DOC2, FOUR_NODE_SET_DOC2

    nodeset0 = DummyExpr.DummyNodeSetExpr([])
    nodeset1 = DummyExpr.DummyNodeSetExpr([DomTree.ROOT])
    nodeset2 = DummyExpr.DummyNodeSetExpr([DomTree.ROOT, DomTree.CHILD1])
    nodeset3 = DummyExpr.DummyNodeSetExpr([DomTree.CHILD1])
    nodeset4 = DummyExpr.DummyNodeSetExpr([DomTree.CHILD3])

    strNodeset3 = '\n    \n    \n    Text1\n  '

    # a,b,c,d,e,f,g become A,B,C,D,E,F,G
    translateFrom1 = DummyExpr.DummyStringExpr('abcdefg')
    translateTo1 = DummyExpr.DummyStringExpr('ABCDEFG')
    # e becomes a
    translateFrom2 = DummyExpr.DummyStringExpr('e')
    translateTo2 = DummyExpr.DummyStringExpr('a')
    # e becomes a; extra chars in To string are ignored
    translateFrom3 = DummyExpr.DummyStringExpr('e')
    translateTo3 = DummyExpr.DummyStringExpr('abc')
    # e becomes a; l is deleted
    translateFrom4 = DummyExpr.DummyStringExpr('el')
    translateTo4 = DummyExpr.DummyStringExpr('a')
    # a,b,c,d,e,f,g become A,B,C,D,E,F,G;
    # repeated chars in From string are ignored
    translateFrom5 = DummyExpr.DummyStringExpr('abcdefgabc')
    translateTo5 = DummyExpr.DummyStringExpr('ABCDEFG123')
    translateFrom6 = DummyExpr.DummyStringExpr('abcdefghhe')
    translateTo6 = DummyExpr.DummyStringExpr('ABCDEFGH')
    translateFrom7 = DummyExpr.DummyStringExpr('abcdefgh')
    translateTo7 = DummyExpr.DummyStringExpr('')

    tests = [
        ('last', [], context1, 3),
        ('last', [], context2, 3),
        ('position', [], context1, 1),
        ('position', [], context2, 2),
        ('count', [nodeset2], context1, 2),
        ('id', [num1], context1, [DomTree.CHILD2]),
        ('id', [DummyExpr.DummyStringExpr('1 1')], context1, [DomTree.CHILD2]),
        ('id', [DummyExpr.DummyStringExpr('0')], context1, []),
        ('id', [DummyExpr.DummyStringExpr('0 1')], context1, [DomTree.CHILD2]),
        ('id', [DummyExpr.DummyStringExpr('0 1 1')], context1,
         [DomTree.CHILD2]),
        ('id', [DummyExpr.DummyStringExpr('0 0 1 1')], context1,
         [DomTree.CHILD2]),
        ('id', [ONE_NODE_SET_DOC2], context1, []),
        ('id', [TWO_NODE_SET_DOC2], context1, [DomTree.CHILD2]),
        ('id', [THREE_NODE_SET_DOC2], context1, [DomTree.CHILD2]),
        ('id', [FOUR_NODE_SET_DOC2], context1, [DomTree.CHILD2]),
        ('local-name', [nodeset0], context1, ''),
        ('local-name', [nodeset4], context1, 'CHILD3'),
        ('namespace-uri', [nodeset0], context1, ''),
        ('namespace-uri', [nodeset4], context1, u'http://foo.com'),
        ('name', [nodeset4], context1, 'foo:CHILD3'),
        ('string', [nodeset3], context1, strNodeset3),
        ('concat', [nodeset3, strPi,
                    strText], context1, strNodeset3 + u'3.14Hi'),
        ('starts-with', [nodeset3, strPi], context1, boolean.false),
        ('starts-with', [nodeset3, nodeset3], context1, boolean.true),
        ('starts-with', [nodeset3, strEmpty], context1, boolean.true),
        ('contains', [nodeset3, strPi], context1, boolean.false),
        ('contains', [nodeset3, nodeset3], context1, boolean.true),
        ('contains', [nodeset3, strEmpty], context1, boolean.true),
        ('substring-before', [strPiText, strText], context1, u'3.14'),
        ('substring-before', [strPiText, strEmpty], context1, u''),
        ('substring-after', [strPiText, strPi], context1, u'Hi'),
        ('substring-after', [strPiText, strEmpty], context1, u''),
        ('substring', [strPiText, strPi], context1, u'14Hi'),
        ('substring', [strPiText, strPi, num1], context1, u'1'),
        ('substring', [str12345, num2, num3], context1, u'234'),
        ('substring', [str12345, num2], context1, u'2345'),
        ('substring', [str12345, num1p5, num2p6], context1, u'234'),
        ('substring', [str12345, num0, num3], context1, u'12'),
        ('substring', [str12345, numNan, num3], context1, u''),
        ('substring', [str12345, num1, numNan], context1, u''),
        ('substring', [str12345, numN42, numInf], context1, u'12345'),
        ('substring', [str12345, numNInf, numInf], context1, u''),
        ('string-length', [strPiText], context1, 6),
        ('normalize-space', [strSpace], context1, u'Ht There Mike'),
        ('translate', [strSpace, translateFrom1,
                       translateTo1], context1, u'Ht    \t ThErE\t   MikE'),
        ('translate', [strHelloWorld, translateFrom2,
                       translateTo2], context1, u'hallo world'),
        ('translate', [strHelloWorld, translateFrom3,
                       translateTo3], context1, u'hallo world'),
        ('translate', [strHelloWorld, translateFrom4,
                       translateTo4], context1, u'hao word'),
        ('translate', [strHelloWorld, translateFrom5,
                       translateTo5], context1, u'hEllo worlD'),
        ('translate', [strHelloWorld, translateFrom6,
                       translateTo6], context1, u'HEllo worlD'),
        ('translate', [strHelloWorld, translateFrom7,
                       translateTo7], context1, u'llo worl'),
        ('boolean', [strPiText], context1, boolean.true),
        ('not', [strPiText], context1, boolean.false),
        ('true', [], context1, boolean.true),
        ('false', [], context1, boolean.false),
        ('number', [], context1, number.nan),
        ('floor', [strPi], context1, 3),
        ('floor', [numNan], context1, number.nan),
        ('floor', [numInf], context1, number.inf),
        ('floor', [numNInf], context1, -number.inf),
        ('floor', [num0p5], context1, 0),
        ('floor', [numN0p5], context1, -1),
        ('ceiling', [strPi], context1, 4),
        ('ceiling', [numNan], context1, number.nan),
        ('ceiling', [numInf], context1, number.inf),
        ('ceiling', [num0p5], context1, 1),
        ('ceiling', [numN0p5], context1,
         0),  # actually should be negative zero
        ('round', [strPi], context1, 3),
        ('round', [numN4p5], context1, -4),
        ('round', [numNan], context1, number.nan),
        ('round', [numInf], context1, number.inf),
        ('round', [numNInf], context1, -number.inf),
        ('round', [str12345], context1, 12345),
        ('lang', [DummyExpr.DummyStringExpr('en')], contextLang1,
         boolean.false),
        ('lang', [DummyExpr.DummyStringExpr('en')], contextLang2,
         boolean.true),
        ('lang', [DummyExpr.DummyStringExpr('')], contextLang1, boolean.true),
        ('lang', [DummyExpr.DummyStringExpr('')], contextLang2, boolean.false),
        ('lang', [DummyExpr.DummyStringExpr('foo')], contextLang1,
         boolean.false),
        ('lang', [DummyExpr.DummyStringExpr('foo')], contextLang2,
         boolean.false),
    ]

    typetests = [
        ('last', [], Types.NumberType),
        ('position', [], Types.NumberType),
        ('count', [nodeset0], Types.NumberType),
        ('id', [DummyExpr.DummyStringExpr('id1')], Types.NodesetType),
        ('local-name', [nodeset3], Types.StringType),
        ('namespace-uri', [nodeset3], Types.StringType),
        ('name', [nodeset3], Types.StringType),
        ('string', [nodeset3], Types.StringType),
        ('concat', [nodeset3,
                    DummyExpr.DummyStringExpr('foo')], Types.StringType),
        ('starts-with', [nodeset3,
                         DummyExpr.DummyStringExpr('foo')], Types.BooleanType),
        ('contains', [nodeset3,
                      DummyExpr.DummyStringExpr('foo')], Types.BooleanType),
        ('substring-before', [nodeset3,
                              DummyExpr.DummyStringExpr('foo')],
         Types.StringType),
        ('substring-after', [nodeset3,
                             DummyExpr.DummyStringExpr('foo')],
         Types.StringType),
        ('substring', [nodeset3,
                       DummyExpr.DummyStringExpr('foo')], Types.StringType),
        ('string-length', [DummyExpr.DummyStringExpr('foo')],
         Types.NumberType),
        ('normalize-space', [DummyExpr.DummyStringExpr('foo')],
         Types.StringType),
        ('translate', [
            DummyExpr.DummyStringExpr('foo'),
            DummyExpr.DummyStringExpr('f'),
            DummyExpr.DummyStringExpr('b')
        ], Types.StringType),
        ('boolean', [nodeset0], Types.BooleanType),
        ('not', [nodeset0], Types.BooleanType),
        ('true', [], Types.BooleanType),
        ('false', [], Types.BooleanType),
        ('lang', [DummyExpr.DummyStringExpr('en')], Types.BooleanType),
        ('number', [DummyExpr.DummyStringExpr('foo')], Types.NumberType),
        ('sum', [nodeset3], Types.NumberType),
        ('floor', [num4p5], Types.NumberType),
        ('ceiling', [num4p5], Types.NumberType),
        ('round', [num4p5], Types.NumberType),
    ]

    tester.testDone()

    tester.startGroup('Function evaluation')

    for (funcname, args, context, expected) in tests:
        p = ParsedExpr.ParsedFunctionCallExpr(funcname, args)
        tester.startTest('Evaluation of %s' % repr(p))
        result = p.evaluate(context)
        tester.compare(expected, result)
        tester.testDone()

    tester.groupDone()

    tester.startGroup('Evaluated function type')

    for (funcname, args, expected) in typetests:
        p = ParsedExpr.ParsedFunctionCallExpr(funcname, args)
        tester.startTest('%s()' % funcname)
        result = p.evaluate(context1)
        tester.compare(expected, type(result))
        tester.testDone()

    tester.groupDone()

    tester.groupDone()

    return
Beispiel #17
0
                    else:
                        _select = self.parseExpression(select)
                        oldNss = context.processorNss
                        context.processorNss = Domlette.GetAllNs(node)

                        nodeset = _select.evaluate(context)
                        if not nodeset:
                            raise XUpdateException(
                                XUpdateException.INVALID_SELECT, select)
                        templateNode = nodeset[0]
                        context.processorNss = oldNss

                    t_nss, t_node, t_preserveSpace = self.templates[name]
                    t_context = Context.Context(
                        templateNode,
                        varBindings=context.varBindings,
                        extFunctionMap=context.functions,
                        processorNss=t_nss)
                    for n in t_node.childNodes:
                        self.visit(t_context, n, t_preserveSpace)
                elif node.localName == 'for-each':
                    select = node.getAttributeNS(EMPTY_NAMESPACE, u'select')
                    if not select:
                        raise XUpdateException(XUpdateException.NO_SELECT)
                    try:
                        _select = self.parseExpression(select)
                    except SyntaxError, e:
                        raise SyntaxError("Select Expression %s: %s" %
                                          (select, str(e)))

                    oldNss = context.processorNss