bool XmlWorldReader::Read(const std::string &file) { // ワールドを初期化 try { initialize(); if (initFlag) { initializeWorld(); } } catch (...) { return false; } // TODO: ファイルの有無を確認 // XMLファイルをパース const XMLCh gLS[] = {chLatin_L, chLatin_S, chNull}; DOMImplementationLS *impl = DOMImplementationRegistry::getDOMImplementation(gLS); DOMLSParser *parser = impl->createLSParser( DOMImplementationLS::MODE_SYNCHRONOUS, NULL ); DOMDocument *doc = parser->parseURI(file.c_str()); if (doc == nullptr) { return false; } // rootノードを取得 DOMElement *worldElement = doc->getDocumentElement(); if (worldElement == nullptr) { parser->release(); return false; } { YPT::XmlString temp("world"); bool res = XMLString::equals(worldElement->getNodeName(), temp); if (!res) { parser->release(); return false; } } // ロード用クラス作成 YPT::XmlWorldPartReader partReader(doc); // XPathコンテキスト作成 DOMXPathNSResolver *resolver = doc->createNSResolver(worldElement); if (resolver == nullptr) { parser->release(); return false; } YPT::XmlString str, str2; DOMXPathResult *result; // -------------------------------------------------- // ワールド全体の設定 // -------------------------------------------------- // ワールド名 str = worldElement->getAttribute(YPT::XmlString("name")); if (str != "") { name = str; } // 重力ベクトル result = doc->evaluate( YPT::XmlString("./gravity"), worldElement, resolver, DOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE, NULL ); if (result != nullptr) { if (result->getSnapshotLength() >= 1) { str = result->getNodeValue()->getTextContent(); b2Vec2 temp; if (!YPT::ConvertStrToVec2(str.ToChar(), &temp)) { world.SetGravity(temp); } } result->release(); } // -------------------------------------------------- // shapes // -------------------------------------------------- result = doc->evaluate( YPT::XmlString("./shape"), worldElement, resolver, DOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE, NULL ); if (result != nullptr) { const XMLSize_t len = result->getSnapshotLength(); for (XMLSize_t i = 0; i < len; ++i) { result->snapshotItem(i); DOMNode *node = result->getNodeValue(); if (node == nullptr) { continue; } DOMNamedNodeMap *nodeMap = node->getAttributes(); if (nodeMap == nullptr) { continue; } DOMNode *typeNode = nodeMap->getNamedItem(YPT::XmlString("type")); if (typeNode == nullptr) { continue; } str = typeNode->getNodeValue(); b2Shape::Type type; int index; if (str == "circle") { type = b2Shape::e_circle; b2CircleShape temp; if (partReader.ReadCircleShape(node, &temp)) { circleShapes.push_back(temp); index = circleShapes.size()-1; } else { // 読み込み失敗 continue; } } else if (str == "edge") { type = b2Shape::e_edge; b2EdgeShape temp; if (partReader.ReadEdgeShape(node, &temp)) { edgeShapes.push_back(temp); index = edgeShapes.size()-1; } else { // 読み込み失敗 continue; } } else if (str == "polygon") { type = b2Shape::e_polygon; b2PolygonShape temp; if (partReader.ReadPolygonShape(node, &temp)) { polygonShapes.push_back(temp); index = polygonShapes.size()-1; } else { // 読み込み失敗 continue; } } else if (str == "chain") { type = b2Shape::e_chain; b2ChainShape temp; if (partReader.ReadChainShape(node, &temp)) { chainShapes.push_back(temp); index = chainShapes.size()-1; } else { // 読み込み失敗 continue; } } else { // 未対応 continue; } // nameプロパティがあれば保存 DOMNode *name = nodeMap->getNamedItem(YPT::XmlString("name")); if (name != nullptr) { str = name->getNodeValue(); shapes.insert(ShapesMap::value_type( std::string(str), std::make_pair(type, index) )); } } result->release(); } // -------------------------------------------------- // fixtures // -------------------------------------------------- result = doc->evaluate( YPT::XmlString("./fixture"), worldElement, resolver, DOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE, NULL ); if (result != nullptr) { const XMLSize_t len = result->getSnapshotLength(); for (XMLSize_t i = 0; i < len; ++i) { result->snapshotItem(i); DOMNode *node = result->getNodeValue(); if (node == nullptr) { continue; } DOMXPathResult *result2 = doc->evaluate( YPT::XmlString("./shape"), node, resolver, DOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE, NULL ); if (result2 == nullptr) { continue; } DOMNode *shapeNode = result2->getNodeValue(); if (shapeNode == nullptr) { continue; } str = shapeNode->getTextContent(); result2->release(); ShapesMap::iterator found = shapes.find(std::string(str)); if (found == shapes.end()) { continue; } // fixture読み込み b2FixtureDef fixtureDef; b2Shape *shape = NULL; int index = found->second.second; switch (found->second.first) { case b2Shape::e_circle: shape = &circleShapes[index]; break; case b2Shape::e_edge: shape = &edgeShapes[index]; break; case b2Shape::e_polygon: shape = &polygonShapes[index]; break; case b2Shape::e_chain: shape = &chainShapes[index]; break; default: // 未対応 break; } if (shape == NULL) { continue; } if (partReader.ReadFixture(node, shape, &fixtureDef)) { // 読み込み成功 // nameプロパティがあれば保存する DOMNamedNodeMap *nodeMap = node->getAttributes(); if (nodeMap == nullptr) { continue; } DOMNode *nameNode = nodeMap->getNamedItem(YPT::XmlString("name")); if (nameNode == nullptr) { continue; } str = nameNode->getNodeValue(); fixtures.insert(FixturesMap::value_type( std::string(str), fixtureDef )); } } result->release(); } // -------------------------------------------------- // bodies // -------------------------------------------------- result = doc->evaluate( YPT::XmlString("./body"), worldElement, resolver, DOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE, NULL ); if (result != nullptr) { const XMLSize_t len = result->getSnapshotLength(); for (XMLSize_t i = 0; i < len; ++i) { result->snapshotItem(i); DOMNode *node = result->getNodeValue(); if (node == nullptr) { continue; } DOMXPathResult *result2 = doc->evaluate( YPT::XmlString("./fixtures/fixture"), node, resolver, DOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE, NULL ); if (result2 == nullptr) { continue; } std::vector< b2FixtureDef *> fixtureDefs; const XMLSize_t fixturesLen = result2->getSnapshotLength(); for (XMLSize_t j = 0; j < fixturesLen; ++j) { result2->snapshotItem(j); DOMNode *fixtureNode = result2->getNodeValue(); if (fixtureNode == nullptr) { continue; } str = fixtureNode->getTextContent(); FixturesMap::iterator found = fixtures.find( std::string(str) ); if (found != fixtures.end()) { fixtureDefs.push_back(&found->second); } } result2->release(); b2Body *body = partReader.ReadBody(world, node, fixtureDefs); if (body != nullptr) { // 読み込み成功 // nameプロパティがあれば保存する DOMNamedNodeMap *nodeMap = node->getAttributes(); if (nodeMap == nullptr) { continue; } DOMNode *nameNode = nodeMap->getNamedItem(YPT::XmlString("name")); if (nameNode == nullptr) { continue; } str = nameNode->getNodeValue(); bodies.insert(BodiesMap::value_type( std::string(str), body )); } } result->release(); } // -------------------------------------------------- // 読み込み完了 // -------------------------------------------------- resolver->release(); parser->release(); return true; }
// --------------------------------------------------------------------------- // // main // // --------------------------------------------------------------------------- int main(int argC, char* argV[]) { int retval = 0; // Initialize the XML4C2 system try { XMLPlatformUtils::Initialize(); } catch(const XMLException &toCatch) { XERCES_STD_QUALIFIER cerr << "Error during Xerces-c Initialization.\n" << " Exception message:" << StrX(toCatch.getMessage()) << XERCES_STD_QUALIFIER endl; return 1; } // Check command line and extract arguments. if (argC < 2) { usage(); XMLPlatformUtils::Terminate(); return 1; } // See if non validating dom parser configuration is requested. int parmInd; for (parmInd = 1; parmInd < argC; parmInd++) { // Break out on first parm not starting with a dash if (argV[parmInd][0] != '-') break; // Watch for special case help request if (!strcmp(argV[parmInd], "-?")) { usage(); XMLPlatformUtils::Terminate(); return 2; } else if (!strncmp(argV[parmInd], "-v=", 3) || !strncmp(argV[parmInd], "-V=", 3)) { const char* const parm = &argV[parmInd][3]; if (!strcmp(parm, "never")) gValScheme = XercesDOMParser::Val_Never; else if (!strcmp(parm, "auto")) gValScheme = XercesDOMParser::Val_Auto; else if (!strcmp(parm, "always")) gValScheme = XercesDOMParser::Val_Always; else { XERCES_STD_QUALIFIER cerr << "Unknown -v= value: " << parm << XERCES_STD_QUALIFIER endl; XMLPlatformUtils::Terminate(); return 2; } } else if (!strcmp(argV[parmInd], "-n") || !strcmp(argV[parmInd], "-N")) { gDoNamespaces = true; } else if (!strcmp(argV[parmInd], "-s") || !strcmp(argV[parmInd], "-S")) { gDoSchema = true; } else if (!strcmp(argV[parmInd], "-f") || !strcmp(argV[parmInd], "-F")) { gSchemaFullChecking = true; } else if (!strcmp(argV[parmInd], "-e") || !strcmp(argV[parmInd], "-E")) { gDoCreate = true; } else if (!strncmp(argV[parmInd], "-wenc=", 6)) { // Get out the encoding name gOutputEncoding = XMLString::transcode( &(argV[parmInd][6]) ); } else if (!strncmp(argV[parmInd], "-wfile=", 7)) { goutputfile = &(argV[parmInd][7]); } else if (!strncmp(argV[parmInd], "-wddc=", 6)) { const char* const parm = &argV[parmInd][6]; if (!strcmp(parm, "on")) gDiscardDefaultContent = true; else if (!strcmp(parm, "off")) gDiscardDefaultContent = false; else { XERCES_STD_QUALIFIER cerr << "Unknown -wddc= value: " << parm << XERCES_STD_QUALIFIER endl; XMLPlatformUtils::Terminate(); return 2; } } else if (!strncmp(argV[parmInd], "-wscs=", 6)) { const char* const parm = &argV[parmInd][6]; if (!strcmp(parm, "on")) gSplitCdataSections = true; else if (!strcmp(parm, "off")) gSplitCdataSections = false; else { XERCES_STD_QUALIFIER cerr << "Unknown -wscs= value: " << parm << XERCES_STD_QUALIFIER endl; XMLPlatformUtils::Terminate(); return 2; } } else if (!strncmp(argV[parmInd], "-wflt=", 6)) { const char* const parm = &argV[parmInd][6]; if (!strcmp(parm, "on")) gUseFilter = true; else if (!strcmp(parm, "off")) gUseFilter = false; else { XERCES_STD_QUALIFIER cerr << "Unknown -wflt= value: " << parm << XERCES_STD_QUALIFIER endl; XMLPlatformUtils::Terminate(); return 2; } } else if (!strncmp(argV[parmInd], "-wfpp=", 6)) { const char* const parm = &argV[parmInd][6]; if (!strcmp(parm, "on")) gFormatPrettyPrint = true; else if (!strcmp(parm, "off")) gFormatPrettyPrint = false; else { XERCES_STD_QUALIFIER cerr << "Unknown -wfpp= value: " << parm << XERCES_STD_QUALIFIER endl; XMLPlatformUtils::Terminate(); return 2; } } else if (!strncmp(argV[parmInd], "-wbom=", 6)) { const char* const parm = &argV[parmInd][6]; if (!strcmp(parm, "on")) gWriteBOM = true; else if (!strcmp(parm, "off")) gWriteBOM = false; else { XERCES_STD_QUALIFIER cerr << "Unknown -wbom= value: " << parm << XERCES_STD_QUALIFIER endl; XMLPlatformUtils::Terminate(); return 2; } } else if (!strncmp(argV[parmInd], "-xpath=", 7)) { gXPathExpression = &(argV[parmInd][7]); } else { XERCES_STD_QUALIFIER cerr << "Unknown option '" << argV[parmInd] << "', ignoring it.\n" << XERCES_STD_QUALIFIER endl; } } // // And now we have to have only one parameter left and it must be // the file name. // if (parmInd + 1 != argC) { usage(); XMLPlatformUtils::Terminate(); return 1; } gXmlFile = argV[parmInd]; // // Create our parser, then attach an error handler to the parser. // The parser will call back to methods of the ErrorHandler if it // discovers errors during the course of parsing the XML document. // XercesDOMParser *parser = new XercesDOMParser; parser->setValidationScheme(gValScheme); parser->setDoNamespaces(gDoNamespaces); parser->setDoSchema(gDoSchema); parser->setValidationSchemaFullChecking(gSchemaFullChecking); parser->setCreateEntityReferenceNodes(gDoCreate); DOMTreeErrorReporter *errReporter = new DOMTreeErrorReporter(); parser->setErrorHandler(errReporter); // // Parse the XML file, catching any XML exceptions that might propogate // out of it. // bool errorsOccured = false; try { parser->parse(gXmlFile); } catch (const OutOfMemoryException&) { XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl; errorsOccured = true; } catch (const XMLException& e) { XERCES_STD_QUALIFIER cerr << "An error occurred during parsing\n Message: " << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl; errorsOccured = true; } catch (const DOMException& e) { const unsigned int maxChars = 2047; XMLCh errText[maxChars + 1]; XERCES_STD_QUALIFIER cerr << "\nDOM Error during parsing: '" << gXmlFile << "'\n" << "DOMException code is: " << e.code << XERCES_STD_QUALIFIER endl; if (DOMImplementation::loadDOMExceptionMsg(e.code, errText, maxChars)) XERCES_STD_QUALIFIER cerr << "Message is: " << StrX(errText) << XERCES_STD_QUALIFIER endl; errorsOccured = true; } catch (...) { XERCES_STD_QUALIFIER cerr << "An error occurred during parsing\n " << XERCES_STD_QUALIFIER endl; errorsOccured = true; } // If the parse was successful, output the document data from the DOM tree if (!errorsOccured && !errReporter->getSawErrors()) { DOMPrintFilter *myFilter = 0; try { // get a serializer, an instance of DOMLSSerializer XMLCh tempStr[3] = {chLatin_L, chLatin_S, chNull}; DOMImplementation *impl = DOMImplementationRegistry::getDOMImplementation(tempStr); DOMLSSerializer *theSerializer = ((DOMImplementationLS*)impl)->createLSSerializer(); DOMLSOutput *theOutputDesc = ((DOMImplementationLS*)impl)->createLSOutput(); // set user specified output encoding theOutputDesc->setEncoding(gOutputEncoding); // plug in user's own filter if (gUseFilter) { // even we say to show attribute, but the DOMLSSerializer // will not show attribute nodes to the filter as // the specs explicitly says that DOMLSSerializer shall // NOT show attributes to DOMLSSerializerFilter. // // so DOMNodeFilter::SHOW_ATTRIBUTE has no effect. // same DOMNodeFilter::SHOW_DOCUMENT_TYPE, no effect. // myFilter = new DOMPrintFilter(DOMNodeFilter::SHOW_ELEMENT | DOMNodeFilter::SHOW_ATTRIBUTE | DOMNodeFilter::SHOW_DOCUMENT_TYPE); theSerializer->setFilter(myFilter); } // plug in user's own error handler DOMErrorHandler *myErrorHandler = new DOMPrintErrorHandler(); DOMConfiguration* serializerConfig=theSerializer->getDomConfig(); serializerConfig->setParameter(XMLUni::fgDOMErrorHandler, myErrorHandler); // set feature if the serializer supports the feature/mode if (serializerConfig->canSetParameter(XMLUni::fgDOMWRTSplitCdataSections, gSplitCdataSections)) serializerConfig->setParameter(XMLUni::fgDOMWRTSplitCdataSections, gSplitCdataSections); if (serializerConfig->canSetParameter(XMLUni::fgDOMWRTDiscardDefaultContent, gDiscardDefaultContent)) serializerConfig->setParameter(XMLUni::fgDOMWRTDiscardDefaultContent, gDiscardDefaultContent); if (serializerConfig->canSetParameter(XMLUni::fgDOMWRTFormatPrettyPrint, gFormatPrettyPrint)) serializerConfig->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, gFormatPrettyPrint); if (serializerConfig->canSetParameter(XMLUni::fgDOMWRTBOM, gWriteBOM)) serializerConfig->setParameter(XMLUni::fgDOMWRTBOM, gWriteBOM); // // Plug in a format target to receive the resultant // XML stream from the serializer. // // StdOutFormatTarget prints the resultant XML stream // to stdout once it receives any thing from the serializer. // XMLFormatTarget *myFormTarget; if (goutputfile) myFormTarget=new LocalFileFormatTarget(goutputfile); else myFormTarget=new StdOutFormatTarget(); theOutputDesc->setByteStream(myFormTarget); // get the DOM representation DOMDocument *doc = parser->getDocument(); // // do the serialization through DOMLSSerializer::write(); // if(gXPathExpression!=NULL) { XMLCh* xpathStr=XMLString::transcode(gXPathExpression); DOMElement* root = doc->getDocumentElement(); try { DOMXPathNSResolver* resolver=doc->createNSResolver(root); DOMXPathResult* result=doc->evaluate( xpathStr, root, resolver, DOMXPathResult::ORDERED_NODE_SNAPSHOT_TYPE, NULL); XMLSize_t nLength = result->getSnapshotLength(); for(XMLSize_t i = 0; i < nLength; i++) { result->snapshotItem(i); theSerializer->write(result->getNodeValue(), theOutputDesc); } result->release(); resolver->release (); } catch(const DOMXPathException& e) { XERCES_STD_QUALIFIER cerr << "An error occurred during processing of the XPath expression. Msg is:" << XERCES_STD_QUALIFIER endl << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl; retval = 4; } catch(const DOMException& e) { XERCES_STD_QUALIFIER cerr << "An error occurred during processing of the XPath expression. Msg is:" << XERCES_STD_QUALIFIER endl << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl; retval = 4; } XMLString::release(&xpathStr); } else theSerializer->write(doc, theOutputDesc); theOutputDesc->release(); theSerializer->release(); // // Filter, formatTarget and error handler // are NOT owned by the serializer. // delete myFormTarget; delete myErrorHandler; if (gUseFilter) delete myFilter; } catch (const OutOfMemoryException&) { XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl; retval = 5; } catch (XMLException& e) { XERCES_STD_QUALIFIER cerr << "An error occurred during creation of output transcoder. Msg is:" << XERCES_STD_QUALIFIER endl << StrX(e.getMessage()) << XERCES_STD_QUALIFIER endl; retval = 4; } } else retval = 4; // // Clean up the error handler. The parser does not adopt handlers // since they could be many objects or one object installed for multiple // handlers. // delete errReporter; // // Delete the parser itself. Must be done prior to calling Terminate, below. // delete parser; XMLString::release(&gOutputEncoding); // And call the termination method XMLPlatformUtils::Terminate(); return retval; }