📄 xpathexpression.cpp
字号:
if( tokens[idx] == "/" ) {
tokens[idx] = AXIS_DESCENDANT_OR_SELF + "::node()";
tokens.insert("/", idx + 1);
}
// check for "." shortcut
else if( tokens[idx] == "." ) {
tokens[idx] = AXIS_SELF + "::node()";
}
// check for ".." shortcut
else if( tokens[idx] == ".." ) {
tokens[idx] = AXIS_PARENT + "::node()";
}
String section = tokens[idx];
xp_path_item item;
// locate predicate
int begBrack = section.findPos("[");
if( begBrack != String::npos ) {
StringTokenizer toker;
toker.addContainer($("\""), $("\""), StringTokenizer::EXCLUSIVE);
toker.addContainer($("\'"), $("\'"), StringTokenizer::EXCLUSIVE);
toker.addContainer($("[" ), $("]" ), StringTokenizer::NORMAL );
flags32_t tokerFlags = StringTokenizer::TRIM_RESULTS|StringTokenizer::NO_WHITESPACE;
Array<String> predicates = toker.tokenize(section.subString(begBrack), $("[]"), tokerFlags);
if( predicates.getSize() > 0 ) {
if( m_predicate == 0 ) {
m_predicate = new XPathPredicate();
}
for( int i = 0; i < predicates.getSize(); ++i ) {
Array<XPathToken> predTokens = m_predicate->parsePredicate(predicates[i]);
item.m_predicates.append(predTokens);
}
}
section = section.left(begBrack).trim();
}
// get axis
int posColon = section.findPos("::");
if( posColon != String::npos ) {
item.m_axis = section.left(posColon);
section = section.stripFromLeft(posColon + 2);
}
else {
item.m_axis = AXIS_CHILD;
}
// get node name
if( section.beginsWith("@") ) {
item.m_axis = AXIS_ATTRIBUTE;
section = section.stripFromLeft(1);
}
item.m_node = section;
curInfo.append(item);
++idx;
}
if( curInfo.getSize() > 0 ) {
info.append(curInfo);
}
}
// ---------------------------------------------------------------------------------------------------------------------
Array<DomNode*> XPathExpression::processPass( Array<DomNode*> search, xp_path_item& item )
{
Array<DomNode*> results;
results = processPassAxis(search, item);
return (results);
}
// ---------------------------------------------------------------------------------------------------------------------
Array<DomNode*> XPathExpression::processPassAxis( Array<DomNode*> search, xp_path_item& item )
{
String axis = item.m_axis;
if( axis == AXIS_CHILD ) {
return processAxisChild(search, item);
}
if( axis == AXIS_DESCENDANT ) {
return processAxisDescendant(search, item);
}
if( axis == AXIS_PARENT ) {
return processAxisParent(search, item);
}
if( axis == AXIS_ANCESTOR ) {
return processAxisAncestor(search, item);
}
if( axis == AXIS_FOLLOWING_SIBLING ) {
return processAxisFollowingSibling(search, item);
}
if( axis == AXIS_PRECEDING_SIBLING ) {
return processAxisPrecedingSibling(search, item);
}
if( axis == AXIS_FOLLOWING ) {
return processAxisFollowing(search, item);
}
if( axis == AXIS_PRECEDING ) {
return processAxisPreceding(search, item);
}
if( axis == AXIS_DESCENDANT_OR_SELF ) {
return processAxisDescendantOrSelf(search, item);
}
if( axis == AXIS_ANCESTOR_OR_SELF ) {
return processAxisAncestorOrSelf(search, item);
}
if( axis == AXIS_SELF ) {
return processAxisSelf(search, item);
}
if( axis == AXIS_ATTRIBUTE ) {
return processAxisAttribute(search, item);
}
throw XPathException("Invalid axis specified: '" + axis + "'");
}
// ---------------------------------------------------------------------------------------------------------------------
Array<DomNode*> XPathExpression::processRecursiveMatch( DomNode* node, xp_path_item& item )
{
Array<DomNode*> results;
if( checkForMatch(node, item) ) {
results.append(node);
}
Array<DomNode*> nodes = node->getSubNodes();
for( int iN = 0; iN < nodes.getSize(); ++iN ) {
results += processRecursiveMatch(nodes[iN], item);
}
return (results);
}
// ---------------------------------------------------------------------------------------------------------------------
Array<DomNode*> XPathExpression::processAxisChild( Array<DomNode*> search, xp_path_item& item )
{
Array<DomNode*> results;
for( int i = 0; i < search.getSize(); ++i ) {
Array<DomNode*> nodes = search[i]->getSubNodes();
Array<DomNode*> nodeResults;
for( int iN = 0; iN < nodes.getSize(); ++iN ) {
if( checkForMatch(nodes[iN], item) ) {
nodeResults.append(nodes[iN]);
}
}
nodeResults = processPredicates(nodeResults, item);
results += nodeResults;
}
return (results);
}
// ---------------------------------------------------------------------------------------------------------------------
Array<DomNode*> XPathExpression::processAxisDescendant( Array<DomNode*> search, xp_path_item& item )
{
Array<DomNode*> results;
for( int i = 0; i < search.getSize(); ++i ) {
Array<DomNode*> nodes = search[i]->getSubNodes();
for( int iN = 0; iN < nodes.getSize(); ++iN ) {
results += processRecursiveMatch(nodes[iN], item);
}
}
results = processPredicates(results, item);
return (results);
}
// ---------------------------------------------------------------------------------------------------------------------
Array<DomNode*> XPathExpression::processAxisParent( Array<DomNode*> search, xp_path_item& item )
{
Array<DomNode*> results;
for( int i = 0; i < search.getSize(); ++i ) {
DomNode* parent = search[i]->getParent();
if( parent != 0 && parent->getNodeType() == DomNode::ELEMENT ) {
if( checkForMatch(parent, item) ) {
Array<DomNode*> matches(1);
matches[0] = parent;
matches = processPredicates(matches, item);
if( matches.getSize() > 0 ) {
results.append(parent);
}
}
}
}
return (results);
}
// ---------------------------------------------------------------------------------------------------------------------
Array<DomNode*> XPathExpression::processAxisAncestor( Array<DomNode*> search, xp_path_item& item )
{
Array<DomNode*> results;
for( int i = 0; i < search.getSize(); ++i ) {
DomNode* parent = search[i]->getParent();
while( parent != 0 && parent->getNodeType() == DomNode::ELEMENT ) {
if( checkForMatch(parent, item) ) {
Array<DomNode*> matches(1);
matches[0] = parent;
matches = processPredicates(matches, item);
if( matches.getSize() > 0 ) {
results.append(parent);
}
}
parent = parent->getParent();
}
}
return (results);
}
// ---------------------------------------------------------------------------------------------------------------------
Array<DomNode*> XPathExpression::processAxisFollowingSibling( Array<DomNode*> search, xp_path_item& item )
{
Array<DomNode*> results;
for( int i = 0; i < search.getSize(); ++i ) {
if( search[i]->getNodeType() == DomNode::ELEMENT ) {
DomElementNode* element = (DomElementNode*)search[i];
Array<DomElementNode*> siblings = element->getSiblingElementNodes();
int idx = 0;
for( ; idx < siblings.getSize() && siblings[idx] != element; ++idx ) {
; // empty loop
}
Array<DomNode*> nodeResults;
for( ++idx; idx < siblings.getSize(); ++idx ) {
if( checkForMatch(siblings[idx], item) ) {
nodeResults.append(siblings[idx]);
}
}
nodeResults = processPredicates(nodeResults, item);
results += nodeResults;
}
}
return (results);
}
// ---------------------------------------------------------------------------------------------------------------------
Array<DomNode*> XPathExpression::processAxisPrecedingSibling( Array<DomNode*> search, xp_path_item& item )
{
Array<DomNode*> results;
for( int i = 0; i < search.getSize(); ++i ) {
if( search[i]->getNodeType() == DomNode::ELEMENT ) {
DomElementNode* element = (DomElementNode*)search[i];
Array<DomElementNode*> siblings = element->getSiblingElementNodes();
Array<DomNode*> nodeResults;
for( int idx = 0; idx < siblings.getSize(); ++idx ) {
if( siblings[idx] == element ) {
break;
}
if( checkForMatch(siblings[idx], item) ) {
nodeResults.append(siblings[idx]);
}
}
nodeResults = processPredicates(nodeResults, item);
results += nodeResults;
}
}
return (results);
}
// ---------------------------------------------------------------------------------------------------------------------
Array<DomNode*> XPathExpression::processAxisFollowing( Array<DomNode*> search, xp_path_item& item )
{
Array<DomNode*> results;
for( int i = 0; i < search.getSize(); ++i ) {
if( search[i]->getNodeType() == DomNode::ELEMENT ) {
DomElementNode* element = (DomElementNode*)search[i];
Array<DomElementNode*> siblings = element->getSiblingElementNodes();
int idx = 0;
for( ; idx < siblings.getSize() && siblings[idx] != element; ++idx ) {
; // empty loop
}
Array<DomNode*> nodeResults;
for( ++idx; idx < siblings.getSize(); ++idx ) {
nodeResults += processRecursiveMatch(siblings[idx], item);
}
nodeResults = processPredicates(nodeResults, item);
results += nodeResults;
DomNode* parent = search[i]->getParent();
while( parent != 0 && parent->getNodeType() == DomNode::ELEMENT ) {
DomElementNode* element = (DomElementNode*)parent;
Array<DomElementNode*> siblings = element->getSiblingElementNodes();
int idx = 0;
for( ; idx < siblings.getSize() && siblings[idx] != element; ++idx ) {
; // empty loop
}
Array<DomNode*> nodeResults;
for( ++idx; idx < siblings.getSize(); ++idx ) {
nodeResults += processRecursiveMatch(siblings[idx], item);
}
nodeResults = processPredicates(nodeResults, item);
results += nodeResults;
parent = parent->getParent();
}
}
}
return (results);
}
// ---------------------------------------------------------------------------------------------------------------------
Array<DomNode*> XPathExpression::processAxisPreceding( Array<DomNode*> search, xp_path_item& item )
{
Array<DomNode*> results;
for( int i = 0; i < search.getSize(); ++i ) {
if( search[i]->getNodeType() == DomNode::ELEMENT ) {
DomElementNode* element = (DomElementNode*)search[i];
Array<DomElementNode*> siblings = element->getSiblingElementNodes();
Array<DomNode*> nodeResults;
for( int iS = 0; iS < siblings.getSize(); ++iS ) {
if( siblings[iS] == element ) {
break;
}
nodeResults += processRecursiveMatch(siblings[iS], item);
}
nodeResults = processPredicates(nodeResults, item);
results += nodeResults;
DomNode* parent = search[i]->getParent();
while( parent != 0 && parent->getNodeType() == DomNode::ELEMENT ) {
DomElementNode* element = (DomElementNode*)parent;
Array<DomElementNode*> siblings = element->getSiblingElementNodes();
Array<DomNode*> nodeResults;
for( int iS = 0; iS < siblings.getSize(); ++iS ) {
if( siblings[iS] == element ) {
break;
}
nodeResults += processRecursiveMatch(siblings[iS], item);
}
nodeResults = processPredicates(nodeResults, item);
results += nodeResults;
parent = parent->getParent();
}
}
}
return (results);
}
// ---------------------------------------------------------------------------------------------------------------------
Array<DomNode*> XPathExpression::processAxisDescendantOrSelf( Array<DomNode*> search, xp_path_item& item )
{
Array<DomNode*> results;
for( int i = 0; i < search.getSize(); ++i ) {
results += processRecursiveMatch(search[i], item);
}
results = processPredicates(results, item);
return (results);
}
// ---------------------------------------------------------------------------------------------------------------------
Array<DomNode*> XPathExpression::processAxisAncestorOrSelf( Array<DomNode*> search, xp_path_item& item )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -