| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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 "DOMServices.hpp" |
| |
| |
| |
| #include <xalanc/XalanDOM/XalanAttr.hpp> |
| #include <xalanc/XalanDOM/XalanCDATASection.hpp> |
| #include <xalanc/XalanDOM/XalanComment.hpp> |
| #include <xalanc/XalanDOM/XalanDOMString.hpp> |
| #include <xalanc/XalanDOM/XalanDocument.hpp> |
| #include <xalanc/XalanDOM/XalanDocumentFragment.hpp> |
| #include <xalanc/XalanDOM/XalanElement.hpp> |
| #include <xalanc/XalanDOM/XalanNamedNodeMap.hpp> |
| #include <xalanc/XalanDOM/XalanNodeList.hpp> |
| #include <xalanc/XalanDOM/XalanProcessingInstruction.hpp> |
| #include <xalanc/XalanDOM/XalanText.hpp> |
| |
| |
| |
| #include <xalanc/PlatformSupport/DOMStringHelper.hpp> |
| #include <xalanc/PlatformSupport/PrefixResolver.hpp> |
| #include <xalanc/PlatformSupport/XalanUnicode.hpp> |
| |
| |
| |
| #include "DOMSupportException.hpp" |
| |
| |
| |
| using xalanc::XalanDOMString; |
| |
| |
| // These XalanDOMString instances will hold the actual |
| // data. This way, the DOMSupport references can be const, |
| // but we can initialize the data when we want to. |
| |
| using xalanc::XalanMemMgrs; |
| |
| static XalanDOMString s_XMLString(XalanMemMgrs::getDummyMemMgr()); |
| static XalanDOMString s_XMLStringWithSeparator(XalanMemMgrs::getDummyMemMgr()); |
| static XalanDOMString s_XMLNamespacePrefix(XalanMemMgrs::getDummyMemMgr()); |
| static XalanDOMString s_XMLNamespaceURI(XalanMemMgrs::getDummyMemMgr()); |
| static XalanDOMString s_XMLNamespace(XalanMemMgrs::getDummyMemMgr()); |
| static XalanDOMString s_XMLNamespaceWithSeparator(XalanMemMgrs::getDummyMemMgr()); |
| static XalanDOMString s_XMLNamespaceSeparatorString(XalanMemMgrs::getDummyMemMgr()); |
| static XalanDOMString s_XMLNamespacePrefixURI(XalanMemMgrs::getDummyMemMgr()); |
| |
| |
| |
| // These variables will hold the actual data. This way, |
| // the DOMSupport references can be const, but we can initialize |
| // the data when we want to. |
| static XalanDOMString::size_type s_XMLStringLength = 0; |
| static XalanDOMString::size_type s_XMLStringWithSeparatorLength = 0; |
| static XalanDOMString::size_type s_XMLNamespacePrefixLength = 0; |
| static XalanDOMString::size_type s_XMLNamespaceURILength = 0; |
| static XalanDOMString::size_type s_XMLNamespaceLength = 0; |
| static XalanDOMString::size_type s_XMLNamespaceWithSeparatorLength = 0; |
| static XalanDOMString::size_type s_XMLNamespaceSeparatorStringLength = 0; |
| static XalanDOMString::size_type s_XMLNamespacePrefixURILength = 0; |
| |
| |
| |
| namespace XALAN_CPP_NAMESPACE { |
| |
| |
| |
| const XalanDOMString& DOMServices::s_XMLString = ::s_XMLString; |
| const XalanDOMString& DOMServices::s_XMLStringWithSeparator = ::s_XMLStringWithSeparator; |
| const XalanDOMString& DOMServices::s_XMLNamespacePrefix = ::s_XMLNamespacePrefix; |
| const XalanDOMString& DOMServices::s_XMLNamespaceURI = ::s_XMLNamespaceURI; |
| const XalanDOMString& DOMServices::s_XMLNamespace = ::s_XMLNamespace; |
| const XalanDOMString& DOMServices::s_XMLNamespaceWithSeparator = ::s_XMLNamespaceWithSeparator; |
| const XalanDOMString& DOMServices::s_XMLNamespaceSeparatorString = ::s_XMLNamespaceSeparatorString; |
| const XalanDOMString& DOMServices::s_XMLNamespacePrefixURI = ::s_XMLNamespacePrefixURI; |
| const XalanDOMString DOMServices::s_emptyString(XalanMemMgrs::getDummyMemMgr()); |
| |
| |
| |
| const XalanDOMString::size_type& DOMServices::s_XMLStringLength = ::s_XMLStringLength; |
| const XalanDOMString::size_type& DOMServices::s_XMLStringWithSeparatorLength = ::s_XMLStringWithSeparatorLength; |
| const XalanDOMString::size_type& DOMServices::s_XMLNamespacePrefixLength = ::s_XMLNamespacePrefixLength; |
| const XalanDOMString::size_type& DOMServices::s_XMLNamespaceURILength = ::s_XMLNamespaceURILength; |
| const XalanDOMString::size_type& DOMServices::s_XMLNamespaceLength = ::s_XMLNamespaceLength; |
| const XalanDOMString::size_type& DOMServices::s_XMLNamespaceWithSeparatorLength = ::s_XMLNamespaceWithSeparatorLength; |
| const XalanDOMString::size_type& DOMServices::s_XMLNamespaceSeparatorStringLength = ::s_XMLNamespaceSeparatorStringLength; |
| const XalanDOMString::size_type& DOMServices::s_XMLNamespacePrefixURILength = ::s_XMLNamespacePrefixURILength; |
| |
| |
| void |
| DOMServices::initialize(MemoryManager& theManager) |
| { |
| ::s_XMLString.reset( theManager, "xml"); |
| |
| ::s_XMLStringWithSeparator.reset( theManager, "xml:" ); |
| ::s_XMLNamespacePrefix.reset( theManager, "xmlns:xml"); |
| ::s_XMLNamespaceURI.reset( theManager, "http://www.w3.org/XML/1998/namespace"); |
| ::s_XMLNamespace.reset( theManager, "xmlns"); |
| ::s_XMLNamespaceWithSeparator.reset( theManager, "xmlns:"); |
| ::s_XMLNamespaceSeparatorString.reset( theManager, ":"); |
| ::s_XMLNamespacePrefixURI.reset( theManager, "http://www.w3.org/2000/xmlns/"); |
| |
| ::s_XMLStringLength = DOMServices::s_XMLString.length(); |
| ::s_XMLStringWithSeparatorLength = DOMServices::s_XMLStringWithSeparator.length(); |
| ::s_XMLNamespacePrefixLength = DOMServices::s_XMLNamespacePrefix.length(); |
| ::s_XMLNamespaceURILength = DOMServices::s_XMLNamespaceURI.length(); |
| ::s_XMLNamespaceLength = DOMServices::s_XMLNamespace.length(); |
| ::s_XMLNamespaceWithSeparatorLength = DOMServices::s_XMLNamespaceWithSeparator.length(); |
| ::s_XMLNamespaceSeparatorStringLength = DOMServices::s_XMLNamespaceSeparatorString.length(); |
| ::s_XMLNamespacePrefixURILength = DOMServices::s_XMLNamespacePrefixURI.length(); |
| } |
| |
| |
| |
| void |
| DOMServices::terminate() |
| { |
| MemoryManager& theManager = XalanMemMgrs::getDummyMemMgr(); |
| |
| releaseMemory(::s_XMLString, theManager ); |
| releaseMemory(::s_XMLStringWithSeparator, theManager ); |
| releaseMemory(::s_XMLNamespacePrefix, theManager ); |
| releaseMemory(::s_XMLNamespaceURI, theManager ); |
| releaseMemory(::s_XMLNamespace, theManager ); |
| releaseMemory(::s_XMLNamespaceWithSeparator, theManager ); |
| releaseMemory(::s_XMLNamespaceSeparatorString, theManager ); |
| releaseMemory(::s_XMLNamespacePrefixURI, theManager ); |
| |
| ::s_XMLStringLength = 0; |
| ::s_XMLStringWithSeparatorLength = 0; |
| ::s_XMLNamespacePrefixLength = 0; |
| ::s_XMLNamespaceURILength = 0; |
| ::s_XMLNamespaceLength = 0; |
| ::s_XMLNamespaceWithSeparatorLength = 0; |
| ::s_XMLNamespaceSeparatorStringLength = 0; |
| ::s_XMLNamespacePrefixURILength = 0; |
| } |
| |
| |
| |
| |
| void |
| DOMServices::getNodeData( |
| const XalanNode& node, |
| XalanDOMString& data) |
| { |
| switch(node.getNodeType()) |
| { |
| case XalanNode::DOCUMENT_FRAGMENT_NODE: |
| { |
| const XalanDocumentFragment& theDocumentFragment = |
| static_cast<const XalanDocumentFragment&>(node); |
| |
| getNodeData(theDocumentFragment, data); |
| } |
| break; |
| |
| case XalanNode::DOCUMENT_NODE: |
| { |
| const XalanDocument& theDocument = |
| static_cast<const XalanDocument&>(node); |
| |
| getNodeData(theDocument, data); |
| } |
| break; |
| |
| case XalanNode::ELEMENT_NODE: |
| { |
| const XalanElement& theElement = |
| static_cast<const XalanElement&>(node); |
| |
| getNodeData(theElement, data); |
| } |
| break; |
| |
| case XalanNode::TEXT_NODE: |
| case XalanNode::CDATA_SECTION_NODE: |
| { |
| const XalanText& theTextNode = |
| static_cast<const XalanText&>(node); |
| |
| getNodeData(theTextNode, data); |
| } |
| break; |
| |
| case XalanNode::ATTRIBUTE_NODE: |
| { |
| const XalanAttr& theAttr = |
| static_cast<const XalanAttr&>(node); |
| |
| getNodeData(theAttr, data); |
| } |
| break; |
| |
| case XalanNode::COMMENT_NODE: |
| { |
| const XalanComment& theComment = |
| static_cast<const XalanComment&>(node); |
| |
| getNodeData(theComment, data); |
| } |
| break; |
| |
| case XalanNode::PROCESSING_INSTRUCTION_NODE: |
| { |
| const XalanProcessingInstruction& thePI = |
| static_cast<const XalanProcessingInstruction&>(node); |
| |
| getNodeData(thePI, data); |
| } |
| break; |
| |
| default: |
| // ignore |
| break; |
| } |
| } |
| |
| |
| |
| |
| void |
| DOMServices::doGetNodeData( |
| const XalanNode& node, |
| ExecutionContext& executionContext, |
| XalanDOMString& data) |
| { |
| assert(executionContext.hasPreserveOrStripSpaceConditions() == true); |
| |
| switch(node.getNodeType()) |
| { |
| case XalanNode::DOCUMENT_FRAGMENT_NODE: |
| { |
| const XalanDocumentFragment& theDocumentFragment = |
| static_cast<const XalanDocumentFragment&>(node); |
| |
| doGetNodeData(theDocumentFragment, executionContext, data); |
| } |
| break; |
| |
| case XalanNode::DOCUMENT_NODE: |
| { |
| const XalanDocument& theDocument = |
| static_cast<const XalanDocument&>(node); |
| |
| doGetNodeData(theDocument, executionContext, data); |
| } |
| break; |
| |
| case XalanNode::ELEMENT_NODE: |
| { |
| const XalanElement& theElement = |
| static_cast<const XalanElement&>(node); |
| |
| doGetNodeData(theElement, executionContext, data); |
| } |
| break; |
| |
| case XalanNode::TEXT_NODE: |
| case XalanNode::CDATA_SECTION_NODE: |
| { |
| const XalanText& theTextNode = |
| static_cast<const XalanText&>(node); |
| |
| doGetNodeData(theTextNode, executionContext, data); |
| } |
| break; |
| |
| case XalanNode::ATTRIBUTE_NODE: |
| { |
| const XalanAttr& theAttr = |
| static_cast<const XalanAttr&>(node); |
| |
| getNodeData(theAttr, data); |
| } |
| break; |
| |
| case XalanNode::COMMENT_NODE: |
| { |
| const XalanComment& theComment = |
| static_cast<const XalanComment&>(node); |
| |
| getNodeData(theComment, data); |
| } |
| break; |
| |
| case XalanNode::PROCESSING_INSTRUCTION_NODE: |
| { |
| const XalanProcessingInstruction& thePI = |
| static_cast<const XalanProcessingInstruction&>(node); |
| |
| getNodeData(thePI, data); |
| } |
| break; |
| |
| default: |
| // ignore |
| break; |
| } |
| } |
| |
| |
| |
| |
| inline void |
| getChildData( |
| const XalanNode* child, |
| XalanDOMString& data) |
| { |
| const XalanNode::NodeType theType = child->getNodeType(); |
| |
| if (theType == XalanNode::ELEMENT_NODE) |
| { |
| const XalanElement* const theElementNode = |
| static_cast<const XalanElement*>(child); |
| |
| DOMServices::getNodeData(*theElementNode, data); |
| } |
| else if (theType == XalanNode::TEXT_NODE || |
| theType == XalanNode::CDATA_SECTION_NODE) |
| { |
| const XalanText* theTextNode = |
| static_cast<const XalanText*>(child); |
| |
| DOMServices::getNodeData(*theTextNode, data); |
| } |
| } |
| |
| |
| |
| inline void |
| getChildData( |
| const XalanNode* child, |
| ExecutionContext& executionContext, |
| XalanDOMString& data) |
| { |
| assert(executionContext.hasPreserveOrStripSpaceConditions() == true); |
| |
| const XalanNode::NodeType theType = child->getNodeType(); |
| |
| if (theType == XalanNode::ELEMENT_NODE) |
| { |
| const XalanElement* const theElementNode = |
| static_cast<const XalanElement*>(child); |
| |
| DOMServices::doGetNodeData(*theElementNode, executionContext, data); |
| } |
| else if (theType == XalanNode::TEXT_NODE || |
| theType == XalanNode::CDATA_SECTION_NODE) |
| { |
| const XalanText* theTextNode = |
| static_cast<const XalanText*>(child); |
| |
| DOMServices::doGetNodeData(*theTextNode, executionContext, data); |
| } |
| } |
| |
| |
| |
| inline void |
| getChildrenData( |
| const XalanNode* firstChild, |
| XalanDOMString& data) |
| { |
| while(firstChild != 0) |
| { |
| getChildData(firstChild, data); |
| |
| firstChild = firstChild->getNextSibling(); |
| } |
| } |
| |
| |
| |
| inline void |
| getChildrenData( |
| const XalanNode* firstChild, |
| ExecutionContext& executionContext, |
| XalanDOMString& data) |
| { |
| assert(executionContext.hasPreserveOrStripSpaceConditions() == true); |
| |
| while(firstChild != 0) |
| { |
| getChildData(firstChild, executionContext, data); |
| |
| firstChild = firstChild->getNextSibling(); |
| } |
| } |
| |
| |
| |
| void |
| DOMServices::getNodeData( |
| const XalanDocument& document, |
| XalanDOMString& data) |
| { |
| assert(document.getDocumentElement() != 0); |
| |
| getChildrenData(document.getDocumentElement(), data); |
| } |
| |
| |
| |
| |
| |
| void |
| DOMServices::doGetNodeData( |
| const XalanDocument& document, |
| ExecutionContext& executionContext, |
| XalanDOMString& data) |
| { |
| assert(executionContext.hasPreserveOrStripSpaceConditions() == true); |
| assert(document.getDocumentElement() != 0); |
| |
| getChildrenData( |
| document.getDocumentElement(), |
| executionContext, |
| data); |
| } |
| |
| |
| |
| |
| |
| void |
| DOMServices::getNodeData( |
| const XalanDocumentFragment& documentFragment, |
| XalanDOMString& data) |
| { |
| for(const XalanNode* child = documentFragment.getFirstChild(); child != 0; child = child->getNextSibling()) |
| { |
| assert(child != 0); |
| |
| getChildData(child, data); |
| } |
| } |
| |
| |
| |
| |
| void |
| DOMServices::doGetNodeData( |
| const XalanDocumentFragment& documentFragment, |
| ExecutionContext& executionContext, |
| XalanDOMString& data) |
| { |
| assert(executionContext.hasPreserveOrStripSpaceConditions() == true); |
| |
| for(const XalanNode* child = documentFragment.getFirstChild(); child != 0; child = child->getNextSibling()) |
| { |
| assert(child != 0); |
| |
| getChildData(child, executionContext, data); |
| } |
| } |
| |
| |
| |
| |
| void |
| DOMServices::getNodeData( |
| const XalanElement& element, |
| XalanDOMString& data) |
| { |
| getChildrenData(element.getFirstChild(), data); |
| } |
| |
| |
| |
| void |
| DOMServices::doGetNodeData( |
| const XalanElement& element, |
| ExecutionContext& executionContext, |
| XalanDOMString& data) |
| { |
| assert(executionContext.hasPreserveOrStripSpaceConditions() == true); |
| |
| getChildrenData(element.getFirstChild(), executionContext, data); |
| } |
| |
| |
| |
| void |
| DOMServices::getNodeData( |
| const XalanNode& node, |
| FormatterListener& formatterListener, |
| MemberFunctionPtr function) |
| { |
| switch(node.getNodeType()) |
| { |
| case XalanNode::DOCUMENT_FRAGMENT_NODE: |
| { |
| const XalanDocumentFragment& theDocumentFragment = |
| static_cast<const XalanDocumentFragment&>(node); |
| |
| getNodeData(theDocumentFragment, formatterListener, function); |
| } |
| break; |
| |
| case XalanNode::DOCUMENT_NODE: |
| { |
| const XalanDocument& theDocument = |
| static_cast<const XalanDocument&>(node); |
| |
| getNodeData(theDocument, formatterListener, function); |
| } |
| break; |
| |
| case XalanNode::ELEMENT_NODE: |
| { |
| const XalanElement& theElement = |
| static_cast<const XalanElement&>(node); |
| |
| getNodeData(theElement, formatterListener, function); |
| } |
| break; |
| |
| case XalanNode::TEXT_NODE: |
| case XalanNode::CDATA_SECTION_NODE: |
| { |
| const XalanText& theTextNode = |
| static_cast<const XalanText&>(node); |
| |
| getNodeData(theTextNode, formatterListener, function); |
| } |
| break; |
| |
| case XalanNode::ATTRIBUTE_NODE: |
| { |
| const XalanAttr& theAttr = |
| static_cast<const XalanAttr&>(node); |
| |
| getNodeData(theAttr, formatterListener, function); |
| } |
| break; |
| |
| case XalanNode::COMMENT_NODE: |
| { |
| const XalanComment& theComment = |
| static_cast<const XalanComment&>(node); |
| |
| getNodeData(theComment, formatterListener, function); |
| } |
| break; |
| |
| case XalanNode::PROCESSING_INSTRUCTION_NODE: |
| { |
| const XalanProcessingInstruction& thePI = |
| static_cast<const XalanProcessingInstruction&>(node); |
| |
| getNodeData(thePI, formatterListener, function); |
| } |
| break; |
| |
| default: |
| // ignore |
| break; |
| } |
| } |
| |
| |
| |
| void |
| DOMServices::doGetNodeData( |
| const XalanNode& node, |
| ExecutionContext& executionContext, |
| FormatterListener& formatterListener, |
| MemberFunctionPtr function) |
| { |
| assert(executionContext.hasPreserveOrStripSpaceConditions() == true); |
| |
| switch(node.getNodeType()) |
| { |
| case XalanNode::DOCUMENT_FRAGMENT_NODE: |
| { |
| const XalanDocumentFragment& theDocumentFragment = |
| static_cast<const XalanDocumentFragment&>(node); |
| |
| doGetNodeData(theDocumentFragment, executionContext, formatterListener, function); |
| } |
| break; |
| |
| case XalanNode::DOCUMENT_NODE: |
| { |
| const XalanDocument& theDocument = |
| static_cast<const XalanDocument&>(node); |
| |
| doGetNodeData(theDocument, executionContext, formatterListener, function); |
| } |
| break; |
| |
| case XalanNode::ELEMENT_NODE: |
| { |
| const XalanElement& theElement = |
| static_cast<const XalanElement&>(node); |
| |
| doGetNodeData(theElement, executionContext, formatterListener, function); |
| } |
| break; |
| |
| case XalanNode::TEXT_NODE: |
| case XalanNode::CDATA_SECTION_NODE: |
| { |
| const XalanText& theTextNode = |
| static_cast<const XalanText&>(node); |
| |
| doGetNodeData(theTextNode, executionContext, formatterListener, function); |
| } |
| break; |
| |
| case XalanNode::ATTRIBUTE_NODE: |
| { |
| const XalanAttr& theAttr = |
| static_cast<const XalanAttr&>(node); |
| |
| getNodeData(theAttr, formatterListener, function); |
| } |
| break; |
| |
| case XalanNode::COMMENT_NODE: |
| { |
| const XalanComment& theComment = |
| static_cast<const XalanComment&>(node); |
| |
| getNodeData(theComment, formatterListener, function); |
| } |
| break; |
| |
| case XalanNode::PROCESSING_INSTRUCTION_NODE: |
| { |
| const XalanProcessingInstruction& thePI = |
| static_cast<const XalanProcessingInstruction&>(node); |
| |
| getNodeData(thePI, formatterListener, function); |
| } |
| break; |
| |
| default: |
| // ignore |
| break; |
| } |
| } |
| |
| |
| |
| inline void |
| getChildData( |
| const XalanNode* child, |
| FormatterListener& formatterListener, |
| DOMServices::MemberFunctionPtr function) |
| { |
| const XalanNode::NodeType theType = child->getNodeType(); |
| |
| if (theType == XalanNode::ELEMENT_NODE) |
| { |
| const XalanElement* const theElementNode = |
| static_cast<const XalanElement*>(child); |
| |
| DOMServices::getNodeData(*theElementNode, formatterListener, function); |
| } |
| else if (theType == XalanNode::TEXT_NODE || |
| theType == XalanNode::CDATA_SECTION_NODE) |
| { |
| const XalanText* theTextNode = |
| static_cast<const XalanText*>(child); |
| |
| DOMServices::getNodeData(*theTextNode, formatterListener, function); |
| } |
| } |
| |
| |
| |
| inline void |
| getChildData( |
| const XalanNode* child, |
| ExecutionContext& executionContext, |
| FormatterListener& formatterListener, |
| DOMServices::MemberFunctionPtr function) |
| { |
| assert(executionContext.hasPreserveOrStripSpaceConditions() == true); |
| |
| const XalanNode::NodeType theType = child->getNodeType(); |
| |
| if (theType == XalanNode::ELEMENT_NODE) |
| { |
| const XalanElement* const theElementNode = |
| static_cast<const XalanElement*>(child); |
| |
| DOMServices::getNodeData(*theElementNode, executionContext, formatterListener, function); |
| } |
| else if (theType == XalanNode::TEXT_NODE || |
| theType == XalanNode::CDATA_SECTION_NODE) |
| { |
| const XalanText* theTextNode = |
| static_cast<const XalanText*>(child); |
| |
| DOMServices::getNodeData(*theTextNode, executionContext, formatterListener, function); |
| } |
| } |
| |
| |
| |
| inline void |
| getChildrenData( |
| const XalanNode* firstChild, |
| FormatterListener& formatterListener, |
| DOMServices::MemberFunctionPtr function) |
| { |
| while(firstChild != 0) |
| { |
| getChildData(firstChild, formatterListener, function); |
| |
| firstChild = firstChild->getNextSibling(); |
| } |
| } |
| |
| |
| |
| inline void |
| getChildrenData( |
| const XalanNode* firstChild, |
| ExecutionContext& executionContext, |
| FormatterListener& formatterListener, |
| DOMServices::MemberFunctionPtr function) |
| { |
| assert(executionContext.hasPreserveOrStripSpaceConditions() == true); |
| |
| while(firstChild != 0) |
| { |
| getChildData(firstChild, executionContext, formatterListener, function); |
| |
| firstChild = firstChild->getNextSibling(); |
| } |
| } |
| |
| |
| |
| void |
| DOMServices::getNodeData( |
| const XalanDocument& document, |
| FormatterListener& formatterListener, |
| MemberFunctionPtr function) |
| { |
| getChildrenData( |
| document.getDocumentElement(), |
| formatterListener, |
| function); |
| } |
| |
| |
| |
| void |
| DOMServices::doGetNodeData( |
| const XalanDocument& document, |
| ExecutionContext& executionContext, |
| FormatterListener& formatterListener, |
| MemberFunctionPtr function) |
| { |
| assert(executionContext.hasPreserveOrStripSpaceConditions() == true); |
| |
| getChildrenData( |
| document.getDocumentElement(), |
| executionContext, |
| formatterListener, |
| function); |
| } |
| |
| |
| |
| void |
| DOMServices::getNodeData( |
| const XalanDocumentFragment& documentFragment, |
| FormatterListener& formatterListener, |
| MemberFunctionPtr function) |
| { |
| for(const XalanNode* child = documentFragment.getFirstChild(); child != 0; child = child->getNextSibling()) |
| { |
| assert(child != 0); |
| |
| getChildData(child, formatterListener, function); |
| } |
| } |
| |
| |
| |
| void |
| DOMServices::doGetNodeData( |
| const XalanDocumentFragment& documentFragment, |
| ExecutionContext& executionContext, |
| FormatterListener& formatterListener, |
| MemberFunctionPtr function) |
| { |
| assert(executionContext.hasPreserveOrStripSpaceConditions() == true); |
| |
| for(const XalanNode* child = documentFragment.getFirstChild(); child != 0; child = child->getNextSibling()) |
| { |
| assert(child != 0); |
| |
| getChildData(child, executionContext, formatterListener, function); |
| } |
| } |
| |
| |
| |
| void |
| DOMServices::getNodeData( |
| const XalanElement& element, |
| FormatterListener& formatterListener, |
| MemberFunctionPtr function) |
| { |
| getChildrenData( |
| element.getFirstChild(), |
| formatterListener, |
| function); |
| } |
| |
| |
| |
| void |
| DOMServices::doGetNodeData( |
| const XalanElement& element, |
| ExecutionContext& executionContext, |
| FormatterListener& formatterListener, |
| MemberFunctionPtr function) |
| { |
| assert(executionContext.hasPreserveOrStripSpaceConditions() == true); |
| |
| getChildrenData( |
| element.getFirstChild(), |
| executionContext, |
| formatterListener, |
| function); |
| } |
| |
| |
| |
| const XalanDOMString& |
| DOMServices::getNameOfNode(const XalanNode& n) |
| { |
| const XalanNode::NodeType theNodeType = |
| n.getNodeType(); |
| |
| if (theNodeType == XalanNode::ATTRIBUTE_NODE) |
| { |
| return getNameOfNode(static_cast<const XalanAttr&>(n)); |
| } |
| else if (theNodeType == XalanNode::ELEMENT_NODE) |
| { |
| return getNameOfNode(static_cast<const XalanElement&>(n)); |
| } |
| else if (theNodeType == XalanNode::PROCESSING_INSTRUCTION_NODE) |
| { |
| return n.getNodeName(); |
| } |
| else |
| { |
| return s_emptyString; |
| } |
| } |
| |
| |
| |
| const XalanDOMString& |
| DOMServices::getNamespaceOfNode(const XalanNode& n) |
| { |
| if (n.getNodeType() != XalanNode::ATTRIBUTE_NODE) |
| { |
| return n.getNamespaceURI(); |
| } |
| else |
| { |
| const XalanDOMString& theNodeName = n.getNodeName(); |
| |
| // Special case for namespace nodes... |
| if (startsWith(theNodeName, DOMServices::s_XMLNamespaceWithSeparator) == true || |
| equals(theNodeName, DOMServices::s_XMLNamespace) == true) |
| { |
| return s_emptyString; |
| } |
| else |
| { |
| return n.getNamespaceURI(); |
| } |
| } |
| } |
| |
| |
| |
| // Note functional overlap with NamespaceResolver's |
| // getNamespaceOfNode() method. |
| // |
| // ***** Also: although this may not yet impact Xalan, |
| // as of DOM Level 2 it is possible for a hand-constructed DOM to |
| // have namespaced nodes with no declaration in scope. In DOM2 it's |
| // considered the responsibility of application code such as DOM |
| // serializers to recognize these cases and synthesize appropriate |
| // declarations when necessary. DOM3 is expected to add |
| // some form of namespaceNormalize() operation to assist this task. |
| // |
| // DOM3 may also add a resolveNamespacePrefix() operation |
| // which is aware of these issues and can generate reasonable |
| // results even for a non-NS-normalized tree. The expected logic |
| // is that a Namespaced node with a prefix will constitute an |
| // implicit declaration of that prefix. |
| // |
| // If we cut over to DOM2 and want to accept DOMs from sources other |
| // than the parser, we need to decide between demanding a |
| // namespace-normalized DOM as input, doing a normalize pass |
| // (full treewalk, expensive), or recognizing implicit declarations. |
| const XalanDOMString* |
| DOMServices::getNamespaceForPrefix( |
| const XalanDOMString& prefix, |
| const XalanElement& namespaceContext) |
| { |
| const XalanDOMString* theNamespace = 0; |
| |
| // Reserved xml: is hardcoded |
| if(equals(prefix, s_XMLString) == true) |
| { |
| theNamespace = &s_XMLNamespaceURI; |
| } |
| else |
| { |
| const bool isDefaultNamespace = prefix.empty(); |
| XalanNode::NodeType type; |
| const XalanNode* parent = &namespaceContext; |
| |
| // Consider elements until NS is resolved, or we run out of |
| // ancestors, or we hit something other than an Element or |
| // EntityReference node (ie, Document or DocumentFragment) |
| while (parent != 0 && theNamespace == 0 |
| && ((type = parent->getNodeType()) == XalanNode::ELEMENT_NODE |
| || type == XalanNode::ENTITY_REFERENCE_NODE)) |
| { |
| if (type == XalanNode::ELEMENT_NODE) |
| { |
| // Scan the attributes for xmlns:* or xmlns: |
| // (The latter is the prefix=="" case.) |
| const XalanNamedNodeMap* const nnm = parent->getAttributes(); |
| assert(nnm != 0); |
| |
| const XalanSize_t theLength = nnm->getLength(); |
| |
| for (XalanSize_t i = 0; i < theLength; i ++) |
| { |
| const XalanNode* const attr = nnm->item(i); |
| assert(attr != 0); |
| |
| const XalanDOMString& aname = attr->getNodeName(); |
| |
| if (isDefaultNamespace == true) |
| { |
| if (equals(aname, s_XMLNamespace) == true) |
| { |
| theNamespace = &attr->getNodeValue(); |
| |
| break; |
| } |
| } |
| else if (startsWith(aname, s_XMLNamespaceWithSeparator) == true) |
| { |
| if (equals( |
| prefix, |
| aname.c_str() + s_XMLNamespaceWithSeparatorLength) == true) |
| { |
| theNamespace = &attr->getNodeValue(); |
| |
| break; |
| } |
| } |
| } |
| } |
| |
| parent = getParentOfNode(*parent); |
| } |
| } |
| |
| return theNamespace; |
| } |
| |
| |
| |
| const XalanDOMString* |
| DOMServices::getNamespaceForPrefix( |
| const XalanDOMChar* theName, |
| const PrefixResolver& thePrefixResolver, |
| bool isAttribute, |
| XalanDOMString& thePrefix) |
| { |
| const XalanDOMString::size_type theLength = length(theName); |
| |
| // Check for special default namespace value... |
| if (isAttribute == true && equals(s_XMLNamespace, theName, theLength) == true) |
| { |
| return &s_XMLNamespacePrefixURI; |
| } |
| else |
| { |
| const XalanDOMString::size_type theColonIndex = indexOf(theName, XalanUnicode::charColon); |
| |
| if (theColonIndex == theLength) |
| { |
| thePrefix.clear(); |
| |
| if (isAttribute == true) |
| { |
| return 0; |
| } |
| else |
| { |
| return thePrefixResolver.getNamespaceForPrefix(s_emptyString); |
| } |
| } |
| else |
| { |
| // Get the prefix from theName... |
| thePrefix.assign(theName, theColonIndex); |
| assert(thePrefix.empty() == false); |
| |
| return thePrefixResolver.getNamespaceForPrefix(thePrefix); |
| } |
| } |
| } |
| |
| |
| |
| bool |
| DOMServices::isNodeAfter( |
| const XalanNode& node1, |
| const XalanNode& node2) |
| { |
| assert(node1.getOwnerDocument() == node2.getOwnerDocument()); |
| assert(node1.getNodeType() != XalanNode::DOCUMENT_NODE && |
| node2.getNodeType() != XalanNode::DOCUMENT_NODE); |
| |
| if (node1.isIndexed() == true) |
| { |
| assert(node2.isIndexed() == true); |
| |
| return node1.getIndex() > node2.getIndex() ? true : false; |
| } |
| else |
| { |
| bool isNodeAfter = false; |
| |
| const XalanNode* parent1 = getParentOfNode(node1); |
| |
| const XalanNode* parent2 = getParentOfNode(node2); |
| |
| // Optimize for most common case |
| if (parent1 == parent2) // then we know they are siblings |
| { |
| isNodeAfter = isNodeAfterSibling(*parent1, |
| node1, |
| node2); |
| } |
| else |
| { |
| // General strategy: Figure out the lengths of the two |
| // ancestor chains, and walk up them looking for the |
| // first common ancestor, at which point we can do a |
| // sibling compare. Edge condition where one is the |
| // ancestor of the other. |
| |
| // Count parents, so we can see if one of the chains |
| // needs to be equalized. |
| XalanSize_t nParents1 = 2; |
| XalanSize_t nParents2 = 2; // count node & parent obtained above |
| |
| while (parent1 != 0) |
| { |
| nParents1++; |
| parent1 = getParentOfNode(*parent1); |
| } |
| |
| while (parent2 != 0) |
| { |
| nParents2++; |
| parent2 = getParentOfNode(*parent2); |
| } |
| |
| // adjustable starting points |
| const XalanNode* startNode1 = &node1; |
| const XalanNode* startNode2 = &node2; |
| |
| // Do I have to adjust the start point in one of |
| // the ancesor chains? |
| if (nParents1 < nParents2) |
| { |
| // adjust startNode2 |
| const XalanSize_t adjust = nParents2 - nParents1; |
| |
| for (XalanSize_t i = 0; i < adjust; i++) |
| { |
| startNode2 = getParentOfNode(*startNode2); |
| } |
| } |
| else if(nParents1 > nParents2) |
| { |
| // adjust startNode1 |
| const XalanSize_t adjust = nParents1 - nParents2; |
| |
| for (XalanSize_t i = 0; i < adjust; i++) |
| { |
| startNode1 = getParentOfNode(*startNode1); |
| } |
| } |
| |
| // so we can "back up" |
| const XalanNode* prevChild1 = 0; |
| const XalanNode* prevChild2 = 0; |
| |
| // Loop up the ancestor chain looking for common parent. |
| while (0 != startNode1) |
| { |
| if (startNode1 == startNode2) // common parent? |
| { |
| if (0 == prevChild1) // first time in loop? |
| { |
| // Edge condition: one is the ancestor of the other. |
| isNodeAfter = (nParents1 < nParents2) ? true : false; |
| |
| break; // from while loop |
| } |
| else |
| { |
| isNodeAfter = isNodeAfterSibling(*startNode1, |
| *prevChild1, |
| *prevChild2); |
| |
| break; // from while loop |
| } |
| } |
| |
| prevChild1 = startNode1; |
| assert(prevChild1 != 0); |
| |
| startNode1 = getParentOfNode(*startNode1); |
| assert(startNode1 != 0); |
| |
| prevChild2 = startNode2; |
| assert(prevChild2 != 0); |
| |
| startNode2 = getParentOfNode(*startNode2); |
| assert(startNode2 != 0); |
| } |
| } |
| |
| return isNodeAfter; |
| } |
| } |
| |
| |
| |
| bool |
| DOMServices::isNodeAfterSibling( |
| const XalanNode& parent, |
| const XalanNode& child1, |
| const XalanNode& child2) |
| { |
| bool isNodeAfterSibling = false; |
| |
| const XalanNode::NodeType child1type = child1.getNodeType(); |
| const XalanNode::NodeType child2type = child2.getNodeType(); |
| |
| if (XalanNode::ATTRIBUTE_NODE != child1type && |
| XalanNode::ATTRIBUTE_NODE == child2type) |
| { |
| // always sort attributes before non-attributes. |
| isNodeAfterSibling = true; |
| } |
| else if (XalanNode::ATTRIBUTE_NODE == child1type && |
| XalanNode::ATTRIBUTE_NODE != child2type) |
| { |
| // always sort attributes before non-attributes. |
| isNodeAfterSibling = false; |
| } |
| else if (XalanNode::ATTRIBUTE_NODE == child1type) |
| { |
| const XalanNamedNodeMap* children = parent.getAttributes(); |
| |
| const XalanSize_t nNodes = children->getLength(); |
| |
| bool found1 = false; |
| bool found2 = false; |
| |
| for (XalanSize_t i = 0; i < nNodes; i++) |
| { |
| const XalanNode* child = children->item(i); |
| |
| if (&child1 == child) |
| { |
| if (found2 == true) |
| { |
| isNodeAfterSibling = true; |
| break; |
| } |
| |
| found1 = true; |
| } |
| else if (&child2 == child) |
| { |
| if (found1 == true) |
| { |
| isNodeAfterSibling = false; |
| break; |
| } |
| |
| found2 = true; |
| } |
| } |
| } |
| else |
| { |
| const XalanNode* child = parent.getFirstChild(); |
| |
| bool found1 = false; |
| bool found2 = false; |
| |
| while (child != 0) |
| { |
| if (&child1 == child) |
| { |
| if (found2 == true) |
| { |
| isNodeAfterSibling = true; |
| break; |
| } |
| |
| found1 = true; |
| } |
| else if (&child2 == child) |
| { |
| if (found1 == true) |
| { |
| isNodeAfterSibling = false; |
| break; |
| } |
| |
| found2 = true; |
| } |
| |
| child = child->getNextSibling(); |
| } |
| |
| assert(found1 != found2); |
| } |
| |
| return isNodeAfterSibling; |
| } |
| |
| |
| |
| } |