コード例 #1
0
ファイル: XPathStep.cpp プロジェクト: Igalia/blink
// Evaluate NodeTest without considering merged predicates.
static inline bool nodeMatchesBasicTest(Node* node, Step::Axis axis, const Step::NodeTest& nodeTest)
{
    switch (nodeTest.kind()) {
        case Step::NodeTest::TextNodeTest:
            return node->nodeType() == Node::TEXT_NODE || node->nodeType() == Node::CDATA_SECTION_NODE;
        case Step::NodeTest::CommentNodeTest:
            return node->nodeType() == Node::COMMENT_NODE;
        case Step::NodeTest::ProcessingInstructionNodeTest: {
            const AtomicString& name = nodeTest.data();
            return node->nodeType() == Node::PROCESSING_INSTRUCTION_NODE && (name.isEmpty() || node->nodeName() == name);
        }
        case Step::NodeTest::AnyNodeTest:
            return true;
        case Step::NodeTest::NameTest: {
            const AtomicString& name = nodeTest.data();
            const AtomicString& namespaceURI = nodeTest.namespaceURI();

            if (axis == Step::AttributeAxis) {
                ASSERT(node->isAttributeNode());

                // In XPath land, namespace nodes are not accessible on the attribute axis.
                if (node->namespaceURI() == XMLNSNames::xmlnsNamespaceURI)
                    return false;

                if (name == starAtom)
                    return namespaceURI.isEmpty() || node->namespaceURI() == namespaceURI;

                return node->localName() == name && node->namespaceURI() == namespaceURI;
            }

            // Node test on the namespace axis is not implemented yet, the caller has a check for it.
            ASSERT(axis != Step::NamespaceAxis);

            // For other axes, the principal node type is element.
            ASSERT(primaryNodeType(axis) == Node::ELEMENT_NODE);
            if (node->nodeType() != Node::ELEMENT_NODE)
                return false;

            if (name == starAtom)
                return namespaceURI.isEmpty() || namespaceURI == node->namespaceURI();

            if (node->document().isHTMLDocument()) {
                if (node->isHTMLElement()) {
                    // Paths without namespaces should match HTML elements in HTML documents despite those having an XHTML namespace. Names are compared case-insensitively.
                    return equalIgnoringCase(toElement(node)->localName(), name) && (namespaceURI.isNull() || namespaceURI == node->namespaceURI());
                }
                // An expression without any prefix shouldn't match no-namespace nodes (because HTML5 says so).
                return toElement(node)->hasLocalName(name) && namespaceURI == node->namespaceURI() && !namespaceURI.isNull();
            }
            return toElement(node)->hasLocalName(name) && namespaceURI == node->namespaceURI();
        }
    }
    ASSERT_NOT_REACHED();
    return false;
}
コード例 #2
0
ファイル: XPathStep.cpp プロジェクト: FilipBE/qtextended
bool Step::nodeMatches(Node* node) const
{
    switch (m_nodeTest.kind()) {
        case NodeTest::TextNodeTest:
            return node->nodeType() == Node::TEXT_NODE || node->nodeType() == Node::CDATA_SECTION_NODE;
        case NodeTest::CommentNodeTest:
            return node->nodeType() == Node::COMMENT_NODE;
        case NodeTest::ProcessingInstructionNodeTest: {
            const String& name = m_nodeTest.data();
            return node->nodeType() == Node::PROCESSING_INSTRUCTION_NODE && (name.isEmpty() || node->nodeName() == name);
        }
        case NodeTest::ElementNodeTest:
            return node->isElementNode();
        case NodeTest::AnyNodeTest:
            return true;
        case NodeTest::NameTest: {
            const String& name = m_nodeTest.data();
            const String& namespaceURI = m_nodeTest.namespaceURI();

            if (m_axis == AttributeAxis) {
                ASSERT(node->isAttributeNode());

                // In XPath land, namespace nodes are not accessible on the attribute axis.
                if (node->namespaceURI() == "http://www.w3.org/2000/xmlns/")
                    return false;

                if (name == "*")
                    return namespaceURI.isEmpty() || node->namespaceURI() == namespaceURI;

                return node->localName() == name && node->namespaceURI() == namespaceURI;
            }

            if (m_axis == NamespaceAxis) {
                // Node test on the namespace axis is not implemented yet
                return false;
            }
            
            if (name == "*")
                return node->nodeType() == primaryNodeType(m_axis) && (namespaceURI.isEmpty() || namespaceURI == node->namespaceURI());

            // We use tagQName here because we don't want the element name in uppercase 
            // like we get with HTML elements.
            // Paths without namespaces should match HTML elements in HTML documents despite those having an XHTML namespace.
            return node->nodeType() == Node::ELEMENT_NODE
                    && static_cast<Element*>(node)->tagQName().localName() == name
                    && ((node->isHTMLElement() && node->document()->isHTMLDocument() && namespaceURI.isNull()) || namespaceURI == node->namespaceURI());
        }
    }
    ASSERT_NOT_REACHED();
    return false;
}