in src/xercesc/parsers/AbstractDOMParser.cpp [965:1195]
void AbstractDOMParser::startElement(const XMLElementDecl& elemDecl
, const unsigned int urlId
, const XMLCh* const elemPrefix
, const RefVectorOf<XMLAttr>& attrList
, const XMLSize_t attrCount
, const bool isEmpty
, const bool isRoot)
{
DOMElement *elem;
DOMElementImpl *elemImpl;
const XMLCh* namespaceURI = 0;
bool doNamespaces = fScanner->getDoNamespaces();
// Create the element name. Here we are going to bypass the
// DOMDocument::createElement() interface and instantiate the
// required types directly in order to avoid name checking
// overhead.
//
if (doNamespaces)
{
//DOM Level 2, doNamespaces on
//
const XMLCh* localName = elemDecl.getBaseName();
if (urlId != fScanner->getEmptyNamespaceId()) { //TagName has a prefix
namespaceURI = fScanner->getURIText(urlId); //get namespaceURI
if (elemPrefix && *elemPrefix)
{
XMLBufBid elemQName(&fBufMgr);
elemQName.set(elemPrefix);
elemQName.append(chColon);
elemQName.append(localName);
elem = createElementNS (
namespaceURI, elemPrefix, localName, elemQName.getRawBuffer());
}
else
elem = createElementNS (namespaceURI, 0, localName, localName);
}
else
elem = createElementNS (namespaceURI, 0, localName, localName);
}
else
{ //DOM Level 1
elem = createElement (elemDecl.getFullName());
}
elemImpl = (DOMElementImpl *) elem;
if (attrCount)
{
unsigned int xmlnsNSId = fScanner->getXMLNSNamespaceId();
unsigned int emptyNSId = fScanner->getEmptyNamespaceId();
DOMAttrMapImpl* map = elemImpl->fAttributes;
map->reserve (attrCount);
for (XMLSize_t index = 0; index < attrCount; ++index)
{
const XMLAttr* oneAttrib = attrList.elementAt(index);
DOMAttrImpl *attr = 0;
if (doNamespaces)
{
//DOM Level 2, doNamespaces on
//
unsigned int attrURIId = oneAttrib->getURIId();
const XMLCh* localName = oneAttrib->getName();
const XMLCh* prefix = oneAttrib->getPrefix();
namespaceURI = 0;
if ((prefix==0 || *prefix==0) && XMLString::equals(localName, XMLUni::fgXMLNSString))
{
// xmlns=...
attrURIId = xmlnsNSId;
}
if (attrURIId != emptyNSId)
{
//TagName has a prefix
namespaceURI = fScanner->getURIText(attrURIId);
}
attr = (DOMAttrImpl*) createAttrNS (namespaceURI,
prefix,
localName,
oneAttrib->getQName());
map->setNamedItemNSFast(attr);
}
else
{
attr = (DOMAttrImpl*) createAttr (oneAttrib->getName());
map->setNamedItemFast(attr);
}
attr->setValueFast(oneAttrib->getValue());
// Attributes of type ID. If this is one, add it to the hashtable of IDs
// that is constructed for use by GetElementByID().
//
if (oneAttrib->getType()==XMLAttDef::ID)
{
if (fDocument->fNodeIDMap == 0)
fDocument->fNodeIDMap = new (fDocument) DOMNodeIDMap(500, fDocument);
fDocument->fNodeIDMap->add(attr);
attr->fNode.isIdAttr(true);
}
attr->setSpecified(oneAttrib->getSpecified());
// store DTD validation information
if(fCreateSchemaInfo)
{
switch(oneAttrib->getType())
{
case XMLAttDef::CData: attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedCDATAAttribute); break;
case XMLAttDef::ID: attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDAttribute); break;
case XMLAttDef::IDRef: attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDREFAttribute); break;
case XMLAttDef::IDRefs: attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDREFSAttribute); break;
case XMLAttDef::Entity: attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENTITYAttribute); break;
case XMLAttDef::Entities: attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENTITIESAttribute); break;
case XMLAttDef::NmToken: attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNMTOKENAttribute); break;
case XMLAttDef::NmTokens: attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNMTOKENSAttribute); break;
case XMLAttDef::Notation: attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNOTATIONAttribute); break;
case XMLAttDef::Enumeration: attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENUMERATIONAttribute); break;
default: attr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdNotValidatedAttribute); break;
}
}
}
}
//Set up the default attributes if any.
//
if (elemDecl.hasAttDefs())
{
XMLAttDefList* defAttrs = &elemDecl.getAttDefList();
XMLAttDef* attr = 0;
DOMAttrImpl * insertAttr = 0;
for(XMLSize_t i=0; i<defAttrs->getAttDefCount(); i++)
{
attr = &defAttrs->getAttDef(i);
const XMLAttDef::DefAttTypes defType = attr->getDefaultType();
if ((defType == XMLAttDef::Default)
|| (defType == XMLAttDef::Fixed))
{
if (doNamespaces)
{
// DOM Level 2 wants all namespace declaration attributes
// to be bound to "http://www.w3.org/2000/xmlns/"
// So as long as the XML parser doesn't do it, it needs to
// be done here.
const XMLCh* qualifiedName = attr->getFullName();
XMLBufBid bbPrefixQName(&fBufMgr);
XMLBuffer& prefixBuf = bbPrefixQName.getBuffer();
int colonPos = -1;
unsigned int uriId = fScanner->resolveQName(qualifiedName, prefixBuf, ElemStack::Mode_Attribute, colonPos);
const XMLCh* namespaceURI = 0;
if (XMLString::equals(qualifiedName, XMLUni::fgXMLNSString)) //for xmlns=...
uriId = fScanner->getXMLNSNamespaceId();
if (uriId != fScanner->getEmptyNamespaceId()) { //TagName has a prefix
namespaceURI = fScanner->getURIText(uriId);
}
insertAttr = (DOMAttrImpl *) fDocument->createAttributeNS(namespaceURI, // NameSpaceURI
qualifiedName); // qualified name
DOMAttr* remAttr = elemImpl->setDefaultAttributeNodeNS(insertAttr);
if (remAttr)
remAttr->release();
}
else
{
// Namespaces is turned off...
insertAttr = (DOMAttrImpl *) fDocument->createAttribute(attr->getFullName());
DOMNode* remAttr = elemImpl->setDefaultAttributeNode(insertAttr);
if (remAttr)
remAttr->release();
}
//need to do this before the get as otherwise we overwrite any value in the attr
if (attr->getValue() != 0)
{
insertAttr->setValueFast(attr->getValue());
insertAttr->setSpecified(false);
}
// store DTD validation information
if(fCreateSchemaInfo)
{
switch(attr->getType())
{
case XMLAttDef::CData: insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedCDATAAttribute); break;
case XMLAttDef::ID: insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDAttribute); break;
case XMLAttDef::IDRef: insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDREFAttribute); break;
case XMLAttDef::IDRefs: insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedIDREFSAttribute); break;
case XMLAttDef::Entity: insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENTITYAttribute); break;
case XMLAttDef::Entities: insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENTITIESAttribute); break;
case XMLAttDef::NmToken: insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNMTOKENAttribute); break;
case XMLAttDef::NmTokens: insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNMTOKENSAttribute); break;
case XMLAttDef::Notation: insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedNOTATIONAttribute); break;
case XMLAttDef::Enumeration: insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdValidatedENUMERATIONAttribute); break;
default: insertAttr->setSchemaTypeInfo(&DOMTypeInfoImpl::g_DtdNotValidatedAttribute); break;
}
}
}
insertAttr = 0;
attr->reset();
}
}
if (fCurrentParent != fDocument)
castToParentImpl (fCurrentParent)->appendChildFast (elem);
else
fCurrentParent->appendChild (elem);
fCurrentParent = elem;
fCurrentNode = elem;
fWithinElement = true;
// If an empty element, do end right now (no endElement() will be called)
if (isEmpty)
endElement(elemDecl, urlId, isRoot, elemPrefix);
}