// Inherits XMLSpy generation source function. xmlNodePtr CNode::InternalGetAt(ENodeType eNodeType, const tstring& sNamespaceURI, const tstring& sName, int nIndex) { xmlChar* szNamespaceURI = NULL; if(sNamespaceURI.size() > 0) szNamespaceURI = X(sNamespaceURI); if (eNodeType == Element) { int nCount = 0; for (xmlNodePtr pNode = m_pDOMNode->children; pNode != NULL; pNode = pNode->next) if (pNode->type == XML_ELEMENT_NODE && InternalNamesMatch(pNode, sNamespaceURI, sName)) if (nCount++ == nIndex) return pNode; throw CXMLException(1, tstring(_T("Index out of range: ")) + sName); } else { xmlAttrPtr pAttr = xmlHasNsProp(m_pDOMNode, X(sName), szNamespaceURI); if (pAttr != NULL && pAttr->type != XML_ATTRIBUTE_DECL) return (xmlNodePtr)pAttr; else throw CXMLException(1, tstring(_T("Index out of range: ")) + sName); } }
// will miss some things such as the bar in <foo lol="wat" bar>, but whatever. void CXMLParser::ParseAttributes(const std::string& sTagContents, std::map<const std::string, std::string>& mAttributes) { std::string::size_type pos = sTagContents.find(" "); bool bInName = true, bWaitingForVal = false, bInVal = false; char cQuote = 0; std::string::size_type valStartPos = 0; std::string sName; while(pos != std::string::npos && pos < sTagContents.size()) { if(bInName && iswspace(sTagContents[pos])) { pos++; } else if(bInName && sTagContents[pos] == '=') { bInName = false; bWaitingForVal = true; pos = sTagContents.find_first_of("'\"", pos + 1); } else if(bInName) { sName += sTagContents[pos]; pos++; } else if(bWaitingForVal && (sTagContents[pos] == '"' || sTagContents[pos] == '\'')) { cQuote = sTagContents[pos]; bInVal = true; bWaitingForVal = false; valStartPos = pos + 1; pos = sTagContents.find(cQuote, pos + 1); } else if(bInVal && sTagContents[pos] == cQuote) { bInVal = false; bInName = true; mAttributes[sName] = sTagContents.substr(valStartPos, pos - valStartPos); mAttributes[sName] = XmlDecode(mAttributes[sName]); sName = ""; pos++; } else throw CXMLException("internal problem while parsing attributes", 0); } if(bInVal || bWaitingForVal) { throw CXMLException("Couldn't parse some tag attributes: <" + sTagContents + ">", 0); } }
//---------------------------------------- CDefaultRecord* CAliasesDictionary::CreateDefaultRecord(CXmlNode* defaultRecordNode) { if (defaultRecordNode == NULL) { return NULL; } CDefaultRecord* defaultRecord = new CDefaultRecord(); std::string value; bool bOk = defaultRecordNode->GetPropVal(CAliasesDictionary::m_NAME_ATTR, &value); if (!bOk) { std::string msg = CTools::Format("Unable to create default record - Default record name is empty - " "Please check all '%s' attributes of the '%s' elements in the aliases dictionary '%s'.", CAliasesDictionary::m_NAME_ATTR.c_str(), CAliasesDictionary::m_DEFAULT_RECORD_ELT.c_str(), m_fullFileName.c_str()); delete defaultRecord; defaultRecord = NULL; throw CXMLException(msg, BRATHL_ERROR); } defaultRecord->SetName(value); CObArray arrayNodes(false); FindAllNodesByName(CAliasesDictionary::m_PRODUCT_TYPE_ELT, defaultRecordNode, arrayNodes, false); CObArray::const_iterator it; for(it = arrayNodes.begin() ; it != arrayNodes.end() ; it++) { CXmlNode* node = dynamic_cast<CXmlNode*>(*it); if (node == NULL) { continue; } CXmlNode* textNode = node->GetChildren(); if (textNode == NULL) { continue; } std::string productType = textNode->GetContent().c_str(); if (productType.empty()) { continue; } defaultRecord->AddProductType(productType); } return defaultRecord; }
//---------------------------------------- CAliases* CAliasesDictionary::ResolveRef(const CAliases* aliases, const CObArray* aliasesArray) { if (aliases == NULL) { return NULL; } if (!aliases->HasRef()) { return NULL; } if (aliasesArray == NULL) { return NULL; } std::string productType = aliases->GetProductType(); std::string ref = aliases->GetRef(); if ((!productType.empty()) && (!ref.empty()) && (productType.compare(ref) == 0)) { std::string msg = CTools::Format("Unable to load the aliases dictionary because the '%s' and '%s' attributes of the '%s' element have the same value (reference to itself). " "Please check the XML aliases dictionary and fix the error.", CAliasesDictionary::m_PRODUCT_TYPE_ATTR.c_str(), CAliasesDictionary::m_REF_ATTR.c_str(), CAliasesDictionary::m_ALIASES_ELT.c_str()); throw CXMLException(msg, BRATHL_ERROR); } CAliases* refAliases = NULL; bool found = false; CObArray::const_iterator it; for (it = aliasesArray->begin() ; it != aliasesArray->end() ; it++) { refAliases = dynamic_cast<CAliases*>(*it); if (refAliases == NULL) { continue; } std::string productType = refAliases->GetProductType(); if (productType.compare(ref) == 0) { found = true; break; } } if (!found) { refAliases = NULL; return refAliases; } return refAliases; }
const XMLName* XMLNamePool::Insert(const XMLString& namespaceURI, const XMLString& localName, const XMLString& qname) { register unsigned long i = 0; register unsigned long n = Hash(namespaceURI, localName, qname) % m_size; while (m_pPool[n].m_used && (m_pPool[n].m_namespaceURI != namespaceURI || m_pPool[n].m_localName != localName || m_pPool[n].m_qname != qname) && i++ < m_size) n = (n + 1) % m_size; if (!m_pPool[n].m_used) { m_pPool[n].m_namespaceURI = namespaceURI; m_pPool[n].m_localName = localName; m_pPool[n].m_qname = qname; m_pPool[n].m_used = true; } else if (i > m_size) throw CXMLException(CXMLException::EXMLNamePoolFull); return &m_pPool[n]; }
//---------------------------------------------------- void CAliasesDictionary::Load(const std::string& fileName, const std::string& encoding, int flags) { try { DeleteRootNode(); CXmlDocument::Load(fileName, encoding, flags); } catch(CXMLParseException& e) { std::string msg = CTools::Format("Unable to load the aliases dictionary file '%s' - Parsing errors found - Native error: '%s'", fileName.c_str(), e.Message().c_str()); DeleteRootNode(); throw CXMLParseException(msg, e.error()); } catch(CXMLException& e) { std::string msg = CTools::Format("Unable to load the aliases dictionary file '%s' - Native error: '%s'", fileName.c_str(), e.Message().c_str()); DeleteRootNode(); throw CXMLException(msg, e.error()); } catch(CException& e) { DeleteRootNode(); throw e; } catch(std::exception& e) { DeleteRootNode(); throw e; } catch(...) { throw CException("Unexpected error while loading the aliases dictionary - No Context and no message have been set for this error", BRATHL_ERROR); } }
PXMLTag CXMLParser::ParseFile(const std::wstring& a_filePath) { std::string l_buf; FILE *fFile = NULL; if(_wfopen_s(&fFile, a_filePath.c_str(), L"r") != 0) { throw CXMLException("Unable to open file.", 0); } while(!feof(fFile)) { char szBuf[4096] = {0}; size_t l_read = fread_s(szBuf, 4096, sizeof(char), 4096, fFile); l_buf.append(szBuf, l_read); } fclose(fFile); return ParseString(l_buf); }
//---------------------------------------------------- void CAliasesDictionary::GetAliases(CXmlNode* parent, CObArray& arrayAliases) { if (parent == NULL) { throw CXMLException("Error in CAliasesDictionary::arrayAliases - Unable to get node because parent argument is NULL", BRATHL_LOGIC_ERROR); } CObArray arrayNodes(false); FindAllNodesByName(CAliasesDictionary::m_ALIASES_ELT, parent, arrayNodes, true); CObArray::const_iterator it; for(it = arrayNodes.begin() ; it != arrayNodes.end() ; it++) { CXmlNode* node = dynamic_cast<CXmlNode*>(*it); CAliases* aliases = CreateAliases(node); if (aliases != NULL) { arrayAliases.Insert(aliases); } } }
//---------------------------------------------------- void CAliasesDictionary::GetDefaultRecords(CXmlNode* parent, CObArray& arrayDefaultRecord) { if (parent == NULL) { throw CXMLException("Error in CAliasesDictionary::GetDefaultRecordNodes - Unable to get node because parent argument is NULL", BRATHL_LOGIC_ERROR); } CObArray arrayNodes(false); FindAllNodesByName(CAliasesDictionary::m_DEFAULT_RECORD_ELT, parent, arrayNodes, true); CObArray::const_iterator it; for(it = arrayNodes.begin() ; it != arrayNodes.end() ; it++) { CXmlNode* node = dynamic_cast<CXmlNode*>(*it); CDefaultRecord* defaultRecord = CreateDefaultRecord(node); if (defaultRecord != NULL) { arrayDefaultRecord.Insert(defaultRecord); } } }
PXMLTag CXMLParser::ParseString(const std::string& sXmlString) { std::stack<PXMLTag> m_openTags; std::stack<PXMLTag> m_openTagParent; PXMLTag xParent, xRoot; bool bEnding = false; std::string::size_type pos = sXmlString.find("<"); std::string::size_type iTextStartPos = std::string::npos; unsigned int iIteration = 0, iTextStartPosIteration = 0; while(pos != std::string::npos) { if(bEnding) { throw CXMLException("Multiple root tags?", pos); } iIteration++; std::string::size_type tagendpos = sXmlString.find(">", pos + 1); if(tagendpos == std::string::npos) { throw CXMLException("No terminating > for open <", pos); } if(tagendpos == pos + 1) { throw CXMLException("Empty tag", pos); } std::string sTagContents = sXmlString.substr(pos + 1, tagendpos - pos - 1); sTagContents = CUtil::StrReplace("\r", "", sTagContents); sTagContents = CUtil::StrReplace("\n", "", sTagContents); CUtil::StrTrim(sTagContents); std::string::size_type posTagName = sTagContents.find(' '); if(posTagName == std::string::npos) posTagName = sTagContents.size(); std::string sTagName = sTagContents.substr(0, posTagName); if(sTagName.substr(0, 3) == "!--") { // skip comments. tagendpos = sXmlString.find("-->", pos) + 2; if(tagendpos == std::string::npos) { throw CXMLException("Unterminated comment", pos); } } else if(sTagName[0] == '?') { // skip <?xml stuff without any further checks. } else if(sTagName.substr(0, 8) == "![CDATA[") { std::string::size_type posCDataEnd = sXmlString.find("]]>", pos); if(posCDataEnd == std::string::npos) { throw CXMLException("Unterminated CDATA section", pos); } else if(m_openTags.empty()) { throw CXMLException("CDATA section outside of a tag", pos); } PXMLTag xOpenTag = m_openTags.top(); xOpenTag->m_text = sXmlString.substr(pos + 1 + 8, posCDataEnd - pos - 9); CUtil::StrTrim(xOpenTag->m_text); tagendpos = posCDataEnd + 2; } else if(sTagName[0] != '/') { // found start tag PXMLTag xNew(new CXMLTag()); xNew->m_name = sTagName; ParseAttributes(sTagContents, xNew->m_attributes); // look out for <img /> style tags: if(sTagContents[sTagContents.size() - 1] != '/') { m_openTags.push(xNew); if(xParent) m_openTagParent.push(xParent); xParent = xNew; // save the position in case this tag has no child tags // and we want to extract text from it. iTextStartPos = tagendpos + 1; iTextStartPosIteration = iIteration; } else if(xParent) { xParent->m_children.push_back(xNew); } else { xRoot = xNew; } } else { // found end tag sTagName.erase(0, 1); if(m_openTags.size() == 0 || _stricmp(m_openTags.top()->m_name.c_str(), sTagName.c_str()) != 0) { throw CXMLException("Ending tag for '" + std::string(sTagName) + "', which is not open", pos); } // take the now-closed tag off the stack: PXMLTag xClosedTag = m_openTags.top(); m_openTags.pop(); // if no other tags have been found in between, extract text: if(iIteration == iTextStartPosIteration + 1) { xClosedTag->m_text = sXmlString.substr(iTextStartPos, pos - iTextStartPos); xClosedTag->m_text = XmlDecode(xClosedTag->m_text); } // no parent = root tag. if this happens, we've walked the tree and are done. if(m_openTagParent.empty()) { xRoot = xClosedTag; bEnding = true; } else { // re-set old parent: xParent = m_openTagParent.top(); m_openTagParent.pop(); // otherwise, save the new child and to the next tag... xParent->m_children.push_back(xClosedTag); } } pos = sXmlString.find("<", tagendpos + 1); } if(m_openTags.size() != 0) { throw CXMLException("Found unclosed tags", 0); } return xRoot; }
//---------------------------------------- CAlias* CAliasesDictionary::CreateAlias(CXmlNode* aliasNode) { if (aliasNode == NULL) { return NULL; } CAlias* alias = new CAlias(); std::string value; bool bOk = aliasNode->GetPropVal(CAliasesDictionary::m_NAME_ATTR, &value); if (!bOk) { std::string msg = CTools::Format("Unable to create alias - Alias name is empty - " "Please check all '%s' attributes of the '%s' elements in the aliases dictionary '%s'.", CAliasesDictionary::m_NAME_ATTR.c_str(), CAliasesDictionary::m_ALIAS_ELT.c_str(), m_fullFileName.c_str()); delete alias; alias = NULL; throw CXMLException(msg, BRATHL_ERROR); } alias->SetName(value); value.clear(); bOk = aliasNode->GetPropVal(CAliasesDictionary::m_REF_ATTR, &value); alias->SetRef(value); bOk = aliasNode->GetPropVal(CAliasesDictionary::m_DESCR_ATTR, &value); alias->SetDescription(value); CXmlNode* textNode = aliasNode->GetChildren(); std::string aliasValue; if (textNode != NULL) { aliasValue = textNode->GetContent().c_str(); } if ((aliasValue.empty()) && (!alias->IsSynonym())) { std::string msg = CTools::Format("Unable to create alias '%s' - Alias value is empty and alias ref. attribute is empty. " "One of two values has to be filled (but not both of them)." "Please check all '%s' attributes of the '%s' elements in the aliases dictionary '%s'.", alias->GetName().c_str(), CAliasesDictionary::m_NAME_ATTR.c_str(), CAliasesDictionary::m_ALIAS_ELT.c_str(), m_fullFileName.c_str()); delete alias; alias = NULL; throw CXMLException(msg, BRATHL_ERROR); } if ((!aliasValue.empty()) && (alias->IsSynonym())) { std::string msg = CTools::Format("Unable to create alias '%s' - Alias value is not empty ('%s') and alias ref. attribute is not empty ('%s'). " "Only one of two values has to be filled, not both of them." "Please check all '%s' attributes of the '%s' elements in the aliases dictionary '%s'.", alias->GetName().c_str(), aliasValue.c_str(), alias->GetRef().c_str(), CAliasesDictionary::m_NAME_ATTR.c_str(), CAliasesDictionary::m_ALIAS_ELT.c_str(), m_fullFileName.c_str()); delete alias; alias = NULL; throw CXMLException(msg, BRATHL_ERROR); } if (alias->IsSynonym()) { CXmlNode* aliasRefNode = FindAliasNode(alias->GetRef(), aliasNode->GetParent()); if (aliasRefNode == NULL) { std::string msg = CTools::Format("Unable to create alias '%s' - Alias is as synonym, but the referenced alias ('%s') is not found. " "Please check all '%s' attributes of the '%s' elements in the aliases dictionary '%s'.", alias->GetName().c_str(), alias->GetRef().c_str(), CAliasesDictionary::m_NAME_ATTR.c_str(), CAliasesDictionary::m_ALIAS_ELT.c_str(), m_fullFileName.c_str()); delete alias; alias = NULL; throw CXMLException(msg, BRATHL_ERROR); } alias->SetDescription(CTools::Format("%s (Synonym of %s).", alias->GetDescription().c_str(), alias->GetRef().c_str())); textNode = aliasRefNode->GetChildren(); if (textNode == NULL) { std::string msg = CTools::Format("Unable to create alias '%s' - Alias is as synonym, but the referenced alias ('%s') value is empty. " "Please check all '%s' attributes of the '%s' elements in the aliases dictionary '%s'.", alias->GetName().c_str(), alias->GetRef().c_str(), CAliasesDictionary::m_NAME_ATTR.c_str(), CAliasesDictionary::m_ALIAS_ELT.c_str(), m_fullFileName.c_str()); delete alias; alias = NULL; throw CXMLException(msg, BRATHL_ERROR); } aliasValue = textNode->GetContent().c_str(); } alias->SetValue(aliasValue); return alias; }
int CSAX2ParserBase::HandleExternalEntityRef(const XML_Char* context, const XML_Char* base, const XML_Char* systemId, const XML_Char* publicId) { csl_assert (systemId != NULL); if (context == NULL && !m_includeExtParEntities) return 0; if (context != NULL && !m_includeExtGenEntities) return 0; CInputSource* pInputSource = NULL; XMLString resolvedSystemId; if (base) resolvedSystemId = ResolveSystemId(base, systemId); else resolvedSystemId = systemId; CEntityResolver* pEntityResolver = NULL; CEntityResolverImp defaultResolver; XMLString pId; if (publicId) pId = XMLString(publicId); if (m_pEntityResolver) { pInputSource = m_pEntityResolver->ResolveEntity(publicId ? &pId : NULL, resolvedSystemId); pEntityResolver = m_pEntityResolver; } if (!pInputSource && m_includeExtGenEntities) { pInputSource = defaultResolver.ResolveEntity(publicId ? &pId : NULL, resolvedSystemId); pEntityResolver = &defaultResolver; } if (pInputSource) { XML_Parser extParser = XML_ExternalEntityParserCreate(GetExpatParser(), context, 0); XML_SetBase(extParser, resolvedSystemId.c_str()); try { if (pInputSource->GetCharacterStream()) { ParseCharExternal(extParser, pInputSource->GetCharacterStream()); } else if (pInputSource->GetByteStream()) { ParseExternal(extParser, pInputSource->GetByteStream()); } else { throw CSAXParseException("no input stream", EMPTY_STRING, pInputSource->GetSystemId(), 0, 0, CXMLException(CXMLException::EXMLBadInputSource, string())); } } catch (CXMLException& e) { // cleanup before we propagate the exception pEntityResolver->DoneWithInputSource(pInputSource); XML_ParserFree(extParser); throw e; } pEntityResolver->DoneWithInputSource(pInputSource); XML_ParserFree(extParser); return 1; } else { return 0; } }
CSAXNotSupportedException::CSAXNotSupportedException(const string& msg): CSAXException(CXMLException(CXMLException::ESAXNotSupportedException, msg)) { }
CSAXNotRecognizedException::CSAXNotRecognizedException(const string& msg): CSAXException(CXMLException(CXMLException::ESAXNotRecognizedException, msg)) { }