void XMLParserJSON::ParseLevel(XMLElement* p_element,JSONvalue& p_value,CString p_arrayName /*=""*/) { JSONobject* object = nullptr; JSONarray* array = nullptr; XMLElement* element = nullptr; CString arrayName; CString value; switch(p_value.GetDataType()) { case JsonType::JDT_object: object = &p_value.GetObject(); for(auto& pair : *object) { if(pair.m_value.GetDataType() == JsonType::JDT_array) { ParseLevel(p_element,pair.m_value,pair.m_name); } else { element = m_soap->AddElement(p_element,pair.m_name,XDT_String,""); ParseLevel(element,pair.m_value); } } break; case JsonType::JDT_array: array = &p_value.GetArray(); for(auto& val : *array) { element = m_soap->AddElement(p_element,p_arrayName,XDT_String,""); ParseLevel(element,val); } break; case JsonType::JDT_string: p_element->SetValue(p_value.GetString()); break; case JsonType::JDT_number_int: value.Format("%d",p_value.GetNumberInt()); p_element->SetValue(value); break; case JsonType::JDT_number_dbl: value.Format("%.15g",p_value.GetNumberDbl()); p_element->SetValue(value); break; case JsonType::JDT_const: switch(p_value.GetConstant()) { case JsonConst::JSON_NONE: break; // Do nothing: empty string!! case JsonConst::JSON_NULL: p_element->SetValue(""); break; case JsonConst::JSON_FALSE: p_element->SetValue("false"); break; case JsonConst::JSON_TRUE: p_element->SetValue("true"); break; } break; } }
void XMLParserJSON::ParseMain(XMLElement* p_element,JSONvalue& p_value) { // finding the main node in the JSON if(p_value.GetDataType() != JsonType::JDT_object) { return; } JSONpair& pair = p_value.GetObject()[0]; JSONvalue& value = pair.m_value; // Detect the SOAP Envelope if(pair.m_name == "Envelope") { if(value.GetDataType() != JsonType::JDT_object) { return; } pair = value.GetObject()[0]; value = pair.m_value; } // Detect the SOAP Body if(pair.m_name == "Body") { if(value.GetDataType() != JsonType::JDT_object) { return; } pair = value.GetObject()[0]; value = pair.m_value; } // Remember the action name m_soap->SetParameterObject(pair.m_name); m_soap->SetSoapAction(pair.m_name); // Parse the message ParseLevel(p_element,value); }
void sv::ObstacleManager::Start() { Pool<Obstacle>::Init(80); ParseLevel(); }
// Parse element node // Returns true if parsing level complete bool XMLParser::ParseElement() { CString elementName; CString attributeName; WhiteSpace elemspace = m_whiteSpace; // Skip leading '<' m_pointer++; if(GetIdentifier(elementName)) { // Creating an identifier CString namesp = SplitNamespace(elementName); MakeElement(namesp,elementName); if(isspace(*m_pointer)) { SkipWhiteSpace(); // See if we must get attributes while(GetIdentifier(attributeName)) { SkipWhiteSpace(); NeedToken('='); CString value = GetQuotedString(); SkipWhiteSpace(); // Adding an attribute m_message->SetAttribute(m_lastElement,attributeName,value); // In special case "[xml:]space", we must change whitespace preserving if(attributeName.Compare("space") == 0) { elemspace = value.Compare("preserve") == 0 ? WhiteSpace::PRESERVE_WHITESPACE : WhiteSpace::COLLAPSE_WHITESPACE; } } } if(*m_pointer && strncmp((const char*)m_pointer,"/>",2) == 0) { m_pointer += 2; return false; } if(*m_pointer == '>') { // Closing of the element m_pointer++; SkipOuterWhiteSpace(); if(*m_pointer && *m_pointer == '<') { // Push element and space-preserving and parse next level XMLElement* level = m_element; WhiteSpace space = m_whiteSpace; m_whiteSpace = elemspace; m_element = m_lastElement; ParseLevel(); m_element = level; m_whiteSpace = space; } else { ParseText(); } } // Need to see ending of the element CString closing; NeedToken('<'); NeedToken('/'); if(GetIdentifier(closing)) { CString closingNS = SplitNamespace(closing); if(elementName.Compare(closing) == 0) { if(namesp.Compare(closingNS)) { CString error; error.Format("Element [%s] has closing tag with different namespace.",elementName.GetString()); SetError(XmlError::XE_MissingEndTag,(uchar*)error.GetString()); } NeedToken('>'); SkipOuterWhiteSpace(); // Parsing level complete return strncmp((const char*)m_pointer,"</",2) == 0; } CString error; error.Format("Element [%s] has incorrect closing tag [%s]",elementName.GetString(),closing.GetString()); SetError(XmlError::XE_MissingEndTag,(uchar*)error.GetString()); } else { CString error; error.Format("Missing end tag for element: %s",elementName.GetString()); SetError(XmlError::XE_MissingEndTag,(uchar*)error.GetString()); } } // End of a list of elements if(*m_pointer == '/') { m_pointer--; return true; } CString error; error.Format("Missing ending of XML element: %s",elementName.GetString()); SetError(XmlError::XE_MissingElement,(uchar*)error.GetString()); return false; }
void XMLParser::ParseMessage(CString& p_message,WhiteSpace p_whiteSpace /*=PRESERVE_WHITESPACE*/) { // Remember parsing mode m_whiteSpace = p_whiteSpace; // Check if we have something to do if(m_message == nullptr || p_message.IsEmpty()) { SetError(XmlError::XE_EmptyXML,(uchar*)"Empty message",false); return; } // Initialize the parsing pointer m_pointer = (uchar*) p_message.GetString(); // Check for Byte-Order-Mark first BOMType bomType = BOMType::BT_NO_BOM; unsigned int skip = 0; BOMOpenResult bomResult = CheckForBOM(m_pointer,bomType,skip); if(bomResult != BOMOpenResult::BOR_NoBom) { if(bomType != BOMType::BT_BE_UTF8) { // cannot process these strings SetError(XmlError::XE_IncompatibleEncoding,(uchar*)"Incompatible Byte-Order-Mark encoding",false); return; } m_message->m_encoding = XMLEncoding::ENC_UTF8; m_message->m_sendBOM = true; m_utf8 = true; // Skip past BOM m_pointer += skip; } // MAIN PARSING LOOP try { // Parse an XML level ParseLevel(); // Checks after parsing if(m_message->m_root->GetName().IsEmpty()) { // Minimum requirement of an XML message SetError(XmlError::XE_NoRootElement,(uchar*)"Missing root element of XML message"); } if(*m_pointer) { SetError(XmlError::XE_ExtraText,m_pointer); } } catch(XmlError& error) { // Error message text already set m_message->m_internalError = error; } // Conclusion of condensed level m_message->SetCondensed(m_spaces < m_elements); }