⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xpathexpression.cpp

📁 简单的xml解析类
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	{
		Array<DomNode*> results;
		for( int i = 0; i < search.getSize(); ++i ) {
			if( checkForMatch(search[i], item) /*match == "*" || match == search[i]->getName()*/ ) {
				results.append(search[i]);
			}

			Array<DomNode*> nodeResults;
			DomNode* parent = search[i]->getParent();
			while( parent != 0 && parent->getNodeType() == DomNode::ELEMENT ) {
				if( checkForMatch(parent, item) ) {
					nodeResults.append(parent);
				}
				parent = parent->getParent();
			}

			nodeResults = processPredicates(nodeResults, item);
			results += nodeResults;
		}
		return (results);
	}

	// ---------------------------------------------------------------------------------------------------------------------

	Array<DomNode*> XPathExpression::processAxisSelf( Array<DomNode*> search, xp_path_item& item )
	{
		Array<DomNode*> results = processPredicates(search, item);
		return (results);
	}

	// ---------------------------------------------------------------------------------------------------------------------

	Array<DomNode*> XPathExpression::processAxisAttribute( Array<DomNode*> search, xp_path_item& item )
	{
		Array<DomNode*> results;
		for( int i = 0; i < search.getSize(); ++i ) {
			Array<DomNode*> attribs = search[i]->getSubNodes(DomNode::ATTRIBUTE);

			if( item.m_node == "*" ) {
				results += attribs;
			}
			else {
				for( int iA = 0; iA < attribs.getSize(); ++iA ) {
					if( item.m_node == attribs[iA]->getName() ) {
						results.append(attribs[iA]);
						break;
					}
				}
			}
		}
		results = processPredicates(results, item);
		return (results);
	}

	// ---------------------------------------------------------------------------------------------------------------------
	
	Array<DomNode*> XPathExpression::processPredicates( Array<DomNode*> search, xp_path_item& item )
	{
		if( item.m_predicates.getSize() == 0 ) {
			return search;
		}

		Array<DomNode*> results;
		Array<DomNode*> wrkSearch = search.copy();
		Array<DomNode*> nxtSearch;

		for( int iP = 0; iP < item.m_predicates.getSize(); ++iP ) {
			for( int i = 0; i < wrkSearch.getSize(); ++i ) {
				XPathToken token = m_predicate->evaluate( item.m_predicates[iP], wrkSearch, wrkSearch[i]);
				if( token.getType() == XPathToken::NUMBER_INT || token.getType() == XPathToken::NUMBER_DBL ) {
					int idx = token.getValueNumberInt();
					if( idx == (i+1) ) {
						nxtSearch.append(wrkSearch[i]);
					}
				}
				else {
					if( token.getType() == XPathToken::NODESET ) {
						Array<DomNode*> nodes;
						if( token.getValueString().beginsWith("/") ) {
							nodes = token.getValueNodeSet(m_root);
						}
						else {
							nodes = token.getValueNodeSet(wrkSearch[i]);
						}
						if( nodes.getSize() > 0 ) {
							nxtSearch.append(wrkSearch[i]);
						}
					}
					else {
						if( token.isCompatibleWith(XPathToken::BOOLEAN) ) {
							if( token.getValueBool() ) {
								nxtSearch.append(wrkSearch[i]);
							}
						}
						else {
							return Array<DomNode*>();
						}
					}
				}
			}
			wrkSearch = nxtSearch;
			nxtSearch.clear();
		}

		return (wrkSearch);
	}

	// ---------------------------------------------------------------------------------------------------------------------

	bool XPathExpression::checkForMatch( DomNode* node, xp_path_item& item )
	{
		if( item.m_node == "node()" ) {
			return (true);
		}

		if( node->getNodeType() == DomNode::ELEMENT ) {
			if( item.m_node == "*" || item.m_node == node->getName() ) {
				return (true);
			}
		}
		else if( node->getNodeType() == DomNode::ATTRIBUTE && item.m_axis == AXIS_ATTRIBUTE ) {
			if( item.m_node == "*" || item.m_node == node->getName() ) {
				return (true);
			}
		}
		else {
			if( item.m_node == "text()" ) {
				if( node->getNodeType() == DomNode::TEXT || node->getNodeType() == DomNode::CDATA ) {
					return (true);
				}
			}
			else if( item.m_node == "comment()" ) {
				if( node->getNodeType() == DomNode::COMMENT ) {
					return (true);
				}
			}
			else if( item.m_node == "processing-instruction()" ) {
				if( node->getNodeType() == DomNode::PROC_INST ) {
					return (true);
				}
			}
		}
		return (false);
	}





	// ---------------------------------------------------------------------------------------------------------------------
	// ---------------------------------------------------------------------------------------------------------------------
	// ---------------------------------------------------------------------------------------------------------------------
	// ---------------------------------------------------------------------------------------------------------------------
	// ---------------------------------------------------------------------------------------------------------------------





	XPathToken::XPathToken() :m_type(STRING)
	{
	}

	// ---------------------------------------------------------------------------------------------------------------------

	XPathToken::XPathToken( String value, type_e type ) :m_value(value), m_type(type)
	{
	}

	// ---------------------------------------------------------------------------------------------------------------------

	XPathToken::XPathToken( String value ) :m_value(value), m_type(STRING)
	{
	}

	// ---------------------------------------------------------------------------------------------------------------------

	XPathToken::XPathToken( bool value ) :m_value(value? $("true"):$("false")), m_type(BOOLEAN)
	{
	}

	// ---------------------------------------------------------------------------------------------------------------------

	XPathToken::XPathToken( int value ) :m_value(String(value)), m_type(NUMBER_INT)
	{
	}

	// ---------------------------------------------------------------------------------------------------------------------

	XPathToken::XPathToken( double value ) :m_value(String(value)), m_type(NUMBER_DBL)
	{
	}

	// ---------------------------------------------------------------------------------------------------------------------

	String XPathToken::getValue( DomNode* context ) const
	{
		if( m_type == NODESET || (m_type == OPERATOR && m_value == "*") ) {
			Array<DomNode*> nodeset = getValueNodeSet(context);
			if( nodeset.getSize() > 0 ) {
				return nodeset[0]->getValue();
			}
			return (String::null);
		}

		return (m_value);
	}

	// ---------------------------------------------------------------------------------------------------------------------

	XPathToken::type_e XPathToken::getType() const
	{
		return (m_type);
	}

	// ---------------------------------------------------------------------------------------------------------------------

	String XPathToken::getValueString() const
	{
		return (m_value);
	}

	// ---------------------------------------------------------------------------------------------------------------------

	bool XPathToken::getValueBool() const
	{
		switch(m_type)
		{
		case BOOLEAN:
			return (m_value == "true");

		case STRING:
			return (m_value != String::null);

		case NUMBER_INT:
		case NUMBER_DBL:
			return (m_value.getAsDouble() != 0.0);
		}

		throw XPathException($("Cannot convert value to boolean"));
	}

	// ---------------------------------------------------------------------------------------------------------------------

	int XPathToken::getValueNumberInt() const
	{
		switch(m_type)
		{
		case NUMBER_INT:
		case NUMBER_DBL:
		case STRING:
			return ((int)m_value.getAsDouble());

		case BOOLEAN:
			return (m_value == "true" ? 1 : 0);
		}

		throw XPathException($("Cannot convert value to integer"));
	}

	// ---------------------------------------------------------------------------------------------------------------------

	double XPathToken::getValueNumberDouble() const
	{
		switch(m_type)
		{
		case NUMBER_INT:
		case NUMBER_DBL:
		case STRING:
			return ((double)m_value.getAsDouble());

		case BOOLEAN:
			return (m_value == "true" ? 1.0 : 0.0);
		}

		throw XPathException($("Cannot convert value to double"));
	}

	// ---------------------------------------------------------------------------------------------------------------------

	Array<DomNode*> XPathToken::getValueNodeSet( DomNode* context ) const
	{
		if( m_type == NODESET || (m_type == OPERATOR && m_value == "*")) {
			XPathExpression expr;
			expr.setRootNode(context);
			return expr.findNodes(m_value.beginsWith("/") ? m_value : "/" + m_value);
		}

		throw XPathException($("Cannot convert value to nodeset"));
	}

	// ---------------------------------------------------------------------------------------------------------------------

	bool XPathToken::isCompatibleWith( type_e type ) const
	{
		if( type == m_type ) {
			return (true);
		}

		switch(type)
		{
		case STRING:
			return (true);

		case NUMBER_INT:
		case NUMBER_DBL:
			return m_value.isValidDouble();

		case BOOLEAN:
			switch(m_type)
			{
			case NUMBER_INT:
			case NUMBER_DBL:
			case NODESET:
				return (true);

			case STRING:
				return (m_value == "true" || m_value == "false");
			}
			break;

		case NODESET:
			return (m_type == BOOLEAN || m_type == STRING || (m_type == OPERATOR && m_value == "*"));
		}

		return (false);
	}




	// ---------------------------------------------------------------------------------------------------------------------
	// ---------------------------------------------------------------------------------------------------------------------
	// ---------------------------------------------------------------------------------------------------------------------
	// ---------------------------------------------------------------------------------------------------------------------
	// ---------------------------------------------------------------------------------------------------------------------





	XPathFunction::XPathFunction( String name, int parmCount ) :m_name(name), m_parmCount(parmCount)
	{
	}

	// ---------------------------------------------------------------------------------------------------------------------

	String XPathFunction::getName() const
	{
		return (m_name);
	}

	// ---------------------------------------------------------------------------------------------------------------------

	int XPathFunction::getParmCount() const
	{
		return (m_parmCount);
	}

	// ---------------------------------------------------------------------------------------------------------------------

	void XPathFunction::validateParm( XPathToken& parm, XPathToken::type_e type )
	{
		if( !parm.isCompatibleWith(type) ) {
			throw XPathException("Invalid parameter passed to " + m_name + ": '" + parm.getValueString() + "'");
		}
	}


}}}	// namespaces

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -