• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • Contact Us
 

KHTML

path.cpp

Go to the documentation of this file.
00001 /*
00002  * path.cc - Copyright 2005 Frerich Raabe <raabe@kde.org>
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions
00006  * are met:
00007  *
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  *
00014  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00015  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00016  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00017  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00018  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00019  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00020  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00021  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00022  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00023  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00024  */
00025 #include "path.h"
00026 
00027 #include "xml/dom_docimpl.h"
00028 #include "xml/dom_nodeimpl.h"
00029 
00030 using namespace DOM;
00031 using namespace khtml;
00032 using namespace khtml::XPath;
00033 
00034 Filter::Filter( Expression *expr, const QList<Predicate *> &predicates )
00035     : m_expr( expr ),
00036     m_predicates( predicates )
00037 {
00038 }
00039 
00040 Filter::~Filter()
00041 {
00042     delete m_expr;
00043     qDeleteAll( m_predicates );
00044 }
00045 
00046 QString Filter::dump() const
00047 {
00048     QString s = "<filter>";
00049     s += m_expr->dump();
00050     foreach( Predicate *predicate, m_predicates ) {
00051         s += predicate->dump();
00052     }
00053     s += "</filter>";
00054     return s;
00055 }
00056 
00057 Value Filter::doEvaluate() const
00058 {
00059     Value v = m_expr->evaluate();
00060     if ( !v.isNodeset() ) {
00061         if ( !m_predicates.empty() ) {
00062             kDebug(6011) << "Ignoring predicates for filter since expression does not evaluate to a nodeset!";
00063         }
00064         return v;
00065     }
00066 
00067     DomNodeList inNodes = v.toNodeset(), outNodes;
00068 
00069     // Filter seems to work in document order, not axis order
00070     inNodes->normalizeUpto(StaticNodeListImpl::DocumentOrder);
00071 
00072     foreach( Predicate *predicate, m_predicates ) {
00073         outNodes = new StaticNodeListImpl();
00074         Expression::evaluationContext().size = int(inNodes->length());
00075 
00076         for ( unsigned long n = 0; n < inNodes->length(); ++n ) {
00077             NodeImpl *node = inNodes->item(n);
00078             Expression::evaluationContext().node = node;
00079             Expression::evaluationContext().position = n + 1;
00080 
00081             if ( predicate->evaluate() ) {
00082                 outNodes->append( node );
00083             }
00084         }
00085 
00086         inNodes = outNodes;
00087         outNodes->setKnownNormalization(StaticNodeListImpl::DocumentOrder);
00088 
00089 #ifdef XPATH_VERBOSE
00090         kDebug(6011) << "Predicate within filter trims to:" << outNodes->length();
00091 #endif
00092     }
00093 
00094     return Value( outNodes );
00095 }
00096 
00097 LocationPath::LocationPath()
00098     : m_absolute( false )
00099 {
00100 }
00101 
00102 LocationPath::~LocationPath()
00103 {
00104     qDeleteAll( m_steps );
00105 }
00106 
00107 void LocationPath::optimize()
00108 {
00109     foreach( Step *step, m_steps ) {
00110         step->optimize();
00111     }
00112 }
00113 
00114 Value LocationPath::doEvaluate() const
00115 {
00116 #ifdef XPATH_VERBOSE
00117     if ( m_absolute ) {
00118         kDebug(6011) << "Evaluating absolute path expression, steps:" << m_steps.count();
00119     } else {
00120         kDebug(6011) << "Evaluating relative path expression, steps:" << m_steps.count();
00121     }
00122 #endif
00123 
00124     DomNodeList inDomNodes  = new StaticNodeListImpl,
00125                 outDomNodes;
00126 
00127     /* For absolute location paths, the context node is ignored - the
00128      * document's root node is used instead.
00129      */
00130     NodeImpl *context = Expression::evaluationContext().node;
00131     if ( m_absolute ) {
00132         if ( context->nodeType() != Node::DOCUMENT_NODE ) {
00133             context = context->ownerDocument();
00134         }
00135     }
00136 
00137     inDomNodes->append( context );
00138 
00139     if ( m_steps.isEmpty() )
00140         return Value( inDomNodes );
00141 
00142     int s = 0;
00143     foreach( Step *step, m_steps ) {
00144 #ifdef XPATH_VERBOSE
00145         kDebug(6011) << "-------------------------------------";
00146         kDebug(6011) << "Step " << s << "insize " << inDomNodes->length();
00147 #endif      
00148 
00149         outDomNodes = new StaticNodeListImpl;
00150         for ( unsigned long i = 0; i < inDomNodes->length(); ++i ) {
00151             DomNodeList matches = step->evaluate( inDomNodes->item( i ) );
00152             for ( unsigned long j = 0; j < matches->length(); ++j )
00153                 outDomNodes->append( matches->item( j ) );
00154         }
00155         inDomNodes = outDomNodes;
00156 
00157         ++s;
00158     }
00159 
00160 #ifdef XPATH_VERBOSE
00161     kDebug(6011) << "-------------------------------------";
00162     kDebug(6011) << "output:" <<outDomNodes->length();
00163     kDebug(6011) << "=====================================";
00164 #endif
00165 
00166     return Value( outDomNodes );
00167 }
00168 
00169 QString LocationPath::dump() const
00170 {
00171     QString s = "<locationpath absolute=\"";
00172     s += m_absolute ? "true" : "false";
00173     s += "\">";
00174     foreach( Step *step, m_steps ) {
00175         s += step->dump();
00176     }
00177     s += "</locationpath>";
00178     return s;
00179 }
00180 
00181 Path::Path( Filter *filter, LocationPath *path )
00182     : m_filter( filter ),
00183     m_path( path )
00184 {
00185 }
00186 
00187 Path::~Path()
00188 {
00189     delete m_filter;
00190     delete m_path;
00191 }
00192 
00193 QString Path::dump() const
00194 {
00195     if ( !m_filter && !m_path ) {
00196         return "<path/>";
00197     }
00198 
00199     QString s = "<path>";
00200     if ( m_filter ) {
00201         s += m_filter->dump();
00202     }
00203     if ( m_path ) {
00204         s += m_path->dump();
00205     }
00206     s += "</path>";
00207 
00208     return s;
00209 }
00210 
00211 Value Path::doEvaluate() const
00212 {
00213     NodeImpl* saveCtx = Expression::evaluationContext().node;
00214 
00215     Value initial =  m_filter->evaluate();
00216     if ( initial.isNodeset() ) {
00217         // Pass in every output from the filter to the path, and union the results
00218         DomNodeList out = new StaticNodeListImpl();
00219         DomNodeList in  = initial.toNodeset();
00220 
00221         for (unsigned long i = 0; i < in->length(); ++i) {
00222             Expression::evaluationContext().node = in->item(i);
00223 
00224             DomNodeList singleSet = m_path->evaluate().toNodeset();
00225             for (unsigned long j = 0; j < singleSet->length(); ++ j)
00226                 out->append(singleSet->item(j));
00227         }
00228 
00229         Expression::evaluationContext().node = saveCtx;
00230         return Value(out);
00231     } else {
00232         // ### what should happen in this case?
00233         Expression::reportInvalidExpressionErr();
00234         return Value();
00235     }
00236 }
00237 
00238 // kate: indent-width 4; replace-tabs off; tab-width 4; space-indent off;

KHTML

Skip menu "KHTML"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.3
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal