Пример #1
0
String stringValue(Node* node)
{
    switch (node->nodeType()) {
        case Node::ATTRIBUTE_NODE:
        case Node::PROCESSING_INSTRUCTION_NODE:
        case Node::COMMENT_NODE:
        case Node::TEXT_NODE:
        case Node::CDATA_SECTION_NODE:
        case Node::XPATH_NAMESPACE_NODE:
            return node->nodeValue();
        default:
            if (isRootDomNode(node) || node->nodeType() == Node::ELEMENT_NODE) {
                StringBuilder result;
                result.reserveCapacity(1024);

                for (Node* n = node->firstChild(); n; n = NodeTraversal::next(*n, node)) {
                    if (n->isTextNode()) {
                        const String& nodeValue = n->nodeValue();
                        result.append(nodeValue);
                    }
                }

                return result.toString();
            }
    }

    return String();
}
Пример #2
0
String stringValue(Node* node)
{
    switch (node->nodeType()) {
        case Node::ATTRIBUTE_NODE:
        case Node::PROCESSING_INSTRUCTION_NODE:
        case Node::COMMENT_NODE:
        case Node::TEXT_NODE:
        case Node::CDATA_SECTION_NODE:
        case Node::XPATH_NAMESPACE_NODE:
            return node->nodeValue();
        default:
            if (isRootDomNode(node) || node->nodeType() == Node::ELEMENT_NODE)
                return TextNodeTraversal::contentsAsString(node);
    }
    return String();
}
Пример #3
0
// Result nodes are ordered in axis order. Node test (including merged predicates) is applied.
void Step::nodesInAxis(Node* context, NodeSet& nodes) const
{
    ASSERT(nodes.isEmpty());
    switch (m_axis) {
        case ChildAxis:
            if (context->isAttributeNode()) // In XPath model, attribute nodes do not have children.
                return;

            for (Node* n = context->firstChild(); n; n = n->nextSibling())
                if (nodeMatches(n, ChildAxis, m_nodeTest))
                    nodes.append(n);
            return;
        case DescendantAxis:
            if (context->isAttributeNode()) // In XPath model, attribute nodes do not have children.
                return;

            for (Node* n = context->firstChild(); n; n = NodeTraversal::next(*n, context))
                if (nodeMatches(n, DescendantAxis, m_nodeTest))
                    nodes.append(n);
            return;
        case ParentAxis:
            if (context->isAttributeNode()) {
                Element* n = toAttr(context)->ownerElement();
                if (nodeMatches(n, ParentAxis, m_nodeTest))
                    nodes.append(n);
            } else {
                ContainerNode* n = context->parentNode();
                if (n && nodeMatches(n, ParentAxis, m_nodeTest))
                    nodes.append(n);
            }
            return;
        case AncestorAxis: {
            Node* n = context;
            if (context->isAttributeNode()) {
                n = toAttr(context)->ownerElement();
                if (nodeMatches(n, AncestorAxis, m_nodeTest))
                    nodes.append(n);
            }
            for (n = n->parentNode(); n; n = n->parentNode())
                if (nodeMatches(n, AncestorAxis, m_nodeTest))
                    nodes.append(n);
            nodes.markSorted(false);
            return;
        }
        case FollowingSiblingAxis:
            if (context->nodeType() == Node::ATTRIBUTE_NODE ||
                 context->nodeType() == Node::XPATH_NAMESPACE_NODE)
                return;

            for (Node* n = context->nextSibling(); n; n = n->nextSibling())
                if (nodeMatches(n, FollowingSiblingAxis, m_nodeTest))
                    nodes.append(n);
            return;
        case PrecedingSiblingAxis:
            if (context->nodeType() == Node::ATTRIBUTE_NODE ||
                 context->nodeType() == Node::XPATH_NAMESPACE_NODE)
                return;

            for (Node* n = context->previousSibling(); n; n = n->previousSibling())
                if (nodeMatches(n, PrecedingSiblingAxis, m_nodeTest))
                    nodes.append(n);

            nodes.markSorted(false);
            return;
        case FollowingAxis:
            if (context->isAttributeNode()) {
                Node* p = toAttr(context)->ownerElement();
                while ((p = NodeTraversal::next(*p))) {
                    if (nodeMatches(p, FollowingAxis, m_nodeTest))
                        nodes.append(p);
                }
            } else {
                for (Node* p = context; !isRootDomNode(p); p = p->parentNode()) {
                    for (Node* n = p->nextSibling(); n; n = n->nextSibling()) {
                        if (nodeMatches(n, FollowingAxis, m_nodeTest))
                            nodes.append(n);
                        for (Node* c = n->firstChild(); c; c = NodeTraversal::next(*c, n))
                            if (nodeMatches(c, FollowingAxis, m_nodeTest))
                                nodes.append(c);
                    }
                }
            }
            return;
        case PrecedingAxis: {
            if (context->isAttributeNode())
                context = toAttr(context)->ownerElement();

            Node* n = context;
            while (ContainerNode* parent = n->parentNode()) {
                for (n = NodeTraversal::previous(*n); n != parent; n = NodeTraversal::previous(*n))
                    if (nodeMatches(n, PrecedingAxis, m_nodeTest))
                        nodes.append(n);
                n = parent;
            }
            nodes.markSorted(false);
            return;
        }
        case AttributeAxis: {
            if (!context->isElementNode())
                return;

            Element* contextElement = toElement(context);

            // Avoid lazily creating attribute nodes for attributes that we do not need anyway.
            if (m_nodeTest.kind() == NodeTest::NameTest && m_nodeTest.data() != starAtom) {
                RefPtr<Node> n = contextElement->getAttributeNodeNS(m_nodeTest.namespaceURI(), m_nodeTest.data());
                if (n && n->namespaceURI() != XMLNSNames::xmlnsNamespaceURI) { // In XPath land, namespace nodes are not accessible on the attribute axis.
                    if (nodeMatches(n.get(), AttributeAxis, m_nodeTest)) // Still need to check merged predicates.
                        nodes.append(n.release());
                }
                return;
            }

            if (!contextElement->hasAttributes())
                return;

            for (unsigned i = 0; i < contextElement->attributeCount(); ++i) {
                RefPtr<Attr> attr = contextElement->ensureAttr(contextElement->attributeItem(i)->name());
                if (nodeMatches(attr.get(), AttributeAxis, m_nodeTest))
                    nodes.append(attr.release());
            }
            return;
        }
        case NamespaceAxis:
            // XPath namespace nodes are not implemented yet.
            return;
        case SelfAxis:
            if (nodeMatches(context, SelfAxis, m_nodeTest))
                nodes.append(context);
            return;
        case DescendantOrSelfAxis:
            if (nodeMatches(context, DescendantOrSelfAxis, m_nodeTest))
                nodes.append(context);
            if (context->isAttributeNode()) // In XPath model, attribute nodes do not have children.
                return;

            for (Node* n = context->firstChild(); n; n = NodeTraversal::next(*n, context))
            if (nodeMatches(n, DescendantOrSelfAxis, m_nodeTest))
                nodes.append(n);
            return;
        case AncestorOrSelfAxis: {
            if (nodeMatches(context, AncestorOrSelfAxis, m_nodeTest))
                nodes.append(context);
            Node* n = context;
            if (context->isAttributeNode()) {
                n = toAttr(context)->ownerElement();
                if (nodeMatches(n, AncestorOrSelfAxis, m_nodeTest))
                    nodes.append(n);
            }
            for (n = n->parentNode(); n; n = n->parentNode())
                if (nodeMatches(n, AncestorOrSelfAxis, m_nodeTest))
                    nodes.append(n);

            nodes.markSorted(false);
            return;
        }
    }
    ASSERT_NOT_REACHED();
}
Пример #4
0
// Result nodes are ordered in axis order. Node test (including merged
// predicates) is applied.
void Step::nodesInAxis(EvaluationContext& evaluationContext, Node* context, NodeSet& nodes) const
{
    ASSERT(nodes.isEmpty());
    switch (m_axis) {
    case ChildAxis:
        // In XPath model, attribute nodes do not have children.
        if (context->isAttributeNode())
            return;

        for (Node* n = context->firstChild(); n; n = n->nextSibling()) {
            if (nodeMatches(evaluationContext, n, ChildAxis, nodeTest()))
                nodes.append(n);
        }
        return;

    case DescendantAxis:
        // In XPath model, attribute nodes do not have children.
        if (context->isAttributeNode())
            return;

        for (Node* n = context->firstChild(); n; n = NodeTraversal::next(*n, context)) {
            if (nodeMatches(evaluationContext, n, DescendantAxis, nodeTest()))
                nodes.append(n);
        }
        return;

    case ParentAxis:
        if (context->isAttributeNode()) {
            Element* n = toAttr(context)->ownerElement();
            if (nodeMatches(evaluationContext, n, ParentAxis, nodeTest()))
                nodes.append(n);
        } else {
            ContainerNode* n = context->parentNode();
            if (n && nodeMatches(evaluationContext, n, ParentAxis, nodeTest()))
                nodes.append(n);
        }
        return;

    case AncestorAxis: {
        Node* n = context;
        if (context->isAttributeNode()) {
            n = toAttr(context)->ownerElement();
            if (nodeMatches(evaluationContext, n, AncestorAxis, nodeTest()))
                nodes.append(n);
        }
        for (n = n->parentNode(); n; n = n->parentNode()) {
            if (nodeMatches(evaluationContext, n, AncestorAxis, nodeTest()))
                nodes.append(n);
        }
        nodes.markSorted(false);
        return;
    }

    case FollowingSiblingAxis:
        if (context->nodeType() == Node::ATTRIBUTE_NODE)
            return;

        for (Node* n = context->nextSibling(); n; n = n->nextSibling()) {
            if (nodeMatches(evaluationContext, n, FollowingSiblingAxis, nodeTest()))
                nodes.append(n);
        }
        return;

    case PrecedingSiblingAxis:
        if (context->nodeType() == Node::ATTRIBUTE_NODE)
            return;

        for (Node* n = context->previousSibling(); n; n = n->previousSibling()) {
            if (nodeMatches(evaluationContext, n, PrecedingSiblingAxis, nodeTest()))
                nodes.append(n);
        }
        nodes.markSorted(false);
        return;

    case FollowingAxis:
        if (context->isAttributeNode()) {
            for (Node* p = NodeTraversal::next(*toAttr(context)->ownerElement()); p; p = NodeTraversal::next(*p)) {
                if (nodeMatches(evaluationContext, p, FollowingAxis, nodeTest()))
                    nodes.append(p);
            }
        } else {
            for (Node* p = context; !isRootDomNode(p); p = p->parentNode()) {
                for (Node* n = p->nextSibling(); n; n = n->nextSibling()) {
                    if (nodeMatches(evaluationContext, n, FollowingAxis, nodeTest()))
                        nodes.append(n);
                    for (Node* c = n->firstChild(); c; c = NodeTraversal::next(*c, n)) {
                        if (nodeMatches(evaluationContext, c, FollowingAxis, nodeTest()))
                            nodes.append(c);
                    }
                }
            }
        }
        return;

    case PrecedingAxis: {
        if (context->isAttributeNode())
            context = toAttr(context)->ownerElement();

        Node* n = context;
        while (ContainerNode* parent = n->parentNode()) {
            for (n = NodeTraversal::previous(*n); n != parent; n = NodeTraversal::previous(*n)) {
                if (nodeMatches(evaluationContext, n, PrecedingAxis, nodeTest()))
                    nodes.append(n);
            }
            n = parent;
        }
        nodes.markSorted(false);
        return;
    }

    case AttributeAxis: {
        if (!context->isElementNode())
            return;

        Element* contextElement = toElement(context);
        // Avoid lazily creating attribute nodes for attributes that we do not
        // need anyway.
        if (nodeTest().kind() == NodeTest::NameTest && nodeTest().data() != starAtom) {
            RefPtrWillBeRawPtr<Node> n = contextElement->getAttributeNodeNS(nodeTest().namespaceURI(), nodeTest().data());
            // In XPath land, namespace nodes are not accessible on the attribute axis.
            if (n && n->namespaceURI() != XMLNSNames::xmlnsNamespaceURI) {
                // Still need to check merged predicates.
                if (nodeMatches(evaluationContext, n.get(), AttributeAxis, nodeTest()))
                    nodes.append(n.release());
            }
            return;
        }

        AttributeCollection attributes = contextElement->attributes();
        AttributeCollection::iterator end = attributes.end();
        for (AttributeCollection::iterator it = attributes.begin(); it != end; ++it) {
            RefPtrWillBeRawPtr<Attr> attr = contextElement->ensureAttr(it->name());
            if (nodeMatches(evaluationContext, attr.get(), AttributeAxis, nodeTest()))
                nodes.append(attr.release());
        }
        return;
    }

    case NamespaceAxis:
        // XPath namespace nodes are not implemented.
        return;

    case SelfAxis:
        if (nodeMatches(evaluationContext, context, SelfAxis, nodeTest()))
            nodes.append(context);
        return;

    case DescendantOrSelfAxis:
        if (nodeMatches(evaluationContext, context, DescendantOrSelfAxis, nodeTest()))
            nodes.append(context);
        // In XPath model, attribute nodes do not have children.
        if (context->isAttributeNode())
            return;

        for (Node* n = context->firstChild(); n; n = NodeTraversal::next(*n, context)) {
            if (nodeMatches(evaluationContext, n, DescendantOrSelfAxis, nodeTest()))
                nodes.append(n);
        }
        return;

    case AncestorOrSelfAxis: {
        if (nodeMatches(evaluationContext, context, AncestorOrSelfAxis, nodeTest()))
            nodes.append(context);
        Node* n = context;
        if (context->isAttributeNode()) {
            n = toAttr(context)->ownerElement();
            if (nodeMatches(evaluationContext, n, AncestorOrSelfAxis, nodeTest()))
                nodes.append(n);
        }
        for (n = n->parentNode(); n; n = n->parentNode()) {
            if (nodeMatches(evaluationContext, n, AncestorOrSelfAxis, nodeTest()))
                nodes.append(n);
        }
        nodes.markSorted(false);
        return;
    }
    }
    ASSERT_NOT_REACHED();
}
Пример #5
0
void Step::nodesInAxis(Node* context, NodeSet& nodes) const
{
    ASSERT(nodes.isEmpty());
    switch (m_axis) {
        case ChildAxis:
            if (context->isAttributeNode()) // In XPath model, attribute nodes do not have children.
                return;

            for (Node* n = context->firstChild(); n; n = n->nextSibling())
                if (nodeMatches(n))
                    nodes.append(n);
            return;
        case DescendantAxis:
            if (context->isAttributeNode()) // In XPath model, attribute nodes do not have children.
                return;

            for (Node* n = context->firstChild(); n; n = n->traverseNextNode(context))
                if (nodeMatches(n))
                    nodes.append(n);
            return;
        case ParentAxis:
            if (context->isAttributeNode()) {
                Node* n = static_cast<Attr*>(context)->ownerElement();
                if (nodeMatches(n))
                    nodes.append(n);
            } else {
                Node* n = context->parentNode();
                if (n && nodeMatches(n))
                    nodes.append(n);
            }
            return;
        case AncestorAxis: {
            Node* n = context;
            if (context->isAttributeNode()) {
                n = static_cast<Attr*>(context)->ownerElement();
                if (nodeMatches(n))
                    nodes.append(n);
            }
            for (n = n->parentNode(); n; n = n->parentNode())
                if (nodeMatches(n))
                    nodes.append(n);
            nodes.reverse();
            return;
        }
        case FollowingSiblingAxis:
            if (context->nodeType() == Node::ATTRIBUTE_NODE ||
                 context->nodeType() == Node::XPATH_NAMESPACE_NODE) 
                return;
            
            for (Node* n = context->nextSibling(); n; n = n->nextSibling())
                if (nodeMatches(n))
                    nodes.append(n);
            return;
        case PrecedingSiblingAxis:
            if (context->nodeType() == Node::ATTRIBUTE_NODE ||
                 context->nodeType() == Node::XPATH_NAMESPACE_NODE)
                return;
            
            for (Node* n = context->previousSibling(); n; n = n->previousSibling())
                if (nodeMatches(n))
                    nodes.append(n);

            nodes.reverse();
            return;
        case FollowingAxis:
            if (context->isAttributeNode()) {
                Node* p = static_cast<Attr*>(context)->ownerElement();
                while ((p = p->traverseNextNode()))
                    if (nodeMatches(p))
                        nodes.append(p);
            } else {
                for (Node* p = context; !isRootDomNode(p); p = p->parentNode()) {
                    for (Node* n = p->nextSibling(); n; n = n->nextSibling()) {
                        if (nodeMatches(n))
                            nodes.append(n);
                        for (Node* c = n->firstChild(); c; c = c->traverseNextNode(n))
                            if (nodeMatches(c))
                                nodes.append(c);
                    }
                }
            }
            return;
        case PrecedingAxis:
            if (context->isAttributeNode())
                context = static_cast<Attr*>(context)->ownerElement();

            for (Node* p = context; !isRootDomNode(p); p = p->parentNode()) {
                for (Node* n = p->previousSibling(); n ; n = n->previousSibling()) {
                    if (nodeMatches(n))
                        nodes.append(n);
                    for (Node* c = n->firstChild(); c; c = c->traverseNextNode(n))
                        if (nodeMatches(c))
                            nodes.append(c);
                }
            }
            nodes.markSorted(false);
            return;
        case AttributeAxis: {
            if (context->nodeType() != Node::ELEMENT_NODE)
                return;

            // Avoid lazily creating attribute nodes for attributes that we do not need anyway.
            if (m_nodeTest.kind() == NodeTest::NameTest && m_nodeTest.data() != "*") {
                RefPtr<Node> n = static_cast<Element*>(context)->getAttributeNodeNS(m_nodeTest.namespaceURI(), m_nodeTest.data());
                if (n && n->namespaceURI() != "http://www.w3.org/2000/xmlns/") // In XPath land, namespace nodes are not accessible on the attribute axis.
                    nodes.append(n.release());
                return;
            }
            
            NamedAttrMap* attrs = context->attributes();
            if (!attrs)
                return;

            for (unsigned long i = 0; i < attrs->length(); ++i) {
                RefPtr<Node> n = attrs->item(i);
                if (nodeMatches(n.get()))
                    nodes.append(n.release());
            }
            return;
        }
        case NamespaceAxis:
            // XPath namespace nodes are not implemented yet.
            return;
        case SelfAxis:
            if (nodeMatches(context))
                nodes.append(context);
            return;
        case DescendantOrSelfAxis:
            if (nodeMatches(context))
                nodes.append(context);
            if (context->isAttributeNode()) // In XPath model, attribute nodes do not have children.
                return;

            for (Node* n = context->firstChild(); n; n = n->traverseNextNode(context))
            if (nodeMatches(n))
                nodes.append(n);
            return;
        case AncestorOrSelfAxis: {
            if (nodeMatches(context))
                nodes.append(context);
            Node* n = context;
            if (context->isAttributeNode()) {
                n = static_cast<Attr*>(context)->ownerElement();
                if (nodeMatches(n))
                    nodes.append(n);
            }
            for (n = n->parentNode(); n; n = n->parentNode())
                if (nodeMatches(n))
                    nodes.append(n);

            nodes.reverse();
            return;
        }
    }
    ASSERT_NOT_REACHED();
}