* New scriptable interfaces to XSLT * Make HTML-output create real html * cleanup the XSLTProcessor class Patch by sicking, pike and peterv r=sicking/pike, sr=peterv, a=asa git-svn-id: svn://10.0.0.236/trunk@132337 18797224-902f-48f8-a5cc-f745e15eee43
534 lines
14 KiB
C++
534 lines
14 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
* The contents of this file are subject to the Mozilla Public
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code is TransforMiiX XSLT processor.
|
|
*
|
|
* The Initial Developer of the Original Code is The MITRE Corporation.
|
|
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
|
*
|
|
* Portions created by Keith Visco as a Non MITRE employee,
|
|
* (C) 1999 Keith Visco. All Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Keith Visco, kvisco@ziplink.net
|
|
* -- original author.
|
|
*
|
|
*/
|
|
|
|
|
|
|
|
#ifndef TRANSFRMX_PROCESSORSTATE_H
|
|
#define TRANSFRMX_PROCESSORSTATE_H
|
|
|
|
#include "NodeSet.h"
|
|
#include "Stack.h"
|
|
#include "ErrorObserver.h"
|
|
#include "NamedMap.h"
|
|
#include "txPatternParser.h"
|
|
#include "Expr.h"
|
|
#include "StringList.h"
|
|
#include "txOutputFormat.h"
|
|
#include "Map.h"
|
|
#include "txIXPathContext.h"
|
|
#include "txExpandedNameMap.h"
|
|
#include "txXMLEventHandler.h"
|
|
#include "XSLTFunctions.h"
|
|
#include "txError.h"
|
|
|
|
class txVariableMap;
|
|
class txXSLKey;
|
|
|
|
/**
|
|
* Class used for keeping the current state of the XSL Processor
|
|
*/
|
|
class ProcessorState : public txIMatchContext {
|
|
|
|
public:
|
|
/**
|
|
* Creates a new ProcessorState for the given XSL document
|
|
* And result Document
|
|
*/
|
|
ProcessorState(Document* aSourceDocument,
|
|
Document* aXslDocument);
|
|
|
|
/**
|
|
* Destroys this ProcessorState
|
|
*/
|
|
~ProcessorState();
|
|
|
|
/**
|
|
* Contain information that is import precedence dependant.
|
|
*/
|
|
class ImportFrame {
|
|
public:
|
|
ImportFrame(ImportFrame* aFirstNotImported);
|
|
~ImportFrame();
|
|
|
|
// Map of named templates
|
|
txExpandedNameMap mNamedTemplates;
|
|
|
|
// Map of template modes, each item in the map is a list
|
|
// of templates
|
|
txExpandedNameMap mMatchableTemplates;
|
|
|
|
// List of whitespace preserving and stripping nametests
|
|
txList mWhiteNameTests;
|
|
|
|
// Map of named attribute sets
|
|
txExpandedNameMap mNamedAttributeSets;
|
|
|
|
// Output format, as specified by the xsl:output elements
|
|
txOutputFormat mOutputFormat;
|
|
|
|
// ImportFrame which is the first one *not* imported by this frame
|
|
ImportFrame* mFirstNotImported;
|
|
|
|
// Map of top-level variables/parameters
|
|
txExpandedNameMap mVariables;
|
|
|
|
// The following stuff is missing here:
|
|
|
|
// Namespace aliases (xsl:namespace-alias)
|
|
};
|
|
// To be able to do some cleaning up in destructor
|
|
friend class ImportFrame;
|
|
|
|
/**
|
|
* Adds the given attribute set to the list of available named attribute
|
|
* sets
|
|
* @param aAttributeSet the Element to add as a named attribute set
|
|
* @param aImportFrame ImportFrame to add the attributeset to
|
|
*/
|
|
void addAttributeSet(Element* aAttributeSet, ImportFrame* aImportFrame);
|
|
|
|
/**
|
|
* Registers the given ErrorObserver with this ProcessorState
|
|
*/
|
|
void addErrorObserver(ErrorObserver& errorObserver);
|
|
|
|
/**
|
|
* Adds the given template to the list of templates to process
|
|
* @param aXslTemplate The Element to add as a template
|
|
* @param aImportFrame ImportFrame to add the template to
|
|
*/
|
|
void addTemplate(Element* aXslTemplate, ImportFrame* aImportFrame);
|
|
|
|
/**
|
|
* Adds the given LRE Stylesheet to the list of templates to process
|
|
* @param aStylesheet The Stylesheet to add as a template
|
|
* @param importFrame ImportFrame to add the template to
|
|
*/
|
|
void addLREStylesheet(Document* aStylesheet, ImportFrame* aImportFrame);
|
|
|
|
/**
|
|
* Returns the AttributeSet associated with the given name
|
|
* or null if no AttributeSet is found
|
|
*/
|
|
NodeSet* getAttributeSet(const txExpandedName& aName);
|
|
|
|
/**
|
|
* Returns the template associated with the given name, or
|
|
* null if not template is found
|
|
*/
|
|
Element* getNamedTemplate(const txExpandedName& aName);
|
|
|
|
/**
|
|
* Returns the OutputFormat which contains information on how
|
|
* to serialize the output.
|
|
*/
|
|
txOutputFormat* getOutputFormat();
|
|
|
|
/**
|
|
* Add a global variable
|
|
*/
|
|
nsresult addGlobalVariable(const txExpandedName& aVarName,
|
|
Element* aVarElem,
|
|
ImportFrame* aImportFrame,
|
|
ExprResult* aDefaultValue);
|
|
|
|
/**
|
|
* Returns map on top of the stack of local variable-bindings
|
|
*/
|
|
txVariableMap* getLocalVariables();
|
|
|
|
/**
|
|
* Sets top map of the local variable-bindings stack
|
|
*/
|
|
void setLocalVariables(txVariableMap* aMap);
|
|
|
|
/**
|
|
* Enums for the getExpr and getPattern functions
|
|
*/
|
|
enum ExprAttr {
|
|
SelectAttr = 0,
|
|
TestAttr,
|
|
ValueAttr
|
|
};
|
|
|
|
enum PatternAttr {
|
|
CountAttr = 0,
|
|
FromAttr
|
|
};
|
|
|
|
Expr* getExpr(Element* aElem, ExprAttr aAttr);
|
|
txPattern* getPattern(Element* aElem, PatternAttr aAttr);
|
|
|
|
/**
|
|
* Retrieve the document designated by the URI uri, using baseUri as base URI.
|
|
* Parses it as an XML document, and returns it. If a fragment identifier is
|
|
* supplied, the element with seleced id is returned.
|
|
* The returned document is owned by the ProcessorState
|
|
*
|
|
* @param uri the URI of the document to retrieve
|
|
* @param baseUri the base URI used to resolve the URI if uri is relative
|
|
* @return loaded document or element pointed to by fragment identifier. If
|
|
* loading or parsing fails NULL will be returned.
|
|
*/
|
|
Node* retrieveDocument(const String& uri, const String& baseUri);
|
|
|
|
/**
|
|
* Return stack of urls of currently entered stylesheets
|
|
*/
|
|
Stack* getEnteredStylesheets();
|
|
|
|
/**
|
|
* Return list of import containers
|
|
*/
|
|
List* getImportFrames();
|
|
|
|
/**
|
|
* Find template in specified mode matching the supplied node
|
|
* @param aNode node to find matching template for
|
|
* @param aMode mode of the template
|
|
* @param aImportFrame out-param, is set to the ImportFrame containing
|
|
* the found template
|
|
* @return root-node of found template, null if none is found
|
|
*/
|
|
Node* findTemplate(Node* aNode,
|
|
const txExpandedName& aMode,
|
|
ImportFrame** aImportFrame)
|
|
{
|
|
return findTemplate(aNode, aMode, 0, aImportFrame);
|
|
}
|
|
|
|
/**
|
|
* Find template in specified mode matching the supplied node. Only search
|
|
* templates imported by a specific ImportFrame
|
|
* @param aNode node to find matching template for
|
|
* @param aMode mode of the template
|
|
* @param aImportedBy seach only templates imported by this ImportFrame,
|
|
* or null to search all templates
|
|
* @param aImportFrame out-param, is set to the ImportFrame containing
|
|
* the found template
|
|
* @return root-node of found template, null if none is found
|
|
*/
|
|
Node* findTemplate(Node* aNode,
|
|
const txExpandedName& aMode,
|
|
ImportFrame* aImportedBy,
|
|
ImportFrame** aImportFrame);
|
|
|
|
/**
|
|
* Struct holding information about a current template rule
|
|
*/
|
|
struct TemplateRule {
|
|
ImportFrame* mFrame;
|
|
const txExpandedName* mMode;
|
|
txVariableMap* mParams;
|
|
};
|
|
|
|
/**
|
|
* Gets current template rule
|
|
*/
|
|
TemplateRule* getCurrentTemplateRule();
|
|
|
|
/**
|
|
* Sets current template rule
|
|
*/
|
|
void setCurrentTemplateRule(TemplateRule* aTemplateRule);
|
|
|
|
/**
|
|
* Adds the set of names to the Whitespace preserving element set
|
|
*/
|
|
void preserveSpace(String& names);
|
|
|
|
void processAttrValueTemplate(const String& aAttValue,
|
|
Element* aContext,
|
|
String& aResult);
|
|
|
|
/**
|
|
* Adds the set of names to the Whitespace stripping handling list.
|
|
* xsl:strip-space calls this with MB_TRUE, xsl:preserve-space
|
|
* with MB_FALSE
|
|
* aElement is used to resolve QNames
|
|
*/
|
|
void shouldStripSpace(String& aNames, Element* aElement,
|
|
MBool aShouldStrip,
|
|
ImportFrame* aImportFrame);
|
|
|
|
/**
|
|
* Adds the supplied xsl:key to the set of keys
|
|
*/
|
|
MBool addKey(Element* aKeyElem);
|
|
|
|
/**
|
|
* Returns the key with the supplied name
|
|
* returns NULL if no such key exists
|
|
*/
|
|
txXSLKey* getKey(txExpandedName& keyName);
|
|
|
|
/**
|
|
* Adds a decimal format. Returns false if the format already exists
|
|
* but dosn't contain the exact same parametervalues
|
|
*/
|
|
MBool addDecimalFormat(Element* element);
|
|
|
|
/**
|
|
* Returns a decimal format or NULL if no such format exists.
|
|
*/
|
|
txDecimalFormat* getDecimalFormat(const txExpandedName& name);
|
|
|
|
/**
|
|
* Returns a pointer to a document that can be used to create RTFs
|
|
*/
|
|
Document* getRTFDocument();
|
|
|
|
/**
|
|
* Sets a new document to be used for creating RTFs
|
|
*/
|
|
void setRTFDocument(Document* aDoc);
|
|
|
|
/**
|
|
* Returns the stylesheet document
|
|
*/
|
|
Document* getStylesheetDocument();
|
|
|
|
/**
|
|
* Virtual methods from txIEvalContext
|
|
*/
|
|
|
|
TX_DECL_MATCH_CONTEXT;
|
|
|
|
/**
|
|
* Set the current txIEvalContext and get the prior one
|
|
*/
|
|
txIEvalContext* setEvalContext(txIEvalContext* aEContext)
|
|
{
|
|
txIEvalContext* tmp = mEvalContext;
|
|
mEvalContext = aEContext;
|
|
return tmp;
|
|
}
|
|
|
|
/**
|
|
* Get the current txIEvalContext
|
|
*/
|
|
txIEvalContext* getEvalContext()
|
|
{
|
|
return mEvalContext;
|
|
}
|
|
|
|
|
|
/**
|
|
* More other functions
|
|
*/
|
|
void receiveError(String& errorMessage)
|
|
{
|
|
receiveError(errorMessage, NS_ERROR_FAILURE);
|
|
}
|
|
|
|
/**
|
|
* Returns a FunctionCall which has the given name.
|
|
* @return the FunctionCall for the function with the given name.
|
|
*/
|
|
nsresult resolveFunctionCall(txAtom* aName, PRInt32 aID,
|
|
Element* aElem, FunctionCall*& aFunction);
|
|
|
|
#ifdef TX_EXE
|
|
txIOutputXMLEventHandler* mOutputHandler;
|
|
#else
|
|
nsCOMPtr<txIOutputXMLEventHandler> mOutputHandler;
|
|
#endif
|
|
txXMLEventHandler* mResultHandler;
|
|
|
|
txIOutputHandlerFactory* mOutputHandlerFactory;
|
|
|
|
private:
|
|
|
|
class MatchableTemplate {
|
|
public:
|
|
MatchableTemplate(Node* aTemplate, txPattern* aPattern,
|
|
double aPriority)
|
|
: mTemplate(aTemplate), mMatch(aPattern), mPriority(aPriority)
|
|
{
|
|
}
|
|
Node* mTemplate;
|
|
txPattern* mMatch;
|
|
double mPriority;
|
|
};
|
|
|
|
class GlobalVariableValue : public TxObject {
|
|
public:
|
|
GlobalVariableValue(ExprResult* aValue = 0)
|
|
: mValue(aValue), mFlags(nonOwned)
|
|
{
|
|
}
|
|
virtual ~GlobalVariableValue();
|
|
|
|
ExprResult* mValue;
|
|
char mFlags;
|
|
enum _flags
|
|
{
|
|
nonOwned = 0,
|
|
evaluating,
|
|
owned
|
|
};
|
|
};
|
|
|
|
/**
|
|
* The list of ErrorObservers registered with this ProcessorState
|
|
*/
|
|
List errorObservers;
|
|
|
|
/**
|
|
* Stack of URIs for currently entered stylesheets
|
|
*/
|
|
Stack enteredStylesheets;
|
|
|
|
/**
|
|
* List of import containers. Sorted by ascending import precedence
|
|
*/
|
|
txList mImportFrames;
|
|
|
|
/**
|
|
* The output format used when serializing the result
|
|
*/
|
|
txOutputFormat mOutputFormat;
|
|
|
|
/**
|
|
* The set of loaded documents. This includes both document() loaded
|
|
* documents and xsl:include/xsl:import'ed documents.
|
|
*/
|
|
NamedMap loadedDocuments;
|
|
|
|
/**
|
|
* The set of all available keys
|
|
*/
|
|
txExpandedNameMap mXslKeys;
|
|
|
|
/**
|
|
* The set of all avalible decimalformats
|
|
*/
|
|
txExpandedNameMap mDecimalFormats;
|
|
|
|
/**
|
|
* Default decimal-format
|
|
*/
|
|
txDecimalFormat mDefaultDecimalFormat;
|
|
|
|
/**
|
|
* List of hashes with parsed expression. Every listitem holds the
|
|
* expressions for an attribute name
|
|
*/
|
|
Map mExprHashes[3];
|
|
|
|
/**
|
|
* List of hashes with parsed patterns. Every listitem holds the
|
|
* patterns for an attribute name
|
|
*/
|
|
Map mPatternHashes[2];
|
|
|
|
/**
|
|
* Current txIEvalContext*
|
|
*/
|
|
txIEvalContext* mEvalContext;
|
|
|
|
/**
|
|
* Current template rule
|
|
*/
|
|
TemplateRule* mCurrentTemplateRule;
|
|
|
|
/**
|
|
* Top of stack of local variable-bindings
|
|
*/
|
|
txVariableMap* mLocalVariables;
|
|
|
|
/**
|
|
* Map of values of global variables
|
|
*/
|
|
txExpandedNameMap mGlobalVariableValues;
|
|
|
|
Document* mSourceDocument;
|
|
Document* xslDocument;
|
|
|
|
/**
|
|
* Document used to create RTFs
|
|
*/
|
|
Document* mRTFDocument;
|
|
};
|
|
|
|
/**
|
|
* txNameTestItem holds both an ElementExpr and a bool for use in
|
|
* whitespace stripping.
|
|
*/
|
|
class txNameTestItem {
|
|
public:
|
|
txNameTestItem(txAtom* aPrefix, txAtom* aLocalName, PRInt32 aNSID,
|
|
MBool stripSpace)
|
|
: mNameTest(aPrefix, aLocalName, aNSID, Node::ELEMENT_NODE),
|
|
mStrips(stripSpace)
|
|
{
|
|
}
|
|
|
|
MBool matches(Node* aNode, txIMatchContext* aContext) {
|
|
return mNameTest.matches(aNode, aContext);
|
|
}
|
|
|
|
MBool stripsSpace() {
|
|
return mStrips;
|
|
}
|
|
|
|
double getDefaultPriority() {
|
|
return mNameTest.getDefaultPriority();
|
|
}
|
|
|
|
protected:
|
|
txNameTest mNameTest;
|
|
MBool mStrips;
|
|
};
|
|
|
|
/**
|
|
* txPSParseContext
|
|
* a txIParseContext forwarding all but resolveNamespacePrefix
|
|
* to a ProcessorState
|
|
*/
|
|
class txPSParseContext : public txIParseContext {
|
|
public:
|
|
txPSParseContext(ProcessorState* aPS, Element* aStyleNode)
|
|
: mPS(aPS), mStyle(aStyleNode)
|
|
{
|
|
}
|
|
|
|
~txPSParseContext()
|
|
{
|
|
}
|
|
|
|
nsresult resolveNamespacePrefix(txAtom* aPrefix, PRInt32& aID);
|
|
nsresult resolveFunctionCall(txAtom* aName, PRInt32 aID,
|
|
FunctionCall*& aFunction);
|
|
void receiveError(const String& aMsg, nsresult aRes);
|
|
|
|
protected:
|
|
ProcessorState* mPS;
|
|
Element* mStyle;
|
|
};
|
|
|
|
#endif
|
|
|