bool XmlSchema::generateCodeForNode(const XmlNode* node, String& headerCode, String& sourceCode) const { assert(node != NULL); if (node->getType() == ELEMENT) { String structDefinition; structDefinition += T("///////////////////////////////////////////////////////////////////////////////////////////////////\r\n"); structDefinition += T("struct "); structDefinition += node->getName(); structDefinition += T("\r\n{\r\n"); //constructor int index = 0; NodeIterator iter; for (XmlNode* child = node->getFirstChild(iter); child != NULL; child = node->getNextChild(iter)) { if (child->isEmpty() && child->getType() == ELEMENT) { //simple type addConstructorItem(child, structDefinition, index); } } if (index > 0) { structDefinition += T(" {\r\n }\r\n"); } //destructor for (XmlNode* child = node->getFirstChild(iter); child != NULL; child = node->getNextChild(iter)) { if (child->findAttribute(ATTR_RECURSIVE) != NULL && child->findAttribute(ATTR_MULTIPLE) == NULL) { //recursive pointer, need to delete structDefinition += T(" ~"); structDefinition += node->getName(); structDefinition += T("()\r\n {\r\n if (Child != NULL)\r\n {\r\n delete Child;\r\n"); structDefinition += T(" Child = NULL;\r\n }\r\n }\r\n"); break; //can't have more than one } } structDefinition += T(" void read(const slim::XmlNode* node);\r\n void write(slim::XmlNode* node) const;\r\n\r\n"); String readingCode; readingCode += T("///////////////////////////////////////////////////////////////////////////////////////////////////\r\n"); readingCode += T("void "); readingCode += node->getName(); readingCode += T("::read(const XmlNode* node)\r\n{\r\n assert(node != NULL);\r\n"); readingCode += T("\r\n NodeIterator iter;\r\n const XmlNode* childNode = NULL;\r\n const XmlAttribute* attribute = NULL;\r\n"); String writingCode; writingCode += T("///////////////////////////////////////////////////////////////////////////////////////////////////\r\n"); writingCode += T("void "); writingCode += node->getName(); writingCode += T("::write(XmlNode* node) const\r\n{\r\n assert(node != NULL);\r\n\r\n node->clearChild();\r\n node->clearAttribute();"); writingCode += T("\r\n\r\n XmlNode* childNode = NULL;\r\n XmlAttribute* attribute = NULL;\r\n"); size_t typeWidth = getNodeMemberTypeWidth(node); for (const XmlNode* child = node->getFirstChild(iter); child != NULL; child = node->getNextChild(iter)) { if (child->getType() != ELEMENT) { continue; } XmlAttribute* multiple = child->findAttribute(ATTR_MULTIPLE); bool recursive = (child->findAttribute(ATTR_RECURSIVE) != NULL); if (child->isEmpty() && !recursive) { //simple type if (multiple != NULL && multiple->getBool()) { addSimpleVector(child, structDefinition, typeWidth, readingCode, writingCode); } else { addSimpleMember(child, structDefinition, typeWidth, readingCode, writingCode); } } else { //struct type if (multiple != NULL && multiple->getBool()) { addStructVector(child, structDefinition, typeWidth, readingCode, writingCode); } else { addStructMember(child, structDefinition, typeWidth, readingCode, writingCode); } } } structDefinition += T("};\r\n\r\n"); readingCode += T("}\r\n\r\n"); writingCode += T("}\r\n\r\n"); sourceCode += readingCode; sourceCode += writingCode; //add to front headerCode = structDefinition + headerCode; } NodeIterator iter; for (const XmlNode* child = node->getFirstChild(iter); child != NULL; child = node->getNextChild(iter)) { if (child->hasChild()) { if (!generateCodeForNode(child, headerCode, sourceCode)) { return false; } } } return true; }
/////////////////////////////////////////////////////////////////////////////////////////////////// //parse data schema from node //src data node //dst schema node bool XmlSchema::parseNodeStruct(XmlNode* dst, XmlNode* src) { assert(dst != NULL); assert(src != NULL); NodeIterator nodeIterator; AttributeIterator attriIterator; for (XmlAttribute* attribute = src->getFirstAttribute(attriIterator); attribute != NULL; attribute = src->getNextAttribute(attriIterator)) { XmlNode* structure = dst->findChild(attribute->getName()); if (structure == NULL) { //first time show up structure = dst->addChild(attribute->getName()); structure->addAttribute(ATTR_TYPE, guessType(attribute->getString())); structure->addAttribute(ATTR_ATTRIBUTE, T("true")); } } for (XmlNode* child = src->getFirstChild(nodeIterator); child != NULL; child = src->getNextChild(nodeIterator)) { if (child->getType() != ELEMENT) { continue; } XmlNode* structure = dst->findChild(child->getName()); if (structure == NULL) { //first time show up bool recursive = false; const XmlNode* parent = dst; while (parent != NULL) { if (Strcmp(parent->getName(), child->getName()) == 0) { recursive = true; break; } parent = parent->getParent(); } structure = dst->addChild(child->getName()); if (recursive) { structure->addAttribute(ATTR_RECURSIVE, T("true")); } else if (!child->hasChild() && !child->hasAttribute()) { //simple type, must have a type attribute structure->addAttribute(ATTR_TYPE, guessType(child->getString())); } } else if (structure->findAttribute(ATTR_ATTRIBUTE) != NULL) { //child and attribute can't have same name return false; } XmlAttribute* multiple = structure->findAttribute(ATTR_MULTIPLE); if (multiple == NULL || !multiple->getBool()) { NodeIterator iter; if (src->findFirstChild(child->getName(), iter) != NULL && src->findNextChild(child->getName(), iter) != NULL) { if (multiple == NULL) { multiple = structure->addAttribute(ATTR_MULTIPLE); } multiple->setBool(true); } } if (!structure->findAttribute(ATTR_RECURSIVE) && (child->hasChild() || child->hasAttribute())) { parseNodeStruct(structure, child); } } return true; }