📄 xpathexpression.cpp
字号:
{
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 + -