From 1d75a78041cae0b3660c1829f38fbf1cd0bdca31 Mon Sep 17 00:00:00 2001 From: Alberto Massari <amassari@apache.org> Date: Mon, 12 Apr 2010 12:11:29 +0000 Subject: [PATCH] Restore the usage of the document fragment in XInclude processing to handle xi:include as root elements; delay the recursive expansion of includes until the document fragment has been placed in the final location [XERCESC-1918] git-svn-id: https://svn.apache.org/repos/asf/xerces/c/trunk@933210 13f79535-47bb-0310-9956-ffa450edef68 --- src/xercesc/xinclude/XIncludeUtils.cpp | 34 +++++++++++++++++++++----- 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/src/xercesc/xinclude/XIncludeUtils.cpp b/src/xercesc/xinclude/XIncludeUtils.cpp index 416e55555..5db22f174 100644 --- a/src/xercesc/xinclude/XIncludeUtils.cpp +++ b/src/xercesc/xinclude/XIncludeUtils.cpp @@ -247,6 +247,7 @@ XIncludeUtils::doDOMNodeXInclude(DOMNode *xincludeNode, DOMDocument *parsedDocum return false; } + RefVectorOf<DOMNode> delayedProcessing(12,false); if (includedDoc == NULL && includedText == NULL){ /* there was an error - this is now a resource error let's see if there is a fallback */ @@ -265,6 +266,7 @@ XIncludeUtils::doDOMNodeXInclude(DOMNode *xincludeNode, DOMDocument *parsedDocum XMLUri includedURI(fallback->getBaseURI()); if (fallback->hasChildNodes()){ + DOMDocumentFragment* frag = parsedDocument->createDocumentFragment(); DOMNode *child = fallback->getFirstChild(); /* add the content of the fallback element, and remove the fallback elem itself */ for ( ; child != NULL ; child=child->getNextSibling()){ @@ -287,10 +289,19 @@ XIncludeUtils::doDOMNodeXInclude(DOMNode *xincludeNode, DOMDocument *parsedDocum ((DOMElement*)newNode)->setAttribute(fgXIBaseAttrName, xil.getLocation()); } } - includeParent->insertBefore (newNode, xincludeNode); - parseDOMNodeDoingXInclude(newNode, parsedDocument, entityResolver); + DOMNode *newChild = frag->appendChild(newNode); + // don't process the node now, wait until it is placed in the final position + delayedProcessing.addElement(newChild); + //parseDOMNodeDoingXInclude(newChild, parsedDocument, entityResolver); + } + includeParent->replaceChild(frag, xincludeNode); + frag->release(); + + for(XMLSize_t i=0;i<delayedProcessing.size();i++) + { + DOMNode* childNode=delayedProcessing.elementAt(i); + parseDOMNodeDoingXInclude(childNode, parsedDocument, entityResolver); } - includeParent->removeChild(xincludeNode); modifiedNode = true; } else { /* empty fallback element - simply remove it! */ @@ -307,6 +318,8 @@ XIncludeUtils::doDOMNodeXInclude(DOMNode *xincludeNode, DOMDocument *parsedDocum /* record the successful include while we process the children */ addDocumentURIToCurrentInclusionHistoryStack(hrefLoc.getLocation()); + DOMDocumentFragment* frag = parsedDocument->createDocumentFragment(); + /* need to import the document prolog here */ DOMNode *child = includedDoc->getFirstChild(); for (; child != NULL; child = child->getNextSibling()) { if (child->getNodeType() == DOMNode::DOCUMENT_TYPE_NODE) @@ -373,10 +386,19 @@ XIncludeUtils::doDOMNodeXInclude(DOMNode *xincludeNode, DOMDocument *parsedDocum } } DOMNode *newNode = parsedDocument->importNode(child, true); - includeParent->insertBefore (newNode, xincludeNode); - parseDOMNodeDoingXInclude(newNode, parsedDocument, entityResolver); + DOMNode *newChild = frag->appendChild(newNode); + // don't process the node now, wait until it is placed in the final position + delayedProcessing.addElement(newChild); + //parseDOMNodeDoingXInclude(newChild, parsedDocument, entityResolver); + } + includeParent->replaceChild(frag, xincludeNode); + frag->release(); + + for(XMLSize_t i=0;i<delayedProcessing.size();i++) + { + DOMNode* childNode=delayedProcessing.elementAt(i); + parseDOMNodeDoingXInclude(childNode, parsedDocument, entityResolver); } - includeParent->removeChild(xincludeNode); popFromCurrentInclusionHistoryStack(NULL); modifiedNode = true; } else if (includedText){ -- GitLab