Beispiel #1
0
bool XercesURIResolver::resolveDocument(Sequence &result, const XMLCh* uri, DynamicContext* context, const QueryPathNode *projection)
{
  Node::Ptr doc;

  // Resolve the uri against the base uri
  const XMLCh *systemId = uri;
  XMLURL urlTmp(context->getMemoryManager());
  if(urlTmp.setURL(context->getBaseURI(), uri, urlTmp)) {
    systemId = context->getMemoryManager()->getPooledString(urlTmp.getURLText());
  } else {
	systemId = context->getMemoryManager()->getPooledString(uri);
  }

  // Check in the cache
  DOMDocument *found = _documentMap.get((void*)systemId);

  // Check to see if we can locate and parse the document
  if(found == 0) {
    try {
      doc = const_cast<DocumentCache*>(context->getDocumentCache())->loadDocument(uri, context, projection);

      found = (DOMDocument*)((DOMNode*)doc->getInterface(XercesConfiguration::gXerces));

      _documentMap.put((void*)systemId, found);
      _uriMap.put((void*)found, const_cast<XMLCh*>(systemId));
    }
    catch(const XMLParseException& e) {
      XMLBuffer errMsg;
      errMsg.set(X("Error parsing resource: "));
      errMsg.append(uri);
      errMsg.append(X(". Error message: "));
      errMsg.append(e.getError());
      errMsg.append(X(" [err:FODC0002]"));
      XQThrow2(XMLParseException,X("XercesContextImpl::resolveDocument"), errMsg.getRawBuffer());
    }
  }
  else {
    doc = new XercesNodeImpl(found, (XercesURIResolver*)context->getDefaultURIResolver());
  }

  if(doc.notNull()) {
    result.addItem(doc);
    return true;
  }

  XMLBuffer errMsg;
  errMsg.set(X("Error retrieving resource: "));
  errMsg.append(uri);
  errMsg.append(X(" [err:FODC0002]"));
  XQThrow2(XMLParseException,X("XercesContextImpl::resolveDocument"), errMsg.getRawBuffer());

  return false;
}
Beispiel #2
0
TupleNode *ForTuple::staticResolution(StaticContext *context)
{
  parent_ = parent_->staticResolution(context);

  varURI_ = context->getUriBoundToPrefix(XPath2NSUtils::getPrefix(varQName_, context->getMemoryManager()), this);
  varName_ = XPath2NSUtils::getLocalName(varQName_);

  if(posQName_ && *posQName_) {
    posURI_ = context->getUriBoundToPrefix(XPath2NSUtils::getPrefix(posQName_, context->getMemoryManager()), this);
    posName_ = XPath2NSUtils::getLocalName(posQName_);

    if(XPath2Utils::equals(posName_, varName_) && XPath2Utils::equals(posURI_, varURI_)) {
      XMLBuffer errMsg;
      errMsg.set(X("The positional variable with name {"));
      errMsg.append(posURI_);
      errMsg.append(X("}"));
      errMsg.append(posName_);
      errMsg.append(X(" conflicts with the iteration variable [err:XQST0089]"));
      XQThrow(StaticErrorException,X("ForTuple::staticResolution"), errMsg.getRawBuffer());
    }
  }

  expr_ = expr_->staticResolution(context);

  return this;
}
Beispiel #3
0
ASTNode* XQFunctionCall::staticResolution(StaticContext *context) 
{
  if(uri_ == 0) {
    if(prefix_ == 0 || *prefix_ == 0) {
      uri_ = context->getDefaultFuncNS();
    }
    else {
      uri_ = context->getUriBoundToPrefix(prefix_, this);
    }
  }

  ASTNode *result = context->lookUpFunction(uri_, name_, *args_, this);
  if(result == 0) {
    XMLBuffer buf;
    buf.set(X("A function called {"));
    buf.append(uri_);
    buf.append(X("}"));
    buf.append(name_);
    buf.append(X(" with "));
    XPath2Utils::numToBuf(args_ ? (unsigned int)args_->size() : 0, buf);
    buf.append(X(" arguments is not defined [err:XPST0017]"));

    XQThrow(StaticErrorException, X("XQFunctionCall::staticResolution"), buf.getRawBuffer());
  }

  // Our arguments don't belong to us anymore
  for(VectorOfASTNodes::iterator i = args_->begin(); i != args_->end(); ++i) {
    *i = 0;
  }
  // Release this object
  this->release();

  return result->staticResolution(context);
}
Beispiel #4
0
Item::Ptr AtomizeResult::next(DynamicContext *context)
{
  // for $item in (Expr) return
  //   typeswitch ($item)
  //     case $value as atomic value return $value
  //     default $node return fn:data($node)

  Item::Ptr result = _sub->next(context);
  while(result.isNull()) {
    _sub = 0;
    result = _parent->next(context);
    if(result.isNull()) {
      _parent = 0;
      return 0;
    }
    if(result->isNode()) {
      _sub = ((Node*)result.get())->dmTypedValue(context);
      result = _sub->next(context);
    }
    else if(result->isFunction()) {
      XMLBuffer buf;
      buf.set(X("Sequence does not match type (xs:anyAtomicType | node())*"));
      buf.append(X(" - found item of type "));
      result->typeToBuffer(context, buf);
      buf.append(X(" [err:XPTY0004]"));
      XQThrow(XPath2TypeMatchException, X("AtomizeResult::next"), buf.getRawBuffer());
    }
  }
  return result;
}
Beispiel #5
0
void FunctionLookup::insertFunction(FuncFactory *func)
{
  // Use similar algorithm to lookup in order to detect overlaps
  // in argument numbers
  RefHash2KeysTableOfEnumerator<FuncFactory> iterator(const_cast<RefHash2KeysTableOf< FuncFactory >* >(&_funcTable));
  //
  // Walk the matches for the primary key (name) looking for overlaps:
  //   ensure func->max < min OR func->min > max
  //
  iterator.setPrimaryKey(func->getURINameHash());
  while(iterator.hasMoreElements())
    {
      FuncFactory *entry= &(iterator.nextElement());
      if ((func->getMaxArgs() < entry->getMinArgs()) ||
          (func->getMinArgs() > entry->getMaxArgs()))
        continue;
      // overlap -- throw exception
      XMLBuffer buf;
      buf.set(X("Multiple functions have the same expanded QName and number of arguments {"));
      buf.append(func->getURI());
      buf.append(X("}"));
      buf.append(func->getName());
      buf.append(X("#"));
      if(func->getMinArgs() >= entry->getMinArgs() &&
         func->getMinArgs() <= entry->getMaxArgs())
        XPath2Utils::numToBuf((unsigned int)func->getMinArgs(), buf);
      else
        XPath2Utils::numToBuf((unsigned int)entry->getMinArgs(), buf);
      buf.append(X(" [err:XQST0034]."));
      XQThrow2(StaticErrorException,X("FunctionLookup::insertFunction"), buf.getRawBuffer());
    }
  // Ok to add function
  size_t secondaryKey = SECONDARY_KEY(func);
  _funcTable.put((void*)func->getURINameHash(), (int)secondaryKey, func);
}
Beispiel #6
0
Result XQNameExpression::createResult(DynamicContext* context, int flags) const
{
    AnyAtomicType::Ptr itemName = getExpression()->createResult(context)->next(context);

    switch(itemName->getPrimitiveTypeIndex()) {
    case AnyAtomicType::QNAME:
        return (Item::Ptr)itemName;
    case AnyAtomicType::STRING:
    case AnyAtomicType::UNTYPED_ATOMIC:
        try {
            return (Item::Ptr)context->getItemFactory()->createDerivedFromAtomicType(AnyAtomicType::QNAME, itemName->asString(context), context);
        }
        catch(XQException &) {
            XQThrow(ASTException,X("XQNameExpression::NameExpressionResult::createResult"),
                    X("The name expression cannot be converted to a xs:QName [err:XQDY0074]"));
        }
    default:
        break;
    }

    XMLBuffer buf;
    buf.set(X("The name expression must be a single xs:QName, xs:string or xs:untypedAtomic"));
    buf.append(X(" - found item of type "));
    itemName->typeToBuffer(context, buf);
    buf.append(X(" [err:XPTY0004]"));
    XQThrow(XPath2TypeMatchException, X("XQNameExpression::NameExpressionResult::createResult"), buf.getRawBuffer());
}
Beispiel #7
0
ASTNode* FunctionLookup::lookUpFunction(const XMLCh* URI, const XMLCh* fname,
                                        const VectorOfASTNodes &args, XPath2MemoryManager* memMgr) const
{
  if (this != g_globalFunctionTable) {
    ASTNode *ret = g_globalFunctionTable->lookUpFunction(
                                                         URI, fname, args, memMgr);
    if (ret)
      return ret;
  }

  RefHash2KeysTableOfEnumerator<FuncFactory> iterator(const_cast<RefHash2KeysTableOf< FuncFactory >* >(&_funcTable));
  //
  // Walk the matches for the primary key (name) looking for matches
  // based on allowable parameters
  //
  XMLBuffer key;
  key.set(fname);
  key.append(':');
  key.append(URI);
  iterator.setPrimaryKey(key.getRawBuffer());
  size_t nargs = args.size();
  while(iterator.hasMoreElements()) {
    FuncFactory *entry= &(iterator.nextElement());
    if (entry->getMinArgs() <= nargs &&
        entry->getMaxArgs() >= nargs)
      return entry->createInstance(args, memMgr);
  }
  return NULL;
}
Beispiel #8
0
const ExternalFunction *FunctionLookup::lookUpExternalFunction(
  const XMLCh* URI, const XMLCh* fname, size_t numArgs) const
{
  size_t secondaryKey = numArgs;
  XMLBuffer key;
  key.set(fname);
  key.append(':');
  key.append(URI);
  return _exFuncTable.get(key.getRawBuffer(), (int)secondaryKey);
}
Beispiel #9
0
EventGenerator::Ptr XQCommentConstructor::generateEvents(EventHandler *events, DynamicContext *context,
                                                    bool preserveNS, bool preserveType) const
{
  XMLBuffer value;
  getStringValue(m_value, value, context);

  // Check for two dashes in a row, or a dash at the end
  if(xslt_) {
    XMLBuffer buf(value.getLen());
    bool foundDash = false;
    const XMLCh *ptr = value.getRawBuffer();
    const XMLCh *end = ptr + value.getLen();
    while(ptr != end) {
      if(*ptr == chDash) {
        if(foundDash) {
          buf.append(' ');
        }
        foundDash = true;
      }
      else foundDash = false;

      buf.append(*ptr);
      ++ptr;
    }

    if(foundDash) {
      buf.append(' ');
    }

    value.set(buf.getRawBuffer());
  }
  else {
    bool foundDash = false;
    const XMLCh *ptr = value.getRawBuffer();
    const XMLCh *end = ptr + value.getLen();
    while(ptr != end) {
      if(*ptr == chDash) {
        if(foundDash) break;
        foundDash = true;
      }
      else foundDash = false;
      ++ptr;
    }
    if(foundDash)
      XQThrow(ASTException,X("DOM Constructor"),X("It is a dynamic error if the result of the content expression of "
                                                  "a computed comment constructor contains two adjacent hyphens or "
                                                  "ends with a hyphen. [err:XQDY0072]"));
  }

  events->commentEvent(value.getRawBuffer());
  return 0;
}
Beispiel #10
0
 virtual InputSource *resolveEntity(XMLResourceIdentifier* resourceIdentifier)
 {
   if(resourceIdentifier->getResourceIdentifierType() == XMLResourceIdentifier::UnKnown &&
      XPath2Utils::equals(resourceIdentifier->getNameSpace(), m_PreviousModuleNamespace)) {
     XMLBuffer buf;
     buf.set(X("The graph of module imports contains a cycle for namespace '"));
     buf.append(resourceIdentifier->getNameSpace());
     buf.append(X("' [err:XQST0073]"));
     XQThrow3(StaticErrorException, X("LoopDetector::resolveEntity"), buf.getRawBuffer(), m_location);
   }
   if(m_pParentResolver)
     return m_pParentResolver->resolveEntity(resourceIdentifier);
   return NULL;
 }
Beispiel #11
0
FunctionRef::Ptr FunctionRefImpl::partialApply(const Result &arg, unsigned int argNum, DynamicContext *context, const LocationInfo *location) const
{
  if(getNumArgs() < argNum) {
    XMLBuffer buf;
    buf.set(X("The function item argument to fn:partial-apply() must have an arity of at least "));
    XPath2Utils::numToBuf(argNum, buf);
    buf.append(X(" - found item of type "));
    typeToBuffer(context, buf);
    buf.append(X(" [err:TBD]"));
    XQThrow3(XPath2TypeMatchException, X("FunctionRefImpl::partialApply"), buf.getRawBuffer(), location);
  }

  return new FunctionRefImpl(this, arg, argNum - 1, context);
}
Beispiel #12
0
static void duplicateVariableError(const XQGlobalVariable *existing, const XQGlobalVariable *bad,
                                   MessageListener *mlistener)
{
  if(mlistener) {
    mlistener->warning(X("In the context of this variable declaration"), existing);
  }
  XMLBuffer buf;
  buf.set(X("A variable with name {"));
  buf.append(bad->getVariableURI());
  buf.append(X("}"));
  buf.append(bad->getVariableLocalName());
  buf.append(X(" conflicts with an existing global variable [err:XQST0049]."));
  XQThrow3(StaticErrorException, X("XQQuery::staticResolution"), buf.getRawBuffer(), bad);
}
Beispiel #13
0
const XMLCh *FunctionReplace::replace(const XMLCh *input, const XMLCh *pattern, const XMLCh *replacement, const XMLCh *options, MemoryManager *mm)
{
  // Always turn off head character optimisation, since it is broken
  XMLBuffer optionsBuf;
  optionsBuf.set(options);
  optionsBuf.append(chLatin_H);

  //Now attempt to replace
  RegularExpression regEx(pattern, optionsBuf.getRawBuffer(), mm);
#ifdef HAVE_ALLMATCHES
  return regEx.replace(input, replacement, mm);
#else
  return regEx.replace(input, replacement);
#endif
}
Beispiel #14
0
Result FunctionRefImpl::execute(const VectorOfResults &args, DynamicContext *context, const LocationInfo *location) const
{
  if(args.size() != getNumArgs()) {
    XMLBuffer buf;
    buf.set(X("The function item invoked does not accept "));
    XPath2Utils::numToBuf((unsigned int)args.size(), buf);
    buf.append(X(" arguments - found item of type "));
    typeToBuffer(context, buf);
    buf.append(X(" [err:XPTY0004]"));
    XQThrow3(XPath2TypeMatchException, X("FunctionRefImpl::execute"), buf.getRawBuffer(), location);
  }

  FunctionRefScope scope(this, args, context);
  AutoVariableStoreReset vsReset(context, &scope);
  return instance_->createResult(context);
}
Beispiel #15
0
ASTNode *XQAtomize::staticTypingImpl(StaticContext *context)
{
  _src.clear();

  _src.getStaticType() = expr_->getStaticAnalysis().getStaticType();
  _src.add(expr_->getStaticAnalysis());

  if(expr_->getStaticAnalysis().isUpdating()) {
    XQThrow(StaticErrorException,X("XQAtomize::staticTyping"),
            X("It is a static error for an atomized expression "
              "to be an updating expression [err:XUST0001]"));
  }

  if(_src.getStaticType().isType(StaticType::FUNCTION_TYPE) &&
     _src.getStaticType().getMin() > 0) {
    XMLBuffer buf;
    buf.set(X("Sequence does not match type (xs:anyAtomicType | node())*"));
    buf.append(X(" - the expression has a static type of "));
    _src.getStaticType().typeToBuf(buf);
    buf.append(X(" [err:XPTY0004]"));
    XQThrow(XPath2TypeMatchException, X("XQAtomize::staticTyping"), buf.getRawBuffer());
  }

  if(!_src.getStaticType().containsType(StaticType::NODE_TYPE|StaticType::FUNCTION_TYPE)) {
    // If the expression has no nodes, this function does nothing
    return substitute(expr_);
  }

  if(doPSVI_) {
    _src.getStaticType().substitute(StaticType::ELEMENT_TYPE | StaticType::ATTRIBUTE_TYPE,
                                    StaticType(StaticType::ANY_ATOMIC_TYPE, 0, StaticType::UNLIMITED));
  } else {
    _src.getStaticType().substitute(StaticType::ELEMENT_TYPE | StaticType::ATTRIBUTE_TYPE,
                                    StaticType::UNTYPED_ATOMIC_TYPE);
  }

  _src.getStaticType().substitute(StaticType::DOCUMENT_TYPE | StaticType::TEXT_TYPE,
                                  StaticType::UNTYPED_ATOMIC_TYPE);
  _src.getStaticType().substitute(StaticType::NAMESPACE_TYPE | StaticType::COMMENT_TYPE |
                                  StaticType::PI_TYPE, StaticType::STRING_TYPE);

  // Remove function types
  _src.getStaticType() &= StaticType(StaticType::NODE_TYPE | StaticType::ANY_ATOMIC_TYPE, 0, StaticType::UNLIMITED);

  return this;
}
Beispiel #16
0
Item::Ptr SequenceType::TypeMatchesResult::next(DynamicContext *context)
{
  Item::Ptr item = _parent->next(context);
  if(item.isNull()) {
    _parent = 0;
  }
  else if(!_seqType->getItemType()->matches(item, context)) {
    XMLBuffer buf;
    buf.set(X("Sequence does not match type "));
    _seqType->toBuffer(buf);
    buf.append(X(" - found item of type "));
    item->typeToBuffer(context, buf);
    buf.append(X(" ["));
    buf.append(_errorCode);
    buf.append(X("]"));
    XQThrow(XPath2TypeMatchException, X("SequenceType::MatchesResult::next"), buf.getRawBuffer());
  }

  return item;
}
Beispiel #17
0
void RegExpFunction::copyRegExp(RegExpFunction* source, XPath2MemoryManager* memMgr)
{
  if(source->regExp_)
  {
    pattern_ = memMgr->getPooledString(source->pattern_);
    options_ = memMgr->getPooledString(source->options_);

    // Always turn off head character optimisation, since it is broken
    XMLBuffer optionsBuf;
    optionsBuf.set(options_);
    optionsBuf.append(chLatin_H);

    //compiling regexp again
    try
    {
      regExp_ = new (memMgr) RegularExpression(pattern_, optionsBuf.getRawBuffer(), memMgr);
    } catch (ParseException &e){
      processParseException(e, "RegExpFunction::copyRegExp", memMgr);
    }
  }
}
Beispiel #18
0
bool XQQuery::staticTypingOnce(StaticTyper *styper)
{
  switch(m_staticTyped) {
  case AFTER: return false;
  case DURING: {
      XMLBuffer buf;
      buf.set(X("The graph of module imports contains a cycle for namespace '"));
      buf.append(getModuleTargetNamespace());
      buf.append(X("' [err:XQST0093]"));
      XQThrow2(StaticErrorException, X("XQQuery::staticResolution"), buf.getRawBuffer());
  }
  case BEFORE: break;
  }

  m_staticTyped = DURING;

  staticTyping(styper);

  m_staticTyped = AFTER;
  m_moduleCache->ordered_.push_back(this);

  return true;
}
Beispiel #19
0
ASTNode *ArithmeticOperator::staticTypingImpl(StaticContext *context)
{
  _src.clear();

  bool emptyArgument = false;
  for(VectorOfASTNodes::iterator i = _args.begin(); i != _args.end(); ++i) {
    if((*i)->getStaticAnalysis().isUpdating()) {
      XQThrow(StaticErrorException,X("ArithmeticOperator::staticTyping"),
              X("It is a static error for an operand of an operator "
                "to be an updating expression [err:XUST0001]"));
    }

    if((*i)->getStaticAnalysis().getStaticType().getMin() == 0)
      emptyArgument = true;
    _src.add((*i)->getStaticAnalysis());

    if((*i)->isDateOrTimeAndHasNoTimezone(context))
      _src.implicitTimezoneUsed(true);
  }

  _src.getStaticType() = StaticType();
  calculateStaticType();

  if(!emptyArgument && _src.getStaticType().getMax() == 0) {
    XMLBuffer errMsg;
    errMsg.set(X("The operator "));
    errMsg.append(_opName);
    errMsg.append(X(" has been called on invalid operand types [err:XPTY0004]"));
    XQThrow(XPath2ErrorException,X("ArithmeticOperator::staticResolution"), errMsg.getRawBuffer());
  }

  if(emptyArgument)
    _src.getStaticType().setCardinality(0, 1);
  else _src.getStaticType().setCardinality(1, 1);

  return this;
}
Beispiel #20
0
ASTNode *XQNameExpression::staticTypingImpl(StaticContext *context)
{
    _src.clear();

    _src.getStaticType() = StaticType::QNAME_TYPE;

    _src.add(expr_->getStaticAnalysis());

    if(expr_->getStaticAnalysis().getStaticType().isType(StaticType::QNAME_TYPE)) {
        return expr_;
    }

    if(!expr_->getStaticAnalysis().getStaticType().
            containsType(StaticType::QNAME_TYPE|StaticType::STRING_TYPE|StaticType::UNTYPED_ATOMIC_TYPE)) {
        XMLBuffer buf;
        buf.set(X("The name expression must be a single xs:QName, xs:string or xs:untypedAtomic"));
        buf.append(X(" - the expression has a static type of "));
        expr_->getStaticAnalysis().getStaticType().typeToBuf(buf);
        buf.append(X(" [err:XPTY0004]"));
        XQThrow(XPath2TypeMatchException, X("XQNameExpression::staticTyping"), buf.getRawBuffer());
    }

    return this;
}
Beispiel #21
0
Item::Ptr SequenceType::OccurrenceMatchesResult::next(DynamicContext *context)
{
  Item::Ptr item = _parent->next(context);

  // "SequenceType matching between a given value and a given SequenceType is performed as follows:
  //  If the SequenceType is empty, the match succeeds only if the value is an empty sequence."
  if(_seqType->getItemType() == NULL && item.notNull()) {
    XMLBuffer buf;
    buf.set(X("Sequence does not match type "));
    _seqType->toBuffer(buf);
    buf.append(X(" - the sequence contains items ["));
    buf.append(X(" ["));
    buf.append(_errorCode);
    buf.append(X("]"));
    XQThrow(XPath2TypeMatchException, X("SequenceType::OccurrenceMatchesResult::next"), buf.getRawBuffer());
  }
  // "If the SequenceType contains an ItemType and an OccurrenceIndicator, the match succeeds only if 
  //  the number of items in the value matches the OccurrenceIndicator and each of these items matches the ItemType. "
  if(_seqType->getItemType() &&
     (_seqType->getOccurrenceIndicator() == PLUS || _seqType->getOccurrenceIndicator() == EXACTLY_ONE) &&
     item.isNull()) {
    XMLBuffer buf;
    buf.set(X("Sequence does not match type "));
    _seqType->toBuffer(buf);
    buf.append(X(" - the sequence does not contain items ["));
    buf.append(_errorCode);
    buf.append(X("]"));
    XQThrow(XPath2TypeMatchException, X("SequenceType::OccurrenceMatchesResult::next"), buf.getRawBuffer());
  }

  // "If the SequenceType is an ItemType with no OccurrenceIndicator, the match succeeds only if 
  //  the value contains precisely one item and that item matches the ItemType "
  if(_seqType->getItemType() &&
     (_seqType->getOccurrenceIndicator() == EXACTLY_ONE || _seqType->getOccurrenceIndicator() == QUESTION_MARK) &&
     item.notNull()) {
    // Do the tests on the number of items up front,
    // since often functions that cast to a single or
    // optional item only call next once. - jpcs

    Item::Ptr second = _parent->next(context);

    if(second.isNull()) {
      _parent = 0;
    }
    else {
      XMLBuffer buf;
      buf.set(X("Sequence does not match type "));
      _seqType->toBuffer(buf);
      buf.append(X(" - the sequence contains more than one item ["));
      buf.append(_errorCode);
      buf.append(X("]"));
      XQThrow(XPath2TypeMatchException, X("SequenceType::OccurrenceMatchesResult::next"), buf.getRawBuffer());
    }
  }

  if(item.isNull()) {
    *resultPointer_ = 0;
  }
  else {
    *resultPointer_ = _parent;
  }

  return item;
}
Beispiel #22
0
void XQQuery::importModule(const XMLCh* szUri, VectorOfStrings* locations, const LocationInfo *location)
{
  for(ImportedModules::iterator modIt = m_importedModules.begin();
      modIt != m_importedModules.end(); ++modIt) {
    if(XPath2Utils::equals((*modIt)->getModuleTargetNamespace(),szUri)) {
      XMLBuffer buf;
      buf.set(X("Module for namespace '"));
      buf.append(szUri);
      buf.append(X("' has already been imported [err:XQST0047]"));
      XQThrow3(StaticErrorException, X("XQQuery::ImportModule"), buf.getRawBuffer(), location);
    }
  }

  // Search in the module cache
  XQQuery *module = 0;
  if(!XPath2Utils::equals(szUri, m_szTargetNamespace)) {
    module = m_moduleCache->getByNamespace(szUri);
    if(module != 0) {
      importModule(module);
      return;
    }
  }

  if(locations == NULL)
    locations = m_context->resolveModuleURI(szUri);
  if(locations == NULL || locations->empty()) {
    XMLBuffer buf;
    buf.set(X("Cannot locate module for namespace "));
    buf.append(szUri);
    buf.append(X(" without the 'at <location>' keyword [err:XQST0059]"));
    XQThrow3(StaticErrorException,X("XQQuery::ImportModule"), buf.getRawBuffer(), location);
  }

  for(VectorOfStrings::iterator it=locations->begin();it!=locations->end();++it) {
    module = parseModule(szUri, *it, location);

    if(!module->getIsLibraryModule()) {
      XMLBuffer buf;
      buf.set(X("The module at "));
      buf.append(module->getFile());
      buf.append(X(" is not a module"));
      XQThrow3(StaticErrorException, X("XQQuery::ImportModule"), buf.getRawBuffer(), location);
    }
    if(!XERCES_CPP_NAMESPACE::XMLString::equals(szUri, module->getModuleTargetNamespace())) {
      XMLBuffer buf;
      buf.set(X("The module at "));
      buf.append(module->getFile());
      buf.append(X(" specifies a different namespace [err:XQST0059]"));
      XQThrow3(StaticErrorException, X("XQQuery::ImportModule"), buf.getRawBuffer(), location);
    }
  }

  // Search in the module cache again, to get the head of the linked list of modules
  module = m_moduleCache->getByNamespace(szUri);
  if(!module) {
    XMLBuffer buf;
    buf.set(X("Cannot locate the module for namespace \""));
    buf.append(szUri);
    buf.append(X("\" [err:XQST0059]"));
    XQThrow3(StaticErrorException,X("XQQuery::ImportModule"), buf.getRawBuffer(), location);
  }

  importModule(module);
}
Beispiel #23
0
void XQUserFunction::staticResolutionStage1(StaticContext *context)
{
  XPath2MemoryManager *mm = context->getMemoryManager();

  resolveName(context);

  if(name_ != 0 && !isTemplate_ && !delayed_) {
    if(XPath2Utils::equals(uri_, XMLUni::fgXMLURIName) ||
       XPath2Utils::equals(uri_, SchemaSymbols::fgURI_SCHEMAFORSCHEMA) ||
       XPath2Utils::equals(uri_, SchemaSymbols::fgURI_XSI) ||
       XPath2Utils::equals(uri_, XQFunction::XMLChFunctionURI) ||
       XPath2Utils::equals(uri_, SchemaSymbols::fgURI_SCHEMAFORSCHEMA)) {
      XQThrow(FunctionException, X("XQUserFunction::staticResolutionStage1"),
              X("A user defined function must not be in the namespaces xml, xsd, xsi, fn or xdt [err:XQST0045]"));
    }
    else if(uri_ == 0 || *uri_ == 0)
      XQThrow(FunctionException, X("XQUserFunction::staticResolutionStage1"),
              X("A user defined function must be defined in a namespace [err:XQST0060]"));
  }

  // Check for the implementation of an external function
  if(body_ == NULL) {
    exFunc_ = context->lookUpExternalFunction(uri_, name_, minArgs_);

    if(exFunc_ == NULL) {
      XMLBuffer buf;
      buf.set(X("External function '{"));
      buf.append(uri_);
      buf.append(X("}"));
      buf.append(name_);
      buf.append(X("' with "));
      XMLCh szNumBuff[20];
      XMLString::binToText((unsigned int)minArgs_, szNumBuff, 19, 10);
      buf.append(szNumBuff);
      buf.append(X(" argument(s) has not been bound to an implementation"));
      XQThrow(FunctionException, X("XQUserFunction::staticResolutionStage1"), buf.getRawBuffer());
    }
  }

  signature_->staticResolution(context);

  // Resolve the mode names
  if(modes_) {
    if(modes_->empty()) {
      XQThrow(StaticErrorException, X("XQUserFunction::staticResolution"),
              X("At least one mode must be specified for a template [err:XTSE0550]"));
    }

    ModeList::iterator it, it2;
    for(it = modes_->begin(); it != modes_->end(); ++it) {
      (*it)->staticResolution(context);

      // Check for "#all" with other values
      if((*it)->getState() == Mode::ALL && modes_->size() != 1) {
        XQThrow3(StaticErrorException, X("XQUserFunction::staticResolution"),
                 X("The mode #all must not be specified in addition to other modes [err:XTSE0550]"), *it);
      }

      // Check for duplicate modes
      it2 = it;
      for(++it2; it2 != modes_->end(); ++it2) {
        if((*it)->getState() == (*it2)->getState() &&
           XPath2Utils::equals((*it)->getName(), (*it2)->getName()) &&
           XPath2Utils::equals((*it)->getURI(), (*it2)->getURI())) {
          XMLBuffer buf;
          buf.append(X("The mode {"));
          buf.append((*it)->getURI());
          buf.append(X("}"));
          buf.append((*it)->getName());
          buf.append(X(" has been specified more than once [err:XTSE0550]"));
          XQThrow3(StaticErrorException, X("XQUserFunction::staticResolution"), buf.getRawBuffer(), *it2);
        }
      }
    }
  }

  // Set up a default StaticType and StaticAnalysis
  if(signature_->returnType) {
    if(body_ != NULL) {
      body_ = signature_->returnType->convertFunctionArg(body_, context, /*numericfunction*/false, signature_->returnType);
    }

    bool isPrimitive;
    signature_->returnType->getStaticType(src_.getStaticType(), context, isPrimitive, signature_->returnType);
  }
  else {
    // Default type is item()*
    src_.getStaticType() = StaticType(StaticType::ITEM_TYPE, 0, StaticType::UNLIMITED);
  }

  if(signature_->updating == FunctionSignature::OP_TRUE) {
    src_.updating(true);
  }

  // TBD What about the other parts of the StaticAnalysis - jpcs
  src_.forceNoFolding(true);

  if(pattern_ != 0 && !pattern_->empty()) {
    // Set the pattern's initial static type to NODE_TYPE
    VectorOfASTNodes::iterator patIt = pattern_->begin();
    for(; patIt != pattern_->end(); ++patIt) {
      const_cast<StaticAnalysis&>((*patIt)->getStaticAnalysis()).getStaticType() = StaticType(StaticType::NODE_TYPE, 0, StaticType::UNLIMITED);
    }
  }

  if(isTemplate_) {
    // Build an instance of the template for us to call
    VectorOfASTNodes newArgs = VectorOfASTNodes(XQillaAllocator<ASTNode*>(mm));

    if(signature_->argSpecs != 0) {
      ArgumentSpecs::const_iterator argIt;
      for(argIt = signature_->argSpecs->begin(); argIt != signature_->argSpecs->end(); ++argIt) {
        XQVariable *argVar = new (mm) XQVariable((*argIt)->getURI(), (*argIt)->getName(), mm);
        argVar->setLocationInfo(*argIt);
        newArgs.push_back(argVar);
      }
    }

    templateInstance_ = createInstance(newArgs, mm);
    templateInstance_->setLocationInfo(this);
  }
}
Beispiel #24
0
Sequence FunctionUnparsedText::createSequence(DynamicContext* context, int flags) const
{
  Item::Ptr uriArg = getParamNumber(1, context)->next(context);
  
  if(uriArg.isNull()) {
    return Sequence(context->getMemoryManager());
  }
  
  const XMLCh *uri = uriArg->asString(context);

  if(!XPath2Utils::isValidURI(uri, context->getMemoryManager()))
    XQThrow(FunctionException, X("FunctionUnparsedText::createSequence"), X("The argument to fn:unparsed-text() is not a valid URI [err:XTDE1170]"));

  // TBD Implement a URIResolver method for resolving unparsed text - jpcs

  const XMLCh *baseUri = context->getBaseURI();

  InputSource *srcToUse = 0;
  if(context->getXMLEntityResolver()){
    XMLResourceIdentifier resourceIdentifier(XMLResourceIdentifier::UnKnown, uri, 0, XMLUni::fgZeroLenString, baseUri);
    srcToUse = context->getXMLEntityResolver()->resolveEntity(&resourceIdentifier);
  }

  if(srcToUse == 0) {
    try {
      // Resolve the uri against the base uri
      XMLURL urlTmp;

      if(baseUri && *baseUri) {
        urlTmp.setURL(baseUri, uri);
      }
      else {
        urlTmp.setURL(uri);
      }

      srcToUse = new URLInputSource(urlTmp);
    }
    catch(const MalformedURLException &e) {
    }
  }

  if(srcToUse == 0) {
    // It's not a URL, so let's assume it's a local file name.
    if(baseUri && *baseUri) {
      AutoDeallocate<XMLCh> tmpBuf(XMLPlatformUtils::weavePaths(baseUri, uri), XMLPlatformUtils::fgMemoryManager);
      srcToUse = new LocalFileInputSource(tmpBuf);
    }
    else {
      srcToUse = new LocalFileInputSource(uri);
    }
  }

  Janitor<InputSource> janIS(srcToUse);

  if(getNumArgs() == 2) {
    const XMLCh *encoding = getParamNumber(2, context)->next(context)->asString(context);
    srcToUse->setEncoding(encoding);
  }

  XMLBuffer result;
  try {
    BinInputStream *stream = srcToUse->makeStream();
    if(stream == NULL) {
      XMLBuffer buf;
      buf.set(X("Cannot read unparsed content from "));
      buf.append(uri);
      buf.append(X(" [err:XTDE1170]"));
      XQThrow2(FunctionException,X("FunctionUnparsedText::createSequence"), buf.getRawBuffer());
    }
    Janitor<BinInputStream> janStream(stream);

#ifdef HAVE_GETCONTENTTYPE
    if(FunctionMatches::matches(stream->getContentType(), X("(text|application)/(xml|[^ +;]+\\+xml)"), X("i"))) {
      srcToUse->setEncoding(0);
      srcToUse->setEncoding(FindXMLEncoding().start(*srcToUse, context));
    }
#endif

    XPath2Utils::readSource(stream, context->getMemoryManager(), result, srcToUse->getEncoding());
  }
  catch(XMLException &e) {
    XMLBuffer buf;
    buf.set(X("Exception reading unparsed content: "));
    buf.append(e.getMessage());
    buf.append(X(" [err:XTDE1190]"));
    XQThrow2(FunctionException,X("FunctionUnparsedText::createSequence"), buf.getRawBuffer());
  }

  return Sequence(context->getItemFactory()->createString(result.getRawBuffer(), context), context->getMemoryManager());
}
Beispiel #25
0
void SequenceType::ItemType::staticResolution(StaticContext *context, const LocationInfo *location)
{
  // Prefix resolution should only happen once
  // (since SequenceType objects can be multiple times in the AST)
  if(!staticallyResolved_) {
    staticallyResolved_ = true;

    if(m_pType && m_TypeURI == 0) {
      const XMLCh *prefix = m_pType->getPrefix();
      // an empty prefix means the default element and type namespace
      if(prefix == 0 || *prefix == 0) {
        m_TypeURI = context->getDefaultElementAndTypeNS();
      }
      else {
        m_TypeURI = context->getUriBoundToPrefix(prefix, location);
      }
    }
  
    if(m_pName && m_NameURI == 0) {
      const XMLCh *prefix = m_pName->getPrefix();
      // if we are testing for an attribute, an empty prefix means empty namespace; if we are testing an element, it means 
      // the default element and type namespace
      if(prefix == 0 || *prefix == 0) {
        if(m_nTestType == TEST_ELEMENT || m_nTestType == TEST_SCHEMA_ELEMENT ||
           m_nTestType == TEST_DOCUMENT || m_nTestType == TEST_SCHEMA_DOCUMENT)
          m_NameURI = context->getDefaultElementAndTypeNS();
      } else {
        m_NameURI = context->getUriBoundToPrefix(prefix, location);
      }
    }
  }

  if(m_pType) {
    if(m_nTestType == ItemType::TEST_ATOMIC_TYPE) {
      // check if the type to be tested is defined and is really an atomic one
      if(!context->getDocumentCache()->isTypeDefined(m_TypeURI, m_pType->getName())) {
        XMLBuffer buf;
        buf.set(X("Type {"));
        buf.append(m_TypeURI);
        buf.append(X("}:"));
        buf.append(m_pType->getName());
        buf.append(X(" is not defined [err:XPST0051]"));
        XQThrow3(StaticErrorException, X("SequenceType::ItemType::staticResolution"), buf.getRawBuffer(), location);
      }
      if(!context->getDocumentCache()->isTypeOrDerivedFromType(m_TypeURI, m_pType->getName(),
                                                               FunctionConstructor::XMLChXPath2DatatypesURI,
                                                               AnyAtomicType::fgDT_ANYATOMICTYPE)) {
        XMLBuffer buf;
        buf.set(X("Type {"));
        buf.append(m_TypeURI);
        buf.append(X("}:"));
        buf.append(m_pType->getName());
        buf.append(X(" is not an atomic type [err:XPST0051]"));
        XQThrow3(StaticErrorException, X("SequenceType::ItemType::staticResolution"), buf.getRawBuffer(), location);
      }
    }
    else if(!context->getDocumentCache()->isTypeDefined(m_TypeURI, m_pType->getName())) {
      XMLBuffer msg;
      msg.set(X("Type {"));
      msg.append(m_TypeURI);
      msg.append(X("}"));
      msg.append(m_pType->getName());
      msg.append(X(" is not defined [err:XPTY0004]"));
      XQThrow3(XPath2ErrorException,X("SequenceType::ItemType::matchesNameType"), msg.getRawBuffer(), location);
    }
  }

  switch(m_nTestType) {
  case TEST_SCHEMA_DOCUMENT:
  case TEST_SCHEMA_ELEMENT: {
    // retrieve the type of the element name
    SchemaElementDecl *elemDecl = context->getDocumentCache()->getElementDecl(m_NameURI, m_pName->getName());
    if(elemDecl == NULL) {
      XMLBuffer msg(1023, context->getMemoryManager());
      msg.set(X("Element {"));
      msg.append(m_NameURI);
      msg.append(X("}"));
      msg.append(m_pName->getName());
      msg.append(X(" is not defined as a global element [err:XPST0081]"));
      XQThrow3(StaticErrorException,X("SequenceType::ItemType::staticResolution"), msg.getRawBuffer(), location);
    }
    break;
  }
  case TEST_SCHEMA_ATTRIBUTE: {
    // retrieve the type of the attribute name
    SchemaAttDef *attrDecl = context->getDocumentCache()->getAttributeDecl(m_NameURI, m_pName->getName());
    if(attrDecl == NULL) {
      XMLBuffer msg(1023, context->getMemoryManager());
      msg.set(X("Attribute {"));
      msg.append(m_NameURI);
      msg.append(X("}"));
      msg.append(m_pName->getName());
      msg.append(X(" is not defined as a global attribute [err:XPST0081]"));
      XQThrow3(StaticErrorException,X("SequenceType::ItemType::staticResolution"), msg.getRawBuffer(), location);
    }
    break;
  }
  default: break;
  }

  if(returnType_)
    returnType_->staticResolution(context);
}
Beispiel #26
0
int main(int /*argc*/, char ** /*argv*/) {

    Normalizer *normalizer = new Normalizer();

    DOMDocument *doc = normalizer->createDocument();
    bool *tmpTrue = new bool(true);
    bool *tmpFalse = new bool(false);

    DOMElement* docFirstElement = doc->createElementNS(X("http://www.test.com"),X("docEle"));
    doc->appendChild(docFirstElement);
    DOMElement* docFirstElementChild = doc->createElementNS(X("http://www.test2.com"),X("docEleChild"));
    docFirstElement->appendChild(docFirstElementChild);

    //create default ns
    doc->normalizeDocument();
    normalizer->serializeNode(doc);
    XERCES_STD_QUALIFIER cout << "\n\n";

    //add in binding
    docFirstElement->setPrefix(X("po"));
    doc->normalizeDocument();
    normalizer->serializeNode(doc);
    XERCES_STD_QUALIFIER cout << "\n\n";

    //use default
    DOMElement* docFirstElementChildChild = doc->createElementNS(X("http://www.test2.com"),X("docEleChildChild"));
    docFirstElementChild->appendChild(docFirstElementChildChild);
    doc->normalizeDocument();
    normalizer->serializeNode(doc);
    XERCES_STD_QUALIFIER cout << "\n\n";

    // this block is needed to destroy the XMLBuffer 
    {
        //use a binding
        XMLBuffer buf;
        buf.set(XMLUni::fgXMLNSString);
        buf.append(chColon);
        buf.append(X("po2"));
        docFirstElementChild->removeAttributeNS(XMLUni::fgXMLNSURIName, XMLUni::fgXMLNSString);
        docFirstElement->removeAttributeNS(XMLUni::fgXMLNSURIName, XMLUni::fgXMLNSString);
        docFirstElement->setAttributeNS(XMLUni::fgXMLNSURIName, buf.getRawBuffer(), X("http://www.test2.com"));
        docFirstElementChild->setPrefix(X("po2"));
        doc->normalizeDocument();
        normalizer->serializeNode(doc);
        XERCES_STD_QUALIFIER cout << "\n\n";
    }

    //some siblngs to ensure the scope stacks are working
    docFirstElementChildChild = doc->createElementNS(X("http://www.test3.com"),X("docEleChildChild2"));
    docFirstElementChild->appendChild(docFirstElementChildChild);
    docFirstElementChildChild = doc->createElementNS(X("http://www.test4.com"),X("po4:docEleChildChild3"));
    docFirstElementChild->appendChild(docFirstElementChildChild);
    docFirstElementChildChild = doc->createElementNS(X("http://www.test4.com"),X("po4:docEleChildChild4"));
    docFirstElementChild->appendChild(docFirstElementChildChild);
    doc->normalizeDocument();
    normalizer->serializeNode(doc);
    XERCES_STD_QUALIFIER cout << "\n\n";

    //conflicting prefix
    docFirstElementChildChild->setAttributeNS(XMLUni::fgXMLNSURIName, X("po4"), X("conflict"));
    doc->normalizeDocument();
    normalizer->serializeNode(doc);
    XERCES_STD_QUALIFIER cout << "\n\n";
    
    //conflicting default
    docFirstElementChildChild = doc->createElementNS(X("http://www.test4.com"),X("docEleChildChild5"));
    docFirstElementChild->appendChild(docFirstElementChildChild);
    docFirstElementChildChild->setAttributeNS(XMLUni::fgXMLNSURIName, XMLUni::fgXMLNSString, X("conflict"));
    doc->normalizeDocument();
    normalizer->serializeNode(doc);
    XERCES_STD_QUALIFIER cout << "\n\n";

    //set the xmlns to ""
    DOMElement *noNamespaceEle = doc->createElementNS(X(""),X("noNamespace"));
    docFirstElementChildChild->appendChild(noNamespaceEle);
    doc->normalizeDocument();
    normalizer->serializeNode(doc);
    XERCES_STD_QUALIFIER cout << "\n\n";


    //now lets do a bit off attribute testing on the doc ele
    docFirstElement->setAttributeNS(X("http://testattr.com"), X("attr1"), X("value"));
    docFirstElement->setAttributeNS(X("http://testattr.com"), X("attr2"), X("value"));
    docFirstElement->setAttributeNS(X("http://testattr2.com"), X("attr3"), X("value"));
    docFirstElement->setAttributeNS(X("http://www.test.com"), X("attr4"), X("value"));
    docFirstElement->setAttributeNS(X("http://testattr2.com"), X("po:attr5"), X("value"));
    docFirstElement->setAttributeNS(X("http://testattr2.com"), X("poFake:attr6"), X("value"));
    docFirstElement->setAttributeNS(X("http://testattr3.com"), X("po3:attr7"), X("value"));
    doc->normalizeDocument();
    normalizer->serializeNode(doc);
    XERCES_STD_QUALIFIER cout << "\n\n";

    //and now on one of its children
    docFirstElementChildChild->setAttributeNS(X("http://testattr.com"), X("attr1"), X("value"));
    docFirstElementChildChild->setAttributeNS(X("http://testattr.com"), X("attr2"), X("value"));
    docFirstElementChildChild->setAttributeNS(X("http://testattr2.com"), X("attr3"), X("value"));
    docFirstElementChildChild->setAttributeNS(X("http://www.test.com"), X("attr4"), X("value"));
    docFirstElementChildChild->setAttributeNS(X("http://testattr2.com"), X("po:attr5"), X("value"));
    docFirstElementChildChild->setAttributeNS(X("http://testattr2.com"), X("poFake:attr6"), X("value"));
    docFirstElementChildChild->setAttributeNS(X("http://testattr3.com"), X("po3:attr7"), X("value"));
    docFirstElementChildChild->setAttributeNS(X("http://testattr4.com"), X("po4:attr8"), X("value"));
    

    //test for a clash with our NSx attrs
    docFirstElementChildChild->setAttributeNS(X("http://testclash.com"), X("NS1:attr9"), X("value"));
    docFirstElementChildChild->setAttributeNS(XMLUni::fgXMLNSURIName, X("xmlns:NS1"), X("http://testclash.com"));

    //clash with standard prefix
    docFirstElementChildChild->setAttributeNS(X("http://testattr5.com"), X("po:attr10"), X("value"));

    doc->normalizeDocument();
    normalizer->serializeNode(doc);
    XERCES_STD_QUALIFIER cout << "\n\n";


    //2 prefix with the same uri
    docFirstElementChildChild = doc->createElementNS(X("http://www.uri1.com"),X("docEleChildChild6"));
    docFirstElementChild->appendChild(docFirstElementChildChild);
    docFirstElementChildChild->setAttributeNS(XMLUni::fgXMLNSURIName, X("xmlns:uri1"), X("http://www.uri1.com"));
    docFirstElementChildChild->setAttributeNS(XMLUni::fgXMLNSURIName, X("xmlns:uri1b"), X("http://www.uri1.com"));
    docFirstElementChildChild->setAttributeNS(X("http://www.uri1.com"), X("uri1:attr1"), X("value"));
    docFirstElementChildChild->setAttributeNS(X("http://www.uri1.com"), X("uri1b:attr2"), X("value"));
    doc->normalizeDocument();
    normalizer->serializeNode(doc);
    XERCES_STD_QUALIFIER cout << "\n\n";

    //check to see we use the nearest binding and for more inheritence
    DOMElement *docFirstElementChildChildChild = doc->createElementNS(X("http://www.uri1.com"),X("docEleChildChildChild"));
    docFirstElementChildChild->appendChild(docFirstElementChildChildChild);
    docFirstElementChildChild->setAttributeNS(XMLUni::fgXMLNSURIName, X("xmlns:nearerThanPo"), X("http://www.test.com"));
    docFirstElementChildChildChild->setAttributeNS(X("http://testattr.com"), X("attr2"), X("value"));
    docFirstElementChildChildChild->setAttributeNS(X("http://www.test.com"), X("attr1"), X("value"));
    doc->normalizeDocument();
    normalizer->serializeNode(doc);
    XERCES_STD_QUALIFIER cout << "\n\n";


    //NS1.1 stuff

    //test creating default prefix when NS1 has been set to ""
    noNamespaceEle->setAttributeNS(XMLUni::fgXMLNSURIName, X("xmlns:NS1"), X(""));
    DOMElement *noNamespaceChild = doc->createElementNS(X("http://testclash.com"),X("testing1.1Stuff"));
    noNamespaceEle->appendChild(noNamespaceChild);
    doc->normalizeDocument();
    normalizer->serializeNode(doc);

    noNamespaceChild = doc->createElementNS(X("http://testclash.com"),X("NS1:testing1.1Stuff"));
    noNamespaceEle->appendChild(noNamespaceChild);
    
    noNamespaceChild->setAttributeNS(X("http://www.someRandomUri.com"), X("attr"), X("value"));
    doc->normalizeDocument();
    normalizer->serializeNode(doc);


    //check error conditions
    XERCES_STD_QUALIFIER cout << "error conditions" << XERCES_STD_QUALIFIER endl;

    DOMConfiguration *conf = doc->getDOMConfig();
    conf->setParameter(XMLUni::fgDOMErrorHandler, normalizer);
    conf->setParameter(XMLUni::fgDOMNamespaces, true);

    DOMElement *level1Node = doc->createElement(X("level1Node"));
    docFirstElement->appendChild(level1Node);
    doc->normalizeDocument();

    docFirstElement->removeChild(level1Node);
    docFirstElement->setAttribute(X("level1Attr"), X("level1"));
    doc->normalizeDocument();
    docFirstElement->removeAttribute(X("level1Attr"));

    //cant check this as Xerces does not let us do it
    //    noNamespaceChild->setAttributeNS(X("http://www.someRandomUri.com"), X("xmlns"), X("value"));
    //    doc->normalizeDocument();



    //lets do a sanity test on a comment
    DOMComment *comment = doc->createComment(X("some comment"));
    docFirstElement->appendChild(comment);
    doc->normalizeDocument();
    normalizer->serializeNode(doc);

    conf->setParameter(XMLUni::fgDOMComments, false);
    docFirstElement->appendChild(comment);
    doc->normalizeDocument();
    normalizer->serializeNode(doc);


    //and on a CDATA
    DOMCDATASection *cData = doc->createCDATASection(X("some cdata"));
    docFirstElement->appendChild(cData);
    doc->normalizeDocument();
    normalizer->serializeNode(doc);

    conf->setParameter(XMLUni::fgDOMCDATASections, false);
    docFirstElement->appendChild(cData);
    doc->normalizeDocument();
    normalizer->serializeNode(doc);

    delete normalizer;
    delete tmpTrue;
    delete tmpFalse;

    return 0;
}