зеркало из https://github.com/mozilla/pjs.git
Implement xsl:import. This dosn't implement any import precedence but gives us the infrastructure to do so.
b=78068 r=peterv sr=shaver
This commit is contained in:
Родитель
bf67b32c16
Коммит
04aa8602af
|
@ -65,7 +65,7 @@ const short URIUtils::PATH_MODE = 4;
|
|||
* found
|
||||
**/
|
||||
istream* URIUtils::getInputStream
|
||||
(String& href, String& errMsg)
|
||||
(const String& href, String& errMsg)
|
||||
{
|
||||
|
||||
istream* inStream = 0;
|
||||
|
|
|
@ -78,7 +78,7 @@ public:
|
|||
|
||||
|
||||
static istream* getInputStream
|
||||
(String& href, String& errMsg);
|
||||
(const String& href, String& errMsg);
|
||||
|
||||
/**
|
||||
* Returns the document base of the href argument
|
||||
|
|
|
@ -65,16 +65,12 @@ XMLParser::~XMLParser()
|
|||
} //-- ~XMLParser
|
||||
|
||||
Document* XMLParser::getDocumentFromURI(const String& href,
|
||||
const String& baseUri,
|
||||
Document* aLoader,
|
||||
String& errMsg)
|
||||
{
|
||||
String documentURL;
|
||||
URIUtils::resolveHref(href, baseUri, documentURL);
|
||||
|
||||
#ifndef TX_EXE
|
||||
nsCOMPtr<nsIURI> documentURI;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(documentURI), documentURL.getConstNSString());
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(documentURI), href.getConstNSString());
|
||||
NS_ENSURE_SUCCESS(rv, NULL);
|
||||
|
||||
nsCOMPtr<nsISyncLoader> loader = do_CreateInstance(TRANSFORMIIX_SYNCLOADER_CONTRACTID, &rv);
|
||||
|
@ -92,11 +88,11 @@ Document* XMLParser::getDocumentFromURI(const String& href,
|
|||
|
||||
return new Document(theDocument);
|
||||
#else
|
||||
istream* xslInput = URIUtils::getInputStream(documentURL, errMsg);
|
||||
istream* xslInput = URIUtils::getInputStream(href, errMsg);
|
||||
|
||||
Document* resultDoc = 0;
|
||||
if ( xslInput ) {
|
||||
resultDoc = parse(*xslInput, documentURL);
|
||||
resultDoc = parse(*xslInput, href);
|
||||
delete xslInput;
|
||||
}
|
||||
if (!resultDoc) {
|
||||
|
|
|
@ -67,7 +67,7 @@ class XMLParser
|
|||
XMLParser();
|
||||
~XMLParser();
|
||||
|
||||
Document* getDocumentFromURI(const String& href, const String& baseUri, Document* aLoader, String& errMsg);
|
||||
Document* getDocumentFromURI(const String& href, Document* aLoader, String& errMsg);
|
||||
#ifdef TX_EXE
|
||||
Document* parse(istream& inputStream, const String& uri);
|
||||
const String& getErrorString();
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "VariableBinding.h"
|
||||
#include "ExprResult.h"
|
||||
#include "Names.h"
|
||||
#include "XMLParser.h"
|
||||
#ifndef TX_EXE
|
||||
// #include "nslog.h"
|
||||
// #define PRINTF NS_LOG_PRINTF(XPATH)
|
||||
|
@ -91,19 +92,6 @@ ProcessorState::~ProcessorState() {
|
|||
delete (NamedMap*) variableSets.pop();
|
||||
}
|
||||
|
||||
//-- delete includes
|
||||
StringList* keys = includes.keys();
|
||||
StringListIterator* iter = keys->iterator();
|
||||
while (iter->hasNext()) {
|
||||
String* key = iter->next();
|
||||
TxObjectWrapper* objWrapper
|
||||
= (TxObjectWrapper*)includes.remove(*key);
|
||||
delete (Document*)objWrapper->object;
|
||||
delete objWrapper;
|
||||
}
|
||||
delete iter;
|
||||
delete keys;
|
||||
|
||||
//-- clean up XSLT actions stack
|
||||
while (currentAction) {
|
||||
XSLTAction* item = currentAction;
|
||||
|
@ -112,6 +100,18 @@ ProcessorState::~ProcessorState() {
|
|||
item->prev = 0;
|
||||
delete item;
|
||||
}
|
||||
|
||||
// Delete all importFrames
|
||||
txListIterator iter(&importFrames);
|
||||
while (iter.hasNext())
|
||||
delete (ImportFrame*)iter.next();
|
||||
|
||||
// Make sure that xslDocument and mSourceDocument isn't deleted along with
|
||||
// the rest of the documents in the loadedDocuments hash
|
||||
loadedDocuments.remove(xslDocument->getBaseURI());
|
||||
loadedDocuments.remove(mSourceDocument->getBaseURI());
|
||||
|
||||
|
||||
} //-- ~ProcessorState
|
||||
|
||||
|
||||
|
@ -160,18 +160,6 @@ void ProcessorState::addErrorObserver(ErrorObserver& errorObserver) {
|
|||
errorObservers.add(&errorObserver);
|
||||
} //-- addErrorObserver
|
||||
|
||||
/**
|
||||
* Adds the given XSL document to the list of includes
|
||||
* The href is used as a key for the include, to prevent
|
||||
* including the same document more than once
|
||||
**/
|
||||
void ProcessorState::addInclude(const String& href, Document* xslDocument) {
|
||||
TxObjectWrapper* objWrapper = new TxObjectWrapper();
|
||||
objWrapper->object = xslDocument;
|
||||
includes.put(href, objWrapper);
|
||||
} //-- addInclude
|
||||
|
||||
|
||||
/**
|
||||
* Adds the given template to the list of templates to process
|
||||
* @param xslTemplate, the Element to add as a template
|
||||
|
@ -307,6 +295,78 @@ Node* ProcessorState::copyNode(Node* node) {
|
|||
return 0;
|
||||
} //-- copyNode
|
||||
|
||||
/*
|
||||
* 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* ProcessorState::retrieveDocument(const String& uri, const String& baseUri)
|
||||
{
|
||||
String absUrl, frag, docUrl;
|
||||
URIUtils::resolveHref(uri, baseUri, absUrl);
|
||||
URIUtils::getFragmentIdentifier(absUrl, frag);
|
||||
URIUtils::getDocumentURI(absUrl, docUrl);
|
||||
|
||||
// try to get already loaded document
|
||||
Document* xmlDoc = (Document*)loadedDocuments.get(docUrl);
|
||||
|
||||
if (!xmlDoc) {
|
||||
// open URI
|
||||
String errMsg;
|
||||
XMLParser xmlParser;
|
||||
|
||||
NS_ASSERTION(currentAction && currentAction->node,
|
||||
"missing currentAction->node");
|
||||
|
||||
Document* loaderDoc;
|
||||
if (currentAction->node->getNodeType() == Node::DOCUMENT_NODE)
|
||||
loaderDoc = (Document*)currentAction->node;
|
||||
else
|
||||
loaderDoc = currentAction->node->getOwnerDocument();
|
||||
|
||||
xmlDoc = xmlParser.getDocumentFromURI(docUrl, loaderDoc, errMsg);
|
||||
|
||||
if (!xmlDoc) {
|
||||
String err("Couldn't load document '");
|
||||
err.append(docUrl);
|
||||
err.append("': ");
|
||||
err.append(errMsg);
|
||||
recieveError(err, ErrorObserver::WARNING);
|
||||
return NULL;
|
||||
}
|
||||
// add to list of documents
|
||||
loadedDocuments.put(docUrl, xmlDoc);
|
||||
}
|
||||
|
||||
// return element with supplied id if supplied
|
||||
if (frag.length())
|
||||
return xmlDoc->getElementById(frag);
|
||||
|
||||
return xmlDoc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return stack of urls of currently entered stylesheets
|
||||
*/
|
||||
Stack* ProcessorState::getEnteredStylesheets()
|
||||
{
|
||||
return &enteredStylesheets;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return list of import containers
|
||||
*/
|
||||
List* ProcessorState::getImportFrames()
|
||||
{
|
||||
return &importFrames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds a template for the given Node. Only templates with
|
||||
* a mode attribute equal to the given mode will be searched.
|
||||
|
@ -394,19 +454,6 @@ Stack* ProcessorState::getDefaultNSURIStack() {
|
|||
return &defaultNameSpaceURIStack;
|
||||
} //-- getDefaultNSURIStack
|
||||
|
||||
/**
|
||||
* @return the included xsl document that was associated with the
|
||||
* given href, or null if no document is found
|
||||
**/
|
||||
Document* ProcessorState::getInclude(const String& href) {
|
||||
TxObjectWrapper* objWrapper = (TxObjectWrapper*)includes.get(href);
|
||||
Document* doc = 0;
|
||||
if (objWrapper) {
|
||||
doc = (Document*) objWrapper->object;
|
||||
}
|
||||
return doc;
|
||||
} //-- getInclude(String)
|
||||
|
||||
Expr* ProcessorState::getExpr(const String& pattern) {
|
||||
// NS_IMPL_LOG(XPATH)
|
||||
// PRINTF("Resolving XPath Expr %s",pattern.toCharArray());
|
||||
|
@ -668,30 +715,6 @@ void ProcessorState::shouldStripSpace(String& names, MBool shouldStrip) {
|
|||
|
||||
} //-- stripSpace
|
||||
|
||||
/**
|
||||
* Adds a document to set of loaded documents
|
||||
**/
|
||||
void ProcessorState::addLoadedDocument(Document* doc, String& url) {
|
||||
String docUrl;
|
||||
URIUtils::getDocumentURI(url, docUrl);
|
||||
loadedDocuments.put(docUrl, doc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a loaded document given it's url. NULL if no such doc exists
|
||||
**/
|
||||
Document* ProcessorState::getLoadedDocument(String& url) {
|
||||
String docUrl;
|
||||
URIUtils::getDocumentURI(url, docUrl);
|
||||
if ((mMainStylesheetURL.length() > 0) && docUrl.isEqual(mMainStylesheetURL)) {
|
||||
return xslDocument;
|
||||
}
|
||||
else if ((mMainSourceURL.length() > 0) && docUrl.isEqual(mMainSourceURL)) {
|
||||
return mSourceDocument;
|
||||
}
|
||||
return (Document*)loadedDocuments.get(docUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the supplied xsl:key to the set of keys
|
||||
**/
|
||||
|
@ -987,11 +1010,11 @@ void ProcessorState::initialize() {
|
|||
//-- determine xsl properties
|
||||
Element* element = NULL;
|
||||
if (mSourceDocument) {
|
||||
mMainSourceURL = mSourceDocument->getBaseURI();
|
||||
loadedDocuments.put(mSourceDocument->getBaseURI(), mSourceDocument);
|
||||
}
|
||||
if (xslDocument) {
|
||||
element = xslDocument->getDocumentElement();
|
||||
mMainStylesheetURL = xslDocument->getBaseURI();
|
||||
loadedDocuments.put(xslDocument->getBaseURI(), xslDocument);
|
||||
}
|
||||
if ( element ) {
|
||||
|
||||
|
|
|
@ -79,14 +79,6 @@ public:
|
|||
**/
|
||||
void addErrorObserver(ErrorObserver& errorObserver);
|
||||
|
||||
|
||||
/**
|
||||
* Adds the given XSL document to the list of includes
|
||||
* The href is used as a key for the include, to prevent
|
||||
* including the same document more than once
|
||||
**/
|
||||
void addInclude(const String& href, Document* xslDocument);
|
||||
|
||||
/**
|
||||
* Adds the given template to the list of templates to process
|
||||
* @param xslTemplate, the Element to add as a template
|
||||
|
@ -126,12 +118,6 @@ public:
|
|||
**/
|
||||
Stack* getDefaultNSURIStack();
|
||||
|
||||
/**
|
||||
* @return the included xsl document that was associated with the
|
||||
* given href, or null if no document is found
|
||||
**/
|
||||
Document* getInclude(const String& href);
|
||||
|
||||
/**
|
||||
* Returns the template associated with the given name, or
|
||||
* null if not template is found
|
||||
|
@ -179,6 +165,45 @@ public:
|
|||
|
||||
String& getXSLNamespace();
|
||||
|
||||
/**
|
||||
* 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();
|
||||
|
||||
/**
|
||||
* Contain information that is import precedence dependant.
|
||||
**/
|
||||
struct ImportFrame {
|
||||
// The following stuff is missing here:
|
||||
|
||||
// ImportFrame(?) for xsl:apply-imports
|
||||
// Nametests for xsl:strip-space and xsl:preserve-space
|
||||
// Template rules
|
||||
// Names templates
|
||||
// Namespace aliases (xsl:namespace-alias)
|
||||
// Named attribute sets
|
||||
// Toplevel variables/parameters
|
||||
// Output specifier (xsl:output)
|
||||
};
|
||||
|
||||
/**
|
||||
* Return list of import containers
|
||||
**/
|
||||
List* getImportFrames();
|
||||
|
||||
/**
|
||||
* Finds a template for the given Node. Only templates without
|
||||
* a mode attribute will be searched.
|
||||
|
@ -249,16 +274,6 @@ public:
|
|||
**/
|
||||
void shouldStripSpace(String& names, MBool shouldStrip);
|
||||
|
||||
/**
|
||||
* Adds a document to set of loaded documents
|
||||
**/
|
||||
void addLoadedDocument(Document* doc, String& location);
|
||||
|
||||
/**
|
||||
* Returns a loaded document given it's url. NULL if no such doc exists
|
||||
**/
|
||||
Document* getLoadedDocument(String& url);
|
||||
|
||||
/**
|
||||
* Adds the supplied xsl:key to the set of keys
|
||||
**/
|
||||
|
@ -367,10 +382,14 @@ private:
|
|||
List errorObservers;
|
||||
|
||||
/**
|
||||
* A map for included stylesheets
|
||||
* (used for deletion when processing is done)
|
||||
* Stack of URIs for currently entered stylesheets
|
||||
**/
|
||||
NamedMap includes;
|
||||
Stack enteredStylesheets;
|
||||
|
||||
/**
|
||||
* List of import containers. Sorted by ascending import precedence
|
||||
**/
|
||||
List importFrames;
|
||||
|
||||
/**
|
||||
* A map for named attribute sets
|
||||
|
@ -409,7 +428,8 @@ private:
|
|||
NodeSet templates;
|
||||
|
||||
/**
|
||||
* the set of loaded documents
|
||||
* The set of loaded documents. This includes both document() loaded
|
||||
* documents and xsl:include/xsl:import'ed documents.
|
||||
**/
|
||||
NamedMap loadedDocuments;
|
||||
|
||||
|
@ -423,8 +443,6 @@ private:
|
|||
Stack nodeSetStack;
|
||||
Document* mSourceDocument;
|
||||
Document* xslDocument;
|
||||
String mMainSourceURL;
|
||||
String mMainStylesheetURL;
|
||||
Document* resultDocument;
|
||||
NamedMap exprHash;
|
||||
NamedMap patternExprHash;
|
||||
|
|
|
@ -108,6 +108,7 @@ XSLTProcessor::XSLTProcessor() {
|
|||
xslTypes.put(ELEMENT, new XSLType(XSLType::ELEMENT));
|
||||
xslTypes.put(FOR_EACH, new XSLType(XSLType::FOR_EACH));
|
||||
xslTypes.put(IF, new XSLType(XSLType::IF));
|
||||
xslTypes.put(IMPORT, new XSLType(XSLType::IMPORT));
|
||||
xslTypes.put(INCLUDE, new XSLType(XSLType::INCLUDE));
|
||||
xslTypes.put(KEY, new XSLType(XSLType::KEY));
|
||||
xslTypes.put(MESSAGE, new XSLType(XSLType::MESSAGE));
|
||||
|
@ -394,13 +395,17 @@ Document* XSLTProcessor::process(istream& xmlInput, String& xmlFilename) {
|
|||
**/
|
||||
void XSLTProcessor::processTopLevel(Document* aSource,
|
||||
Document* aStylesheet,
|
||||
ListIterator* importFrame,
|
||||
ProcessorState* aPs)
|
||||
{
|
||||
NS_ASSERTION(aStylesheet, "processTopLevel called without stylesheet");
|
||||
if (!aStylesheet)
|
||||
return;
|
||||
|
||||
processTopLevel(aSource, aStylesheet->getDocumentElement(), aPs);
|
||||
processTopLevel(aSource,
|
||||
aStylesheet->getDocumentElement(),
|
||||
importFrame,
|
||||
aPs);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -408,6 +413,7 @@ void XSLTProcessor::processTopLevel(Document* aSource,
|
|||
**/
|
||||
void XSLTProcessor::processTopLevel(Document* aSource,
|
||||
Element* aStylesheet,
|
||||
ListIterator* importFrame,
|
||||
ProcessorState* aPs)
|
||||
{
|
||||
// Index templates and process top level xsl elements
|
||||
|
@ -416,8 +422,39 @@ void XSLTProcessor::processTopLevel(Document* aSource,
|
|||
return;
|
||||
|
||||
NS_ASSERTION(aSource, "processTopLevel called without source document");
|
||||
|
||||
|
||||
MBool importsDone = MB_FALSE;
|
||||
Node* node = aStylesheet->getFirstChild();
|
||||
while (node && !importsDone) {
|
||||
if (node->getNodeType() == Node::ELEMENT_NODE) {
|
||||
Element* element = (Element*)node;
|
||||
String name = element->getNodeName();
|
||||
switch (getElementType(name, aPs)) {
|
||||
case XSLType::IMPORT :
|
||||
{
|
||||
String href;
|
||||
URIUtils::resolveHref(element->getAttribute(HREF_ATTR),
|
||||
element->getBaseURI(),
|
||||
href);
|
||||
|
||||
importFrame->addAfter(new ProcessorState::ImportFrame);
|
||||
importFrame->next();
|
||||
|
||||
processInclude(href, aSource, importFrame, aPs);
|
||||
|
||||
importFrame->previous();
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
importsDone = MB_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!importsDone)
|
||||
node = node->getNextSibling();
|
||||
}
|
||||
|
||||
while (node) {
|
||||
if (node->getNodeType() == Node::ELEMENT_NODE) {
|
||||
Element* element = (Element*)node;
|
||||
|
@ -439,41 +476,20 @@ void XSLTProcessor::processTopLevel(Document* aSource,
|
|||
bindVariable(name, exprResult, MB_TRUE, aPs);
|
||||
break;
|
||||
}
|
||||
case XSLType::IMPORT :
|
||||
{
|
||||
notifyError("xsl:import only allowed at top of stylesheet");
|
||||
break;
|
||||
}
|
||||
case XSLType::INCLUDE :
|
||||
{
|
||||
String href;
|
||||
URIUtils::resolveHref(element->getAttribute(HREF_ATTR),
|
||||
element->getBaseURI(),
|
||||
href);
|
||||
|
||||
String href = element->getAttribute(HREF_ATTR);
|
||||
//-- Read in XSL document
|
||||
|
||||
if (aPs->getInclude(href)) {
|
||||
/* XXX this is wrong, it's allowed to include one stylesheet multiple
|
||||
times but we should build some sort of stack to make sure that we
|
||||
don't have circular inclusions */
|
||||
String err("stylesheet already included: ");
|
||||
err.append(href);
|
||||
notifyError(err, ErrorObserver::WARNING);
|
||||
break;
|
||||
}
|
||||
|
||||
String errMsg;
|
||||
XMLParser xmlParser;
|
||||
|
||||
Document* xslDoc = xmlParser.getDocumentFromURI(href, element->getBaseURI(), aStylesheet->getOwnerDocument(), errMsg);
|
||||
|
||||
if (!xslDoc) {
|
||||
String err("error including XSL stylesheet: ");
|
||||
err.append(href);
|
||||
err.append("; ");
|
||||
err.append(errMsg);
|
||||
notifyError(err);
|
||||
}
|
||||
else {
|
||||
//-- add stylesheet to list of includes
|
||||
aPs->addInclude(href, xslDoc);
|
||||
processTopLevel(aSource, xslDoc, aPs);
|
||||
}
|
||||
processInclude(href, aSource, importFrame, aPs);
|
||||
break;
|
||||
|
||||
}
|
||||
case XSLType::KEY :
|
||||
{
|
||||
|
@ -567,6 +583,64 @@ void XSLTProcessor::processTopLevel(Document* aSource,
|
|||
|
||||
} //-- process(Document, ProcessorState)
|
||||
|
||||
/*
|
||||
* Processes an include or import stylesheet
|
||||
* @param aHref URI of stylesheet to process
|
||||
* @param aSource source document
|
||||
* @param aImportFrame current importFrame iterator
|
||||
* @param aPs current ProcessorState
|
||||
*/
|
||||
void XSLTProcessor::processInclude(String& aHref,
|
||||
Document* aSource,
|
||||
ListIterator* aImportFrame,
|
||||
ProcessorState* aPs)
|
||||
{
|
||||
// make sure the include isn't included yet
|
||||
StackIterator* iter = aPs->getEnteredStylesheets()->iterator();
|
||||
if (!iter) {
|
||||
// XXX report out of memory
|
||||
return;
|
||||
}
|
||||
|
||||
while(iter->hasNext()) {
|
||||
if (((String*)iter->next())->isEqual(aHref)) {
|
||||
String err("Stylesheet includes itself. URI: ");
|
||||
err.append(aHref);
|
||||
notifyError(err);
|
||||
delete iter;
|
||||
return;
|
||||
}
|
||||
}
|
||||
aPs->getEnteredStylesheets()->push(&aHref);
|
||||
delete iter;
|
||||
|
||||
// Load XSL document
|
||||
Node* stylesheet = aPs->retrieveDocument(aHref, NULL_STRING);
|
||||
if (!stylesheet) {
|
||||
String err("Unable to load included stylesheet ");
|
||||
err.append(aHref);
|
||||
notifyError(err);
|
||||
aPs->getEnteredStylesheets()->pop();
|
||||
return;
|
||||
}
|
||||
|
||||
switch(stylesheet->getNodeType()) {
|
||||
case Node::DOCUMENT_NODE :
|
||||
processTopLevel(aSource, (Document*)stylesheet, aImportFrame, aPs);
|
||||
break;
|
||||
case Node::ELEMENT_NODE :
|
||||
processTopLevel(aSource, (Element*)stylesheet, aImportFrame, aPs);
|
||||
break;
|
||||
default:
|
||||
// This should never happen
|
||||
String err("Unsupported fragment identifier");
|
||||
notifyError(err);
|
||||
break;
|
||||
}
|
||||
|
||||
aPs->getEnteredStylesheets()->pop();
|
||||
}
|
||||
|
||||
#ifdef TX_EXE
|
||||
/**
|
||||
* Processes the given XML Document using the given XSL document
|
||||
|
@ -597,7 +671,10 @@ Document* XSLTProcessor::process
|
|||
//- index templates and process top level xsl elements -/
|
||||
//-------------------------------------------------------/
|
||||
|
||||
processTopLevel(&xmlDocument, &xslDocument, &ps);
|
||||
ListIterator importFrame(ps.getImportFrames());
|
||||
importFrame.addAfter(new ProcessorState::ImportFrame);
|
||||
importFrame.next();
|
||||
processTopLevel(&xmlDocument, &xslDocument, &importFrame, &ps);
|
||||
|
||||
//----------------------------------------/
|
||||
//- Process root of XML source document -/
|
||||
|
@ -640,7 +717,10 @@ void XSLTProcessor::process
|
|||
//- index templates and process top level xsl elements -/
|
||||
//-------------------------------------------------------/
|
||||
|
||||
processTopLevel(&xmlDocument, &xslDocument, &ps);
|
||||
ListIterator importFrame(ps.getImportFrames());
|
||||
importFrame.addAfter(new ProcessorState::ImportFrame);
|
||||
importFrame.next();
|
||||
processTopLevel(&xmlDocument, &xslDocument, &importFrame, &ps);
|
||||
|
||||
//----------------------------------------/
|
||||
//- Process root of XML source document -/
|
||||
|
@ -1946,7 +2026,10 @@ XSLTProcessor::TransformDocument(nsIDOMNode* aSourceDOM,
|
|||
//------------------------------------------------------/
|
||||
//- index templates and process top level xsl elements -/
|
||||
//------------------------------------------------------/
|
||||
processTopLevel(sourceDocument, xslDocument, ps);
|
||||
ListIterator importFrame(ps->getImportFrames());
|
||||
importFrame.addAfter(new ProcessorState::ImportFrame);
|
||||
importFrame.next();
|
||||
processTopLevel(sourceDocument, xslDocument, &importFrame, ps);
|
||||
|
||||
//---------------------------------------/
|
||||
//- Process root of XML source document -/
|
||||
|
|
|
@ -343,8 +343,27 @@ private:
|
|||
**/
|
||||
void processDefaultTemplate(Node* node, ProcessorState* ps, String* mode);
|
||||
|
||||
void processTopLevel(Document* aSource, Document* aStylesheet, ProcessorState* aPs);
|
||||
void processTopLevel(Document* aSource, Element* aStylesheet, ProcessorState* aPs);
|
||||
void processTopLevel(Document* aSource,
|
||||
Document* aStylesheet,
|
||||
ListIterator* importFrame,
|
||||
ProcessorState* aPs);
|
||||
|
||||
void processTopLevel(Document* aSource,
|
||||
Element* aStylesheet,
|
||||
ListIterator* importFrame,
|
||||
ProcessorState* aPs);
|
||||
|
||||
/*
|
||||
* Processes an include or import stylesheet
|
||||
* @param aHref URI of stylesheet to process
|
||||
* @param aSource source document
|
||||
* @param aImportFrame current importFrame iterator
|
||||
* @param aPs current ProcessorState
|
||||
*/
|
||||
void processInclude(String& aHref,
|
||||
Document* aSource,
|
||||
ListIterator* aImportFrame,
|
||||
ProcessorState* aPs);
|
||||
|
||||
ExprResult* processVariable(Node* node, Element* xslVariable, ProcessorState* ps);
|
||||
|
||||
|
@ -375,6 +394,7 @@ public:
|
|||
COPY_OF,
|
||||
ELEMENT,
|
||||
IF,
|
||||
IMPORT,
|
||||
INCLUDE,
|
||||
KEY,
|
||||
FOR_EACH,
|
||||
|
|
|
@ -37,9 +37,7 @@
|
|||
*/
|
||||
|
||||
#include "XSLTFunctions.h"
|
||||
#include "XMLParser.h"
|
||||
#include "XMLDOMUtils.h"
|
||||
#include "URIUtils.h"
|
||||
#include "Names.h"
|
||||
|
||||
/*
|
||||
|
@ -108,23 +106,23 @@ ExprResult* DocumentFunctionCall::evaluate(Node* context, ContextState* cs)
|
|||
if (!baseURISet) {
|
||||
// if the second argument wasn't specified, use
|
||||
// the baseUri of node itself
|
||||
retrieveDocument(uriStr, node->getBaseURI(), *nodeSet, cs);
|
||||
nodeSet->add(mProcessorState->retrieveDocument(uriStr, node->getBaseURI()));
|
||||
}
|
||||
else {
|
||||
retrieveDocument(uriStr, baseURI, *nodeSet, cs);
|
||||
nodeSet->add(mProcessorState->retrieveDocument(uriStr, baseURI));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// The first argument is not a NodeSet
|
||||
String uriStr;
|
||||
evaluateToString(param1, context, cs, uriStr);
|
||||
exprResult1->stringValue(uriStr);
|
||||
if (!baseURISet) {
|
||||
Node* xsltElement = mProcessorState->peekAction();
|
||||
retrieveDocument(uriStr, xsltElement->getBaseURI(), *nodeSet, cs);
|
||||
nodeSet->add(mProcessorState->retrieveDocument(uriStr, xsltElement->getBaseURI()));
|
||||
}
|
||||
else {
|
||||
retrieveDocument(uriStr, baseURI, *nodeSet, cs);
|
||||
nodeSet->add(mProcessorState->retrieveDocument(uriStr, baseURI));
|
||||
}
|
||||
}
|
||||
delete exprResult1;
|
||||
|
@ -133,63 +131,3 @@ ExprResult* DocumentFunctionCall::evaluate(Node* context, ContextState* cs)
|
|||
|
||||
return nodeSet;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve the document designated by the URI uri, using baseUri as base URI if
|
||||
* necessary, parses it as an XML document, and append the resulting document node
|
||||
* to resultNodeSet.
|
||||
*
|
||||
* @param uri the URI of the document to retrieve
|
||||
* @param baseUri the base URI used to resolve the URI if uri is relative
|
||||
* @param resultNodeSet the NodeSet to append the document to
|
||||
* @param cs the ContextState, used for reporting errors
|
||||
*/
|
||||
void DocumentFunctionCall::retrieveDocument(const String& uri,
|
||||
const String& baseUri,
|
||||
NodeSet& resultNodeSet,
|
||||
ContextState* cs)
|
||||
{
|
||||
String absUrl, frag;
|
||||
Document* xmlDoc;
|
||||
|
||||
URIUtils::resolveHref(uri, baseUri, absUrl);
|
||||
URIUtils::getFragmentIdentifier(absUrl, frag);
|
||||
|
||||
// try to get already loaded document
|
||||
xmlDoc = mProcessorState->getLoadedDocument(absUrl);
|
||||
|
||||
if (!xmlDoc) {
|
||||
// open URI
|
||||
String errMsg;
|
||||
XMLParser xmlParser;
|
||||
Node* xsltElement;
|
||||
|
||||
xsltElement = mProcessorState->peekAction();
|
||||
if (!xsltElement) {
|
||||
// no xslt element
|
||||
return;
|
||||
}
|
||||
|
||||
xmlDoc = xmlParser.getDocumentFromURI(absUrl, "", xsltElement->getOwnerDocument(), errMsg);
|
||||
if (!xmlDoc) {
|
||||
String err("error in document() function: ");
|
||||
err.append(errMsg);
|
||||
cs->recieveError(err);
|
||||
return;
|
||||
}
|
||||
// add to ProcessorState list of documents
|
||||
mProcessorState->addLoadedDocument(xmlDoc, absUrl);
|
||||
}
|
||||
|
||||
// append the document or the fragment to resultNodeSet
|
||||
if (frag.length() > 0) {
|
||||
Node* node = xmlDoc->getElementById(frag);
|
||||
if (node) {
|
||||
resultNodeSet.add(node);
|
||||
}
|
||||
}
|
||||
else {
|
||||
resultNodeSet.add(xmlDoc);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -62,7 +62,6 @@ public:
|
|||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
|
||||
private:
|
||||
void retrieveDocument(const String& uri,const String& baseUri, NodeSet &resultNodeSet, ContextState* cs);
|
||||
ProcessorState* mProcessorState;
|
||||
};
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче