예제 #1
0
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);
}
예제 #2
0
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);
}
예제 #3
0
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);
}