?? domnormalizer.cpp
字號:
/* * Copyright 2001-2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */#include <xercesc/dom/DOMAttr.hpp>#include <xercesc/dom/DOMNode.hpp>#include <xercesc/dom/DOMErrorHandler.hpp>#include <xercesc/dom/DOMError.hpp>#include <xercesc/dom/DOMText.hpp>#include <xercesc/framework/XMLBuffer.hpp>#include <xercesc/util/Mutexes.hpp>#include <xercesc/util/PlatformUtils.hpp>#include <xercesc/util/XMLMsgLoader.hpp>#include <xercesc/util/XMLRegisterCleanup.hpp>#include <xercesc/util/XMLString.hpp>#include <xercesc/util/XMLUni.hpp>#include <xercesc/util/XMLUniDefs.hpp>#include "DOMConfigurationImpl.hpp"#include "DOMDocumentImpl.hpp"#include "DOMElementImpl.hpp"#include "DOMErrorImpl.hpp"#include "DOMEntityReferenceImpl.hpp"#include "DOMLocatorImpl.hpp"#include "DOMNormalizer.hpp"#include "DOMTextImpl.hpp"XERCES_CPP_NAMESPACE_BEGIN// ---------------------------------------------------------------------------// Local static data// ---------------------------------------------------------------------------static bool sRegistered = false;static XMLMutex* sNormalizerMutex = 0;static XMLRegisterCleanup normalizerMutexCleanup;static XMLMsgLoader* gMsgLoader = 0;static XMLRegisterCleanup cleanupMsgLoader;// ---------------------------------------------------------------------------// Local, static functions// ---------------------------------------------------------------------------// Cleanup for the message loadervoid DOMNormalizer::reinitMsgLoader(){ delete gMsgLoader; gMsgLoader = 0;}// Cleanup for the normalizer mutexvoid DOMNormalizer::reinitNormalizerMutex(){ delete sNormalizerMutex; sNormalizerMutex = 0; sRegistered = false;}//// We need to fault in this mutex. But, since its used for synchronization// itself, we have to do this the low level way using a compare and swap.//static XMLMutex& gNormalizerMutex(){ if (!sNormalizerMutex) { XMLMutexLock lock(XMLPlatformUtils::fgAtomicMutex); // If we got here first, then register it and set the registered flag if (!sRegistered) { sNormalizerMutex = new XMLMutex; normalizerMutexCleanup.registerCleanup(DOMNormalizer::reinitNormalizerMutex); sRegistered = true; } } return *sNormalizerMutex;}static XMLMsgLoader& gNormalizerMsgLoader(){ if (!gMsgLoader) { XMLMutexLock lockInit(&gNormalizerMutex()); // If we haven't loaded our message yet, then do that if (!gMsgLoader) { gMsgLoader = XMLPlatformUtils::loadMsgSet(XMLUni::fgXMLErrDomain); if (!gMsgLoader) XMLPlatformUtils::panic(PanicHandler::Panic_CantLoadMsgDomain); // Register this object to be cleaned up at termination cleanupMsgLoader.registerCleanup(DOMNormalizer::reinitMsgLoader); } } return *gMsgLoader;}DOMNormalizer::DOMNormalizer(MemoryManager* const manager) : fDocument(0) , fConfiguration(0) , fErrorHandler(0) , fNSScope(0) , fNewNamespaceCount(1) , fMemoryManager(manager){ fNSScope = new (fMemoryManager) InScopeNamespaces(fMemoryManager);}DOMNormalizer::~DOMNormalizer() { delete fNSScope;}void DOMNormalizer::normalizeDocument(DOMDocumentImpl *doc) { fDocument = doc; fConfiguration = (DOMConfigurationImpl*)doc->getDOMConfiguration(); DOMConfigurationImpl *dci = (DOMConfigurationImpl*)fDocument->getDOMConfiguration(); if(dci) fErrorHandler = dci->getErrorHandler(); else fErrorHandler = 0; DOMNode *child = 0; DOMNode *next = 0; ((DOMNormalizer *)this)->fNewNamespaceCount = 1; for(child = doc->getFirstChild();child != 0; child = next) { next = child->getNextSibling(); child = normalizeNode(child); if(child != 0) { next = child; } }}DOMNode * DOMNormalizer::normalizeNode(DOMNode *node) const { switch(node->getNodeType()) { case DOMNode::ELEMENT_NODE: { fNSScope->addScope(fMemoryManager); DOMNamedNodeMap *attrMap = node->getAttributes(); if(fConfiguration->featureValues & DOMConfigurationImpl::FEATURE_NAMESPACES) { namespaceFixUp((DOMElementImpl*)node); } else { //this is done in namespace fixup so no need to do it if namespace is on if(attrMap) { for(XMLSize_t i = 0; i < attrMap->getLength(); i++) { attrMap->item(i)->normalize(); } } } DOMNode *child = node->getFirstChild(); DOMNode *next = 0; for (; child != 0; child = next) { next = child->getNextSibling(); child = normalizeNode(child); if(child != 0) { next = child; } } fNSScope->removeScope(); break; } case DOMNode::COMMENT_NODE: { if (!(fConfiguration->featureValues & DOMConfigurationImpl::FEATURE_COMMENTS)) { DOMNode *prevSibling = node->getPreviousSibling(); DOMNode *parent = node->getParentNode(); // remove the comment node parent->removeChild(node); if (prevSibling != 0 && prevSibling->getNodeType() == DOMNode::TEXT_NODE) { DOMNode *nextSibling = prevSibling->getNextSibling(); if (nextSibling != 0 && nextSibling->getNodeType() == DOMNode::TEXT_NODE) { ((DOMTextImpl*)nextSibling)->insertData(0, prevSibling->getNodeValue()); parent->removeChild(prevSibling); return nextSibling; } } } break; } case DOMNode::CDATA_SECTION_NODE: { if (!(fConfiguration->featureValues & DOMConfigurationImpl::FEATURE_CDATA_SECTIONS)) { // convert CDATA to TEXT nodes DOMText *text = fDocument->createTextNode(node->getNodeValue()); DOMNode *parent = node->getParentNode(); DOMNode *prevSibling = node->getPreviousSibling(); node = parent->replaceChild(text, node); if (prevSibling != 0 && prevSibling->getNodeType() == DOMNode::TEXT_NODE) { text->insertData(0, prevSibling->getNodeValue()); parent->removeChild(prevSibling); } return text; // Don't advance; } break; } case DOMNode::TEXT_NODE: { DOMNode *next = node->getNextSibling(); if(next != 0 && next->getNodeType() == DOMNode::TEXT_NODE) { ((DOMText*)node)->appendData(next->getNodeValue()); node->getParentNode()->removeChild(next); return node; } else if (XMLString::stringLen(node->getNodeValue()) == 0) { node->getParentNode()->removeChild(node); } } } return 0;}void DOMNormalizer::namespaceFixUp(DOMElementImpl *ele) const { DOMAttrMapImpl *attrMap = ele->fAttributes; int len = attrMap->getLength(); //get the ns info from the attrs for(int i = 0; i < len; i++) { DOMAttr *at = (DOMAttr*)attrMap->item(i); //normalize the attr whatever happens at->normalize(); const XMLCh *uri = at->getNamespaceURI(); const XMLCh *value = at->getNodeValue(); if(XMLString::equals(XMLUni::fgXMLNSURIName, uri)) { if(XMLString::equals(XMLUni::fgXMLNSURIName, value)) { error(XMLErrs::NSDeclInvalid, ele); } else { const XMLCh *prefix = at->getPrefix(); if(XMLString::equals(prefix, XMLUni::fgXMLNSString)) { fNSScope->addOrChangeBinding(at->getLocalName(), value, fMemoryManager); } else { fNSScope->addOrChangeBinding(XMLUni::fgZeroLenString, value, fMemoryManager); } } } } const XMLCh* prefix = ele->getPrefix(); prefix ? prefix : prefix = XMLUni::fgZeroLenString; const XMLCh* uri = ele->getNamespaceURI(); uri ? uri : uri = XMLUni::fgZeroLenString; if(!XMLString::equals(uri, XMLUni::fgZeroLenString)) { if(!fNSScope->isValidBinding(prefix, uri)) {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -