Xalan-C++ API Documentation

The Xalan C++ XSLT Processor Version 1.8

Main Page | Directories | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | File Members | Related Pages

XPathExpression.hpp

Go to the documentation of this file.
00001 /*
00002  * Copyright 1999-2004 The Apache Software Foundation.
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 #if !defined(XPATHEXPRESSION_HEADER_GUARD_1357924680)
00017 #define XPATHEXPRESSION_HEADER_GUARD_1357924680
00018 
00019 
00020 
00021 // Base header file.  Must be first.
00022 #include <xalanc/XPath/XPathDefinitions.hpp>
00023 
00024 
00025 
00026 #include <vector>
00027 
00028 #if defined(XALAN_CLASSIC_IOSTREAMS)
00029 #include <iostream.h>
00030 #else
00031 #include <iosfwd>
00032 #endif
00033 
00034 
00035 
00036 #include <xalanc/XalanDOM/XalanDOMString.hpp>
00037 
00038 
00039 
00040 #include <xalanc/PlatformSupport/DOMStringHelper.hpp>
00041 #include <xalanc/PlatformSupport/PrintWriter.hpp>
00042 
00043 
00044 
00045 #include <xalanc/XPath/XToken.hpp>
00046 #include <xalanc/XPath/XalanXPathException.hpp>
00047 
00048 
00049 
00050 XALAN_CPP_NAMESPACE_BEGIN
00051 
00052 
00053 
00054 class XALAN_XPATH_EXPORT XPathExpression
00055 {
00056 public:
00057 
00058 #if defined(XALAN_NO_STD_NAMESPACE)
00059     typedef ostream                         OstreamType;
00060 
00061     typedef vector<int>                     OpCodeMapType;
00062     typedef vector<XToken>                  TokenQueueType;
00063 
00064     typedef OpCodeMapType::value_type       OpCodeMapValueType;
00065     typedef OpCodeMapValueType              OpCodeMapSizeType;
00066 
00067     typedef vector<OpCodeMapValueType>      OpCodeMapValueVectorType;
00068 
00069     typedef vector<double>                  NumberLiteralValueVectorType;
00070 #else
00071     typedef std::ostream                    OstreamType;
00072 
00073     typedef std::vector<int>                OpCodeMapType;
00074     typedef std::vector<XToken>             TokenQueueType;
00075 
00076     typedef OpCodeMapType::value_type       OpCodeMapValueType;
00077     typedef OpCodeMapValueType              OpCodeMapSizeType;
00078 
00079     typedef std::vector<OpCodeMapValueType> OpCodeMapValueVectorType;
00080 
00081     typedef std::vector<double>             NumberLiteralValueVectorType;
00082 #endif
00083 
00084 #define XALAN_XPATH_EXPRESSION_USE_ITERATORS
00085 
00086 #if defined(XALAN_XPATH_EXPRESSION_USE_ITERATORS)
00087     typedef OpCodeMapType::const_iterator   OpCodeMapPositionType;
00088 #else
00089     typedef OpCodeMapSizeType               OpCodeMapPositionType;
00090 #endif
00091     typedef OpCodeMapType::difference_type  OpCodeMapDifferenceType;
00092     typedef TokenQueueType::value_type      TokenQueueValueType;
00093     typedef int                             TokenQueueSizeType;
00094     typedef TokenQueueSizeType              TokenQueuePositionType;
00095 
00114     enum eOpCodes
00115     {
00121         eELEMWILDCARD = -3,
00122 
00127         eEMPTY = -2,
00128 
00133         eENDOP = -1,
00134 
00148         eOP_XPATH = 1,
00149 
00159         eOP_OR = 2,
00160 
00170         eOP_AND = 3,
00171 
00181         eOP_NOTEQUALS = 4,
00182 
00192         eOP_EQUALS = 5,
00193 
00203         eOP_LTE = 6,
00204 
00214         eOP_LT = 7,
00215 
00225         eOP_GTE = 8,
00226 
00236         eOP_GT = 9,
00237 
00247         eOP_PLUS = 10,
00248 
00258         eOP_MINUS = 11,
00259 
00269         eOP_MULT = 12,
00270 
00280         eOP_DIV = 13,
00281 
00291         eOP_MOD = 14,
00292 
00301         eOP_NEG = 15,
00302 
00311         eOP_BOOL = 16,
00312 
00321         eOP_UNION = 17,
00322 
00331         eOP_LITERAL = 18,
00332 
00341         eOP_VARIABLE = 19,
00342 
00356         eOP_GROUP = 20,
00357 
00366         eOP_NUMBERLIT = 21,
00367 
00381         eOP_ARGUMENT = 22,
00382 
00398         eOP_EXTFUNCTION = 23,
00399 
00416         eOP_FUNCTION = 24,
00417 
00431         eOP_LOCATIONPATH = 25,
00432 
00442         eOP_PREDICATE = 26,
00443 
00451         eNODETYPE_COMMENT = 27,
00452         
00460         eNODETYPE_TEXT = 28,
00461         
00469         eNODETYPE_PI = 29,
00470         
00478         eNODETYPE_NODE = 30,
00479         
00488         eNODENAME = 31,
00489         
00497         eNODETYPE_ROOT = 32,
00498         
00506         eNODETYPE_ANYELEMENT = 33,
00507 
00518         eFROM_ANCESTORS = 34,
00519         eFROM_ANCESTORS_OR_SELF = 35,
00520         eFROM_ATTRIBUTES = 36,
00521         eFROM_CHILDREN = 37,
00522         eFROM_DESCENDANTS = 38,
00523         eFROM_DESCENDANTS_OR_SELF = 39,
00524         eFROM_FOLLOWING = 40,
00525         eFROM_FOLLOWING_SIBLINGS = 41,
00526         eFROM_PARENT = 42,
00527         eFROM_PRECEDING = 43,
00528         eFROM_PRECEDING_SIBLINGS = 44,
00529         eFROM_SELF = 45,
00530         eFROM_NAMESPACE = 46,
00531         eFROM_ROOT = 47,
00532 
00541         eOP_MATCHPATTERN = 48,
00542 
00551         eOP_LOCATIONPATHPATTERN = 49,
00552 
00553         // For match patterns
00554         eMATCH_ATTRIBUTE = 50,
00555         eMATCH_ANY_ANCESTOR = 51,
00556         eMATCH_IMMEDIATE_ANCESTOR = 52,
00557         eMATCH_ANY_ANCESTOR_WITH_PREDICATE = 53,
00558         eMATCH_ANY_ANCESTOR_WITH_FUNCTION_CALL = 54,
00559 
00569         eOP_PREDICATE_WITH_POSITION = 55,
00570   
00575         eOP_FUNCTION_POSITION = 56,
00576         eOP_FUNCTION_LAST = 57,
00577         eOP_FUNCTION_COUNT = 58,
00578         eOP_FUNCTION_NOT = 59,
00579         eOP_FUNCTION_TRUE = 60,
00580         eOP_FUNCTION_FALSE = 61,
00581         eOP_FUNCTION_BOOLEAN = 62,
00582         eOP_FUNCTION_NAME_0 = 63,
00583         eOP_FUNCTION_NAME_1 = 64,
00584         eOP_FUNCTION_LOCALNAME_0 = 65,
00585         eOP_FUNCTION_LOCALNAME_1 = 66,
00586         eOP_FUNCTION_FLOOR = 67,
00587         eOP_FUNCTION_CEILING = 68,
00588         eOP_FUNCTION_ROUND = 69,
00589         eOP_FUNCTION_NUMBER_0 = 70,
00590         eOP_FUNCTION_NUMBER_1 = 71,
00591         eOP_FUNCTION_STRING_0 = 72,
00592         eOP_FUNCTION_STRING_1 = 73,
00593         eOP_FUNCTION_STRINGLENGTH_0 = 74,
00594         eOP_FUNCTION_STRINGLENGTH_1 = 75,
00595         eOP_FUNCTION_NAMESPACEURI_0 = 76,
00596         eOP_FUNCTION_NAMESPACEURI_1 = 77,
00597         eOP_FUNCTION_SUM = 78,
00598         eOP_FUNCTION_CONCAT = 79,
00599 
00600         // Always add _before_ this one and update
00601         // s_opCodeLengthArray.
00602         eOpCodeNextAvailable
00603     };  // enum eOpCodes
00604 
00608     class XALAN_XPATH_EXPORT XPathExpressionException : public XalanXPathException
00609     {
00610     public:
00611 
00617         XPathExpressionException(const XalanDOMString&  theMessage);
00618 
00619         virtual~
00620         XPathExpressionException();
00621     };
00622 
00626     class XALAN_XPATH_EXPORT InvalidOpCodeException : public XPathExpressionException
00627     {
00628     public:
00629 
00635         InvalidOpCodeException(OpCodeMapValueType   theOpCode);
00636 
00637         virtual~
00638         InvalidOpCodeException();
00639 
00640     private:
00641 
00642         static XalanDOMString
00643         FormatErrorMessage(OpCodeMapValueType   theOpCode);
00644     };
00645 
00650     class XALAN_XPATH_EXPORT InvalidArgumentCountException : public XPathExpressionException
00651     {
00652     public:
00653 
00661         InvalidArgumentCountException(
00662             OpCodeMapValueType  theOpCode,
00663             OpCodeMapValueType  theExpectedCount,
00664             OpCodeMapValueType  theSuppliedCount);
00665 
00666         virtual~
00667         InvalidArgumentCountException();
00668 
00669     private:
00670 
00671         static XalanDOMString
00672         FormatErrorMessage(
00673             OpCodeMapValueType  theOpCode,
00674             OpCodeMapValueType  theExpectedCount,
00675             OpCodeMapValueType  theSuppliedCount);
00676     };
00677 
00681     class XALAN_XPATH_EXPORT InvalidArgumentException : public XPathExpressionException
00682     {
00683     public:
00684 
00691         InvalidArgumentException(
00692             OpCodeMapValueType  theOpCode,
00693             OpCodeMapValueType  theValue);
00694 
00695         virtual~
00696         InvalidArgumentException();
00697 
00698     private:
00699 
00700         static XalanDOMString
00701         FormatErrorMessage(
00702                 OpCodeMapValueType  theOpCode,
00703                 OpCodeMapValueType  theValue);
00704     };
00705 
00706 
00713 #if defined(XALAN_INLINE_INITIALIZATION)
00714     static const TokenQueueSizeType     s_opCodeMapLengthIndex = 1;
00715 #else
00716     enum eDummy
00717     {
00718         s_opCodeMapLengthIndex = 1
00719     };
00720 #endif
00721 
00722     explicit
00723     XPathExpression();
00724 
00725     ~XPathExpression();
00726 
00730     void
00731     reset();
00732 
00736     void
00737     shrink();
00738 
00744     OpCodeMapSizeType
00745     opCodeMapSize() const
00746     {
00747         return OpCodeMapSizeType(m_opMap.size());
00748     }
00749 
00761     OpCodeMapValueType
00762     opCodeMapLength() const
00763     {
00764         const OpCodeMapSizeType     theSize = opCodeMapSize();
00765 
00766         if (theSize > s_opCodeMapLengthIndex)
00767         {
00768             assert(theSize == OpCodeMapSizeType(m_opMap[s_opCodeMapLengthIndex]));
00769 
00770             return m_opMap[s_opCodeMapLengthIndex];
00771         }
00772         else
00773         {
00774             assert(theSize == OpCodeMapValueType(theSize));
00775 
00776             return OpCodeMapValueType(theSize);
00777         }
00778     }
00779 
00780     OpCodeMapPositionType
00781     getInitialOpCodePosition() const
00782     {
00783 #if defined(XALAN_XPATH_EXPRESSION_USE_ITERATORS)
00784         return m_opMap.begin();
00785 #else
00786         return 0;
00787 #endif
00788     }
00789 
00790     bool
00791     isValidOpCodePosition(OpCodeMapPositionType     opPos) const
00792     {
00793         const OpCodeMapDifferenceType  theDifference =
00794             OpCodeMapDifferenceType(opPos - getInitialOpCodePosition());
00795 
00796         return theDifference >= 0 && 
00797                theDifference < opCodeMapSize();
00798     }
00799 
00800 #if defined(XALAN_XPATH_EXPRESSION_USE_ITERATORS)
00801     bool
00802     isValidOpCodePosition(OpCodeMapSizeType     theIndex) const
00803     {
00804         return theIndex >= 0 && theIndex < opCodeMapSize();
00805     }
00806 
00814     OpCodeMapValueType
00815     getOpCodeMapValue(OpCodeMapSizeType     theIndex) const
00816     {
00817         assert(theIndex < opCodeMapLength());
00818 
00819         return m_opMap[theIndex];
00820     }
00821 #endif
00822 
00830     OpCodeMapValueType
00831     getOpCodeMapValue(OpCodeMapPositionType     opPos) const
00832     {
00833         assert(opPos < getInitialOpCodePosition() + opCodeMapLength());
00834 
00835 #if defined(XALAN_XPATH_EXPRESSION_USE_ITERATORS)
00836         return *opPos;
00837 #else
00838 
00839         return m_opMap[opPos];
00840 #endif
00841     }
00842 
00850     void
00851     setOpCodeMapValue(
00852             OpCodeMapSizeType           theOpCodeMapIndex,
00853             const OpCodeMapValueType&   theValue)
00854     {
00855         assert(theOpCodeMapIndex < opCodeMapLength());
00856 
00857         m_opMap[theOpCodeMapIndex] = theValue;
00858     }
00859 
00860     OpCodeMapValueType
00861     getOpCodeArgumentLength(OpCodeMapPositionType   opPos) const
00862     {
00863         return getOpCodeMapValue(opPos + XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
00864     }
00865 
00873     OpCodeMapValueType
00874     getOpCodeLengthFromOpMap(OpCodeMapPositionType  opPos) const;
00875 
00876 #if defined(XALAN_XPATH_EXPRESSION_USE_ITERATORS)
00877 
00884     OpCodeMapValueType
00885     getOpCodeLengthFromOpMap(OpCodeMapSizeType  theIndex) const;
00886 #endif
00887 
00888 #if defined(XALAN_XPATH_EXPRESSION_USE_ITERATORS)
00889 
00896     OpCodeMapPositionType
00897     getNextOpCodePosition(OpCodeMapPositionType     opPos) const
00898     {
00899         assert(opPos < getInitialOpCodePosition() + opCodeMapLength());
00900 
00901         return opPos + *(opPos + s_opCodeMapLengthIndex);
00902     }
00903 #endif
00904 
00912     OpCodeMapSizeType
00913 #if defined(XALAN_XPATH_EXPRESSION_USE_ITERATORS)
00914     getNextOpCodePosition(OpCodeMapSizeType     theIndex) const
00915 #else
00916     getNextOpCodePosition(OpCodeMapPositionType     theIndex) const
00917 #endif
00918     {
00919         assert(theIndex < opCodeMapLength());
00920 
00921         assert(theIndex + m_opMap[theIndex + s_opCodeMapLengthIndex] ==
00922                OpCodeMapSizeType(theIndex + m_opMap[theIndex + s_opCodeMapLengthIndex]));
00923 
00924         return OpCodeMapSizeType(theIndex + m_opMap[theIndex + s_opCodeMapLengthIndex]);
00925     }
00926 
00936     void
00937     setOpCodeArgs(
00938             eOpCodes                            theOpCode,
00939             OpCodeMapSizeType                   theIndex,
00940             const OpCodeMapValueVectorType&     theArgs);
00941 
00948     OpCodeMapSizeType
00949     appendOpCode(eOpCodes   theOpCode);
00950 
00957     OpCodeMapSizeType
00958     appendOpCode(
00959             eOpCodes                            theOpCode,
00960             const OpCodeMapValueVectorType&     theArgs)
00961     {
00962         const OpCodeMapSizeType     thePosition = appendOpCode(theOpCode);
00963 
00964         setOpCodeArgs(theOpCode,
00965                       thePosition,
00966                       theArgs);
00967 
00968         return thePosition;
00969     }
00970 
00978     void
00979     replaceOpCode(
00980             OpCodeMapSizeType   theIndex,
00981             eOpCodes            theOldOpCode,
00982             eOpCodes            theNewOpCode);
00983 
00990     OpCodeMapValueType
00991     insertOpCode(
00992             eOpCodes            theOpCode,
00993             OpCodeMapSizeType   theIndex);
00994 
01004     void
01005     updateOpCodeLength(OpCodeMapSizeType    theIndex)
01006     {
01007         assert(theIndex < opCodeMapSize());
01008 
01009         updateOpCodeLength(m_opMap[theIndex], theIndex);
01010     }
01011 
01020     void
01021     updateShiftedOpCodeLength(
01022             OpCodeMapValueType  theOpCode,
01023             OpCodeMapSizeType   theOriginalIndex,
01024             OpCodeMapSizeType   theNewIndex);
01025 
01036     void
01037     updateOpCodeLength(
01038             OpCodeMapValueType  theOpCode,
01039             OpCodeMapSizeType   theIndex);
01040 
01048     static bool
01049     isNodeTestOpCode(OpCodeMapValueType     theOpCode);
01050 
01056     void
01057     updateOpCodeLengthAfterNodeTest(OpCodeMapSizeType   theIndex);
01058 
01064     bool
01065     hasMoreTokens() const
01066     {
01067         return tokenQueueSize() > m_currentPosition ? true : false;
01068     }
01069 
01075     TokenQueueSizeType
01076     tokenQueueSize() const
01077     {
01078         return TokenQueueSizeType(m_tokenQueue.size());
01079     }
01080 
01081     bool
01082     isValidTokenQueuePosition(TokenQueueSizeType    thePosition) const
01083     {
01084         return thePosition < tokenQueueSize();
01085     }
01086 
01092     TokenQueueSizeType
01093     getTokenPosition() const
01094     {
01095         return m_currentPosition;
01096     }
01097 
01101     void
01102     resetTokenPosition()
01103     {
01104         m_currentPosition = 0;
01105     }
01106 
01113     const XToken*
01114     getToken(TokenQueuePositionType     thePosition) const
01115     {
01116         assert(thePosition < tokenQueueSize());
01117 
01118         return &m_tokenQueue[thePosition];
01119     }
01120 
01126     const XToken*
01127     getNextToken()
01128     {
01129         if (hasMoreTokens() == true)
01130         {
01131             return getToken(m_currentPosition++);
01132         }
01133         else
01134         {
01135             return 0;
01136         }
01137     }
01138 
01144     const XToken*
01145     getPreviousToken()
01146     {
01147         if (m_currentPosition > 0)
01148         {
01149             return getToken(--m_currentPosition);
01150         }
01151         else
01152         {
01153             return 0;
01154         }
01155     }
01156 
01157     enum eRelativeDirection
01158     {
01159         eRelativeBackward,
01160         eRelativeForward
01161     };
01162 
01171     const XToken*
01172     getRelativeToken(
01173         TokenQueuePositionType  theOffset,
01174         eRelativeDirection      theDirection) const
01175     {
01176         const TokenQueuePositionType    thePosition =
01177             calculateRelativePosition(theOffset, theDirection);
01178 
01179         if (thePosition == tokenQueueSize())
01180         {
01181             return 0;
01182         }
01183         else
01184         {
01185             return getToken(thePosition);
01186         }
01187     }
01188 
01194     void
01195     pushToken(const XalanDOMString&     theToken)
01196     {
01197         m_tokenQueue.push_back(XToken(theToken));
01198     }
01199 
01206     void
01207     pushToken(
01208             double                  theNumber,
01209             const XalanDOMString&   theString)
01210     {
01211         m_tokenQueue.push_back(XToken(theNumber, theString));
01212     }
01213 
01220     void
01221     insertToken(const XalanDOMString&   theToken)
01222     {
01223         m_tokenQueue.insert(m_tokenQueue.begin() + (m_currentPosition - 1), XToken(theToken));
01224     }
01225 
01233     void
01234     insertToken(
01235             double                  theNumber,
01236             const XalanDOMString&   theString)
01237     {
01238         m_tokenQueue.insert(m_tokenQueue.begin() + (m_currentPosition - 1), XToken(theNumber, theString));
01239     }
01240 
01247     void
01248     replaceRelativeToken(
01249             TokenQueuePositionType  theOffset,
01250             eRelativeDirection      theDirection,
01251             const XalanDOMString&   theString)
01252     {
01253         const TokenQueuePositionType    thePosition =
01254             calculateRelativePosition(theOffset, theDirection);
01255         assert(thePosition < tokenQueueSize());
01256 
01257         m_tokenQueue[thePosition].set(theString);
01258     }
01259 
01266     void
01267     dumpOpCodeMap(
01268             PrintWriter&        thePrintWriter,
01269             OpCodeMapSizeType   theStartPosition = 0) const;
01270 
01277     void
01278     dumpOpCodeMap(
01279             OstreamType&        theStream,
01280             OpCodeMapSizeType   theStartPosition = 0) const;
01281 
01288     void
01289     dumpTokenQueue(
01290             PrintWriter&        thePrintWriter,
01291             TokenQueueSizeType  theStartPosition = 0) const;
01292 
01299     void
01300     dumpTokenQueue(
01301             OstreamType&        theStream,
01302             TokenQueueSizeType  theStartPosition = 0) const;
01303 
01309     void
01310     dumpRemainingTokenQueue(PrintWriter&    thePrintWriter) const;
01311 
01317     void
01318     dumpRemainingTokenQueue(OstreamType&    theStream) const;
01319 
01326     void
01327     pushValueOnOpCodeMap(const OpCodeMapType::value_type&   theValue)
01328     {
01329         // Push the index onto the op map.
01330         m_opMap.push_back(theValue);
01331 
01332         // Update the op map length.
01333         ++m_opMap[s_opCodeMapLengthIndex];
01334     }
01335 
01342     void
01343     pushArgumentOnOpCodeMap(const XToken&   theXToken);
01344 
01351     void
01352     pushArgumentOnOpCodeMap(const XalanDOMString&   theString);
01353 
01361     void
01362     pushArgumentOnOpCodeMap(
01363             double                  theNumber,
01364             const XalanDOMString&   theString);
01365 
01372     void
01373     pushNumberLiteralOnOpCodeMap(double     theNumber);
01374 
01380     double
01381     getNumberLiteral(int    theIndex) const
01382     {
01383         assert(theIndex >= 0 &&
01384                NumberLiteralValueVectorType::size_type(theIndex) < m_numberLiteralValues.size());
01385 
01386         return m_numberLiteralValues[NumberLiteralValueVectorType::size_type(theIndex)];
01387     }
01388 
01393     void
01394     pushCurrentTokenOnOpCodeMap();
01395 
01401     void
01402     setCurrentPattern(const XalanDOMString&     thePattern)
01403     {
01404         m_currentPattern = &thePattern;
01405     }
01406 
01412     const XalanDOMString&
01413     getCurrentPattern() const
01414     {
01415         assert(m_currentPattern != 0);
01416 
01417         return *m_currentPattern;
01418     }
01419 
01420 private:
01421 
01431     TokenQueuePositionType
01432     calculateRelativePosition(
01433         TokenQueuePositionType  theOffset,
01434         eRelativeDirection      theDirection) const
01435     {
01436         if (theDirection == eRelativeBackward &&
01437             theOffset <= m_currentPosition)
01438         {
01439             return m_currentPosition - theOffset;
01440         }
01441         else if (theDirection == eRelativeForward &&
01442                  m_currentPosition + theOffset < tokenQueueSize())
01443         {
01444             return m_currentPosition + theOffset;
01445         }
01446         else
01447         {
01448             return tokenQueueSize();
01449         }
01450     }
01451 
01458     OpCodeMapType           m_opMap;
01459 
01464     OpCodeMapSizeType       m_lastOpCodeIndex;
01465 
01471     TokenQueueType          m_tokenQueue;
01472 
01476     TokenQueueSizeType      m_currentPosition;
01477 
01481     const XalanDOMString*   m_currentPattern;
01482 
01483     // Default vector allocation sizes.
01484     enum
01485     {
01486         eDefaultOpMapSize = 100,
01487         eDefaultTokenQueueSize = 30
01488     };
01489 
01490     NumberLiteralValueVectorType    m_numberLiteralValues;
01491 };
01492 
01493 
01494 
01495 XALAN_CPP_NAMESPACE_END
01496 
01497 
01498 
01499 #endif  // XPATHEXPRESSION_HEADER_GUARD_1357924680

Interpreting class diagrams

Doxygen and GraphViz are used to generate this API documentation from the Xalan-C header files.

Xalan-C++ XSLT Processor Version 1.8
Copyright © 1999-2004 The Apache Software Foundation. All Rights Reserved.