void XercesUpdateFactory::applyReplaceAttribute(const PendingUpdate &update, DynamicContext *context) { const XercesNodeImpl *nodeImpl = (const XercesNodeImpl*)update.getTarget()->getInterface(Item::gXQilla); DOMAttr *domnode = (DOMAttr*)nodeImpl->getDOMNode(); Node::Ptr parentNode = nodeImpl->dmParent(context); DOMElement *element = domnode->getOwnerElement(); DOMDocument *doc = element->getOwnerDocument(); bool untyped = parentNode->dmNodeKind() == Node::element_string && XPath2Utils::equals(parentNode->getTypeName(), DocumentCache::g_szUntyped) && XPath2Utils::equals(parentNode->getTypeURI(), SchemaSymbols::fgURI_SCHEMAFORSCHEMA); Result children = update.getValue(); Item::Ptr item; while((item = children->next(context)).notNull()) { const XercesNodeImpl *childImpl = (const XercesNodeImpl*)item->getInterface(Item::gXQilla); DOMNode *newChild = importNodeFix(doc, const_cast<DOMNode*>(childImpl->getDOMNode()), /*deep*/true); // 1. Error checks: // a. If the QNames of any two attribute nodes in $replacement have implied namespace bindings that conflict with // each other, a dynamic error is raised [err:XUDY0024]. // b. If the QName of any attribute node in $replacement has an implied namespace binding that conflicts with a // namespace binding in the "namespaces" property of parent($target), a dynamic error is raised [err:XUDY0024]. // Checks performed by UpdateFactory // 2b. If the type-name property of parent($target) is xs:untyped, then upd:setToUntyped() is invoked // on each element node in $replacement. if(!untyped) setTypes(newChild, childImpl->getDOMNode()); // 2a. For each node in $replacement, the parent property is set to parent($target). // 4a. If $target is an attribute node, the attributes property of parent($target) is modified by removing $target // and adding the nodes in $replacement (if any). // 4b. If $target is an attribute node, the namespaces property of parent($target) is modified to include namespace // bindings for any attribute namespace prefixes in $replacement that did not already have bindings. element->setAttributeNode((DOMAttr*)newChild); } // 3a. $target is marked for deletion. forDeletion_.insert(domnode); // 4d. upd:removeType(parent($target)) is invoked. removeType(element); // Use parentNode, since the attr replace could have removed the original attr addToPutSet(parentNode, &update, context); }
void XercesUpdateFactory::applyInsertAfter(const PendingUpdate &update, DynamicContext *context) { const XercesNodeImpl *nodeImpl = (const XercesNodeImpl*)update.getTarget()->getInterface(Item::gXQilla); DOMNode *domnode = const_cast<DOMNode*>(nodeImpl->getDOMNode()); DOMNode *before = domnode->getNextSibling(); Node::Ptr parentNode = nodeImpl->dmParent(context); DOMNode *parent = domnode->getParentNode(); DOMDocument *doc = const_cast<DOMDocument*>(XPath2Utils::getOwnerDoc(domnode)); bool untyped = parentNode->dmNodeKind() == Node::element_string && XPath2Utils::equals(parentNode->getTypeName(), DocumentCache::g_szUntyped) && XPath2Utils::equals(parentNode->getTypeURI(), SchemaSymbols::fgURI_SCHEMAFORSCHEMA); bool containsElementOrText = false; Result children = update.getValue(); Item::Ptr item; while((item = children->next(context)).notNull()) { const XercesNodeImpl *childImpl = (const XercesNodeImpl*)item->getInterface(Item::gXQilla); DOMNode *newChild = importNodeFix(doc, const_cast<DOMNode*>(childImpl->getDOMNode()), /*deep*/true); if(childImpl->dmNodeKind() == Node::element_string || childImpl->dmNodeKind() == Node::text_string) { containsElementOrText = true; } // If the type-name property of parent($target) is xs:untyped, then upd:setToUntyped() is invoked on each // element or attribute node in $content. if(!untyped) setTypes(newChild, childImpl->getDOMNode()); // For each node in $content, the parent property is set to parent($target). // The children property of parent($target) is modified to add the nodes in $content just before $target, // preserving their order. parent->insertBefore(newChild, before); } // If at least one of the nodes in $content is an element or text node, upd:removeType(parent($target)) is invoked. if(containsElementOrText) { removeType(parent); } addToPutSet(update.getTarget(), &update, context); }
void XercesUpdateFactory::applyReplaceNode(const PendingUpdate &update, DynamicContext *context) { const XercesNodeImpl *nodeImpl = (const XercesNodeImpl*)update.getTarget()->getInterface(Item::gXQilla); DOMNode *domnode = const_cast<DOMNode*>(nodeImpl->getDOMNode()); Node::Ptr parentNode = nodeImpl->dmParent(context); DOMNode *parent = domnode->getParentNode(); DOMDocument *doc = const_cast<DOMDocument*>(XPath2Utils::getOwnerDoc(domnode)); bool untyped = parentNode->dmNodeKind() == Node::element_string && XPath2Utils::equals(parentNode->getTypeName(), DocumentCache::g_szUntyped) && XPath2Utils::equals(parentNode->getTypeURI(), SchemaSymbols::fgURI_SCHEMAFORSCHEMA); Result children = update.getValue(); Item::Ptr item; while((item = children->next(context)).notNull()) { const XercesNodeImpl *childImpl = (const XercesNodeImpl*)item->getInterface(Item::gXQilla); DOMNode *newChild = importNodeFix(doc, const_cast<DOMNode*>(childImpl->getDOMNode()), /*deep*/true); // 1b. If the type-name property of parent($target) is xs:untyped, then upd:setToUntyped() is invoked // on each element node in $replacement. if(!untyped) setTypes(newChild, childImpl->getDOMNode()); // 1a. For each node in $replacement, the parent property is set to parent($target). // 3b. If $target is an element, text, comment, or processing instruction node, the children property // of parent($target) is modified to add the nodes in $replacement just before $target, preserving // their order. parent->insertBefore(newChild, domnode); } // 2a. $target is marked for deletion. forDeletion_.insert(domnode); // 3c. upd:removeType(parent($target)) is invoked. removeType(parent); addToPutSet(update.getTarget(), &update, context); }