// Read CPACS fuselage section elements void CCPACSFuselageSectionElements::ReadCPACS(TixiDocumentHandle tixiHandle, const std::string& sectionXPath) { Cleanup(); ReturnCode tixiRet; int elementCount; std::string tempString; char* elementPath; /* Get section element count */ tempString = sectionXPath + "/elements"; elementPath = const_cast<char*>(tempString.c_str()); tixiRet = tixiGetNamedChildrenCount(tixiHandle, elementPath, "element", &elementCount); if (tixiRet != SUCCESS) { throw CTiglError("XML error: tixiGetNamedChildrenCount failed in CCPACSFuselageSectionElements::ReadCPACS", TIGL_XML_ERROR); } // Loop over all section elements for (int i = 1; i <= elementCount; i++) { CCPACSFuselageSectionElement* element = new CCPACSFuselageSectionElement(); elements.push_back(element); tempString = sectionXPath + "/elements/element["; std::ostringstream xpath; xpath << tempString << i << "]"; element->ReadCPACS(tixiHandle, xpath.str()); } }
// Read CPACS wing sections element void CCPACSWingSections::ReadCPACS(TixiDocumentHandle tixiHandle, const std::string& wingXPath) { Cleanup(); ReturnCode tixiRet; int sectionCount; std::string tempString; char* elementPath; /* Get section element count */ tempString = wingXPath + "/sections"; elementPath = const_cast<char*>(tempString.c_str()); tixiRet = tixiGetNamedChildrenCount(tixiHandle, elementPath, "section", §ionCount); if (tixiRet != SUCCESS) { throw CTiglError("XML error: tixiGetNamedChildrenCount failed in CCPACSWingSections::ReadCPACS", TIGL_XML_ERROR); } // Loop over all sections for (int i = 1; i <= sectionCount; i++) { CCPACSWingSection* section = new CCPACSWingSection(); sections.push_back(section); tempString = wingXPath + "/sections/section["; std::ostringstream xpath; xpath << tempString << i << "]"; section->ReadCPACS(tixiHandle, xpath.str()); } }
// Read CPACS positionings element void CCPACSWingPositionings::ReadCPACS(TixiDocumentHandle tixiHandle, const std::string& wingXPath) { Cleanup(); ReturnCode tixiRet; int positioningCount; std::string tempString; char* elementPath; /* Get positioning element count */ tempString = wingXPath + "/positionings"; elementPath = const_cast<char*>(tempString.c_str()); tixiRet = tixiGetNamedChildrenCount(tixiHandle, elementPath, "positioning", &positioningCount); if (tixiRet != SUCCESS) { throw CTiglError("XML error: tixiGetNamedChildrenCount failed in CCPACSWingPositionings::ReadCPACS", TIGL_XML_ERROR); } // Loop over all positionings for (int i = 1; i <= positioningCount; i++) { CCPACSWingPositioning* positioning = new CCPACSWingPositioning(); tempString = wingXPath + "/positionings/positioning["; std::ostringstream xpath; xpath << tempString << i << "]"; positioning->ReadCPACS(tixiHandle, xpath.str()); positionings[positioning->GetOuterSectionIndex()] = positioning; } Update(); }
TEST_F(OtherTests, childCount_childDoesNotExist) { const char* elementPath = "/plane/wings"; const char* childName = "this_child_does_not_exist"; int count; ASSERT_TRUE( tixiGetNamedChildrenCount( inDocumentHandle, elementPath, childName, &count ) == SUCCESS); ASSERT_TRUE( count == 0); }
TEST_F(OtherTests, childCount_twoChildren) { const char* elementPath = "/plane/wings"; const char* childName = "wing"; int count; ASSERT_TRUE( tixiGetNamedChildrenCount( inDocumentHandle, elementPath, childName, &count ) == SUCCESS ); ASSERT_TRUE( count == 2 ); }
// Read CPACS rotorHinges elements void CCPACSRotorHinges::ReadCPACS(TixiDocumentHandle tixiHandle, const std::string rotorHingesXPath, const std::string rotorHingeElementName) { Cleanup(); /* Get rotorHinge element count */ int elementCount; if (tixiGetNamedChildrenCount(tixiHandle, rotorHingesXPath.c_str(), rotorHingeElementName.c_str(), &elementCount) != SUCCESS) { throw CTiglError("XML error: tixiGetNamedChildrenCount failed in CCPACSRotorHinges::ReadCPACS", TIGL_XML_ERROR); } // Loop over all rotorHinge elements for (int i = 1; i <= elementCount; i++) { CCPACSRotorHinge* rotorHinge = new CCPACSRotorHinge(rotorBladeAttachment); rotorHinges.push_back(rotorHinge); std::ostringstream xpath; xpath << rotorHingesXPath << "/" << rotorHingeElementName << "[" << i << "]"; rotorHinge->ReadCPACS(tixiHandle, xpath.str()); } }
// Read CPACS wings element void CCPACSWings::ReadCPACS(TixiDocumentHandle tixiHandle, const char* configurationUID) { Cleanup(); char *tmpString = NULL; if (tixiUIDGetXPath(tixiHandle, configurationUID, &tmpString) != SUCCESS) { throw CTiglError("XML error: tixiUIDGetXPath failed in CCPACSWings::ReadCPACS", TIGL_XML_ERROR); } std::string wingXPath= tmpString; wingXPath += "[@uID=\""; wingXPath += configurationUID; wingXPath += "\"]/wings"; // Read wing profiles profiles.ReadCPACS(tixiHandle); if (tixiCheckElement(tixiHandle, wingXPath.c_str()) != SUCCESS) { return; } /* Get wing element count */ int wingCount; if (tixiGetNamedChildrenCount(tixiHandle, wingXPath.c_str(), "wing", &wingCount) != SUCCESS) { throw CTiglError("XML error: tixiGetNamedChildrenCount failed in CCPACSWings::ReadCPACS", TIGL_XML_ERROR); } // Loop over all wings for (int i = 1; i <= wingCount; i++) { CCPACSWing* wing = new CCPACSWing(configuration); wings.push_back(wing); std::ostringstream xpath; xpath << wingXPath << "/wing[" << i << "]"; wing->ReadCPACS(tixiHandle, xpath.str()); } }
// Write CPACS fuselage profiles void CCPACSFuselageProfiles::WriteCPACS(TixiDocumentHandle tixiHandle) { const char* elementPath = "/cpacs/vehicles/profiles/fuselageProfiles"; std::string path; ReturnCode tixiRet; int fuselageProfileCount, test; TixiSaveExt::TixiSaveElement(tixiHandle, "/cpacs/vehicles", "profiles"); TixiSaveExt::TixiSaveElement(tixiHandle, "/cpacs/vehicles/profiles", "fuselageProfiles"); if (tixiGetNamedChildrenCount(tixiHandle, elementPath, "fuselageProfile", &test) != SUCCESS) { throw CTiglError("XML error: tixiGetNamedChildrenCount failed in CCPACSFuselageProfiles::WriteCPACS", TIGL_XML_ERROR); } fuselageProfileCount = GetProfileCount(); for (int i = 1; i <= fuselageProfileCount; i++) { std::stringstream ss; ss << elementPath << "/fuselageProfile[" << i << "]"; path = ss.str(); CCPACSFuselageProfile& fuselageProfile = GetProfile(i); if ((tixiRet = tixiCheckElement(tixiHandle, path.c_str())) == ELEMENT_NOT_FOUND) { if ((tixiRet = tixiCreateElement(tixiHandle, elementPath, "fuselageProfile")) != SUCCESS) { throw CTiglError("XML error: tixiCreateElement failed in CCPACSFuselageProfiles::WriteCPACS", TIGL_XML_ERROR); } } fuselageProfile.WriteCPACS(tixiHandle, path); } for (int i = fuselageProfileCount + 1; i <= test; i++) { std::stringstream ss; ss << elementPath << "/fuselageProfile[" << fuselageProfileCount + 1 << "]"; path = ss.str(); tixiRet = tixiRemoveElement(tixiHandle, path.c_str()); } }
// Read CPACS fuselage profiles void CCPACSFuselageProfiles::ReadCPACS(TixiDocumentHandle tixiHandle) { Cleanup(); if (tixiCheckElement(tixiHandle, "/cpacs/vehicles/profiles/fuselageProfiles") != SUCCESS) { return; } /* Get <geometry> element count */ int geometryCount; if (tixiGetNamedChildrenCount(tixiHandle, "/cpacs/vehicles/profiles/fuselageProfiles", "fuselageProfile", &geometryCount) != SUCCESS) { throw CTiglError("Error: tixiGetNamedChildrenCount failed in CCPACSFuselageProfiles::ReadCPACS", TIGL_XML_ERROR); } // Loop over all <fuselageProfile> elements for (int i = 1; i <= geometryCount; i++) { std::ostringstream xpath; xpath << "/cpacs/vehicles/profiles/fuselageProfiles/fuselageProfile[" << i << "]"; CCPACSFuselageProfile* profile = new CCPACSFuselageProfile(xpath.str()); profile->ReadCPACS(tixiHandle); profiles[profile->GetUID()] = profile; } }
ReturnCode openExternalFiles(TixiDocument* aTixiDocument, int* number) { int iNode = 0; int handle = aTixiDocument->handle; xmlNodePtr cur = NULL; ReturnCode error = SUCCESS; assert(aTixiDocument != NULL); *number = 0; while(1) { // loop until there are no externaldata nodes included xmlXPathObjectPtr xpathObject = XPathEvaluateExpression(aTixiDocument->docPtr, "//externaldata"); xmlNodeSetPtr nodeset = NULL; char* externalDataNodeXPath, *externalDataDirectoryXPath, *externalDataDirectory, *resolvedDirectory; int externalFileCount = 0; if (!xpathObject) { // no more external data, stop break; } nodeset = xpathObject->nodesetval; if (!nodeset || nodeset->nodeNr < 1) { break; } // goto the first node that is an element for (iNode = 0; iNode < nodeset->nodeNr; ++iNode) { cur = nodeset->nodeTab[iNode]; if (cur->type == XML_ELEMENT_NODE) { break; // for loop } } if (iNode == nodeset->nodeNr) { // no element node found xmlXPathFreeObject(xpathObject); break; // while loop } // found external data node xmlXPathFreeObject(xpathObject); /* get nodes XPath */ externalDataNodeXPath = (char*) xmlGetNodePath(cur); /* now get the subdirectory */ externalDataDirectoryXPath = buildString("%s/%s", externalDataNodeXPath, EXTERNAL_DATA_NODE_NAME_PATH); error = tixiGetTextElement(handle, externalDataDirectoryXPath, &externalDataDirectory); free(externalDataDirectoryXPath); if (error) { printMsg(MESSAGETYPE_ERROR, "Error: openExternalFiles returns %d. No path defined in externaldata node!\n", error); xmlFree(externalDataNodeXPath); return OPEN_FAILED; } // resolv data directory (in case of relative paths) resolvedDirectory = resolveDirectory(aTixiDocument->dirname, externalDataDirectory); /* now get number and names of all external files */ tixiGetNamedChildrenCount(handle, externalDataNodeXPath, EXTERNAL_DATA_NODE_NAME_FILENAME, &externalFileCount); if (externalFileCount == 0) { printMsg(MESSAGETYPE_ERROR, "Error: no filename nodes defined in externalData node.\n"); xmlFree(externalDataNodeXPath); free(resolvedDirectory); return OPEN_FAILED; } for (iNode = 1; iNode <= externalFileCount; iNode++) { char* externalFileName, *externalFullFileName, *newDocumentString, *fileNameXPath; xmlDocPtr xmlDocument = NULL; fileNameXPath = buildString("%s/filename[%d]", externalDataNodeXPath, iNode); tixiGetTextElement(handle, fileNameXPath, &externalFileName); free(fileNameXPath); /* Build complete filename */ externalFullFileName = buildString("%s%s", resolvedDirectory, externalFileName); /* open files */ newDocumentString = loadExternalFileToString(externalFullFileName); if (newDocumentString == NULL) { printMsg(MESSAGETYPE_ERROR, "\nError in fetching external file \"%s\".\n", externalFullFileName); free(externalFullFileName); xmlFree(externalDataNodeXPath); free(resolvedDirectory); return OPEN_FAILED; } /* now parse the file to DOM */ xmlDocument = xmlReadMemory(newDocumentString, (int) strlen(newDocumentString), "urlResource", NULL, 0); free(newDocumentString); if (xmlDocument) { xmlNodePtr rootToInsert = xmlDocGetRootElement(xmlDocument); xmlNodePtr parent = cur->parent; if (parent) { xmlChar* nodePathNew = NULL; char* dataURI = localPathToURI(externalDataDirectory); xmlNodePtr nodeToInsert = xmlDocCopyNode(rootToInsert, aTixiDocument->docPtr, 1); /* add metadata to node, to allow saving external node data */ xmlSetProp(nodeToInsert, (xmlChar*) EXTERNAL_DATA_XML_ATTR_FILENAME, (xmlChar*) externalFileName); /* save the sub-directory */ xmlSetProp(nodeToInsert, (xmlChar*) EXTERNAL_DATA_XML_ATTR_DIRECTORY, (xmlChar*) dataURI); free(dataURI); /* save the external data node position */ nodePathNew = xmlGetNodePath(parent); xmlSetProp(nodeToInsert, (xmlChar*) EXTERNAL_DATA_XML_ATTR_NODEPATH, nodePathNew); xmlFree(nodePathNew); /* replace externalData node with xml file's content */ xmlReplaceNode(cur, nodeToInsert); /* file could be loaded and parsed, increase the counter */ (*number)++; } xmlFreeDoc(xmlDocument); } else { printMsg(MESSAGETYPE_WARNING, "Document %s will be ignored. No valid XML document!\n", externalFullFileName); /* remove external data node */ xmlUnlinkNode(cur); } free(externalFullFileName); } /* end for files */ free(resolvedDirectory); free(externalDataNodeXPath); xmlFreeNode(cur); } if (*number == 0) { printMsg(MESSAGETYPE_WARNING, "WARNING: Unable to load any externaldata files.\n"); } return SUCCESS; }
TEST_F(OtherTests, childCound_invalidXPath){ int count = 0; ASSERT_EQ(INVALID_XPATH, tixiGetNamedChildrenCount( inDocumentHandle, "/plane/wings/\\blubb", "centerOfGravity", &count)); ASSERT_EQ(INVALID_XPATH, tixiGetNamedChildrenCount( inDocumentHandle, "/plane/wings/wing[1]", "centerOf\\Gravity", &count)); }
TEST_F(OtherTests, childCound_pathNotUnique){ int count = 0; ASSERT_EQ(ELEMENT_PATH_NOT_UNIQUE, tixiGetNamedChildrenCount( inDocumentHandle, "/plane/wings/wing", "centerOfGravity", &count)); }
TEST_F(OtherTests, childCound_invalidParent){ int count = 0; ASSERT_EQ(ELEMENT_NOT_FOUND, tixiGetNamedChildrenCount( inDocumentHandle, "/invalidparent", "wings", &count)); }
TEST_F(OtherTests, childCound_invalidHandle){ int count = 0; ASSERT_EQ(INVALID_HANDLE, tixiGetNamedChildrenCount(-1, "/plane", "wings", &count)); }