void testXmlFromScratch() { Xml::Document scratch; scratch.setRootTag("MyDoc"); cout << scratch; Xml::Comment c("This is a comment."); Xml::Unknown u("!GODONLY knows what this is!!"); Xml::Text t("This is some\ntext on two lines with trailing blanks "); Xml::Element e("elementTag"); // We're never going to use this one so its heap space will // leak if we don't explicitly call clearOrphan(). Xml::Element neverMind("neverMind"); cout << "initially e='" << e.getValue() << "'" << endl; e.updValue() += "AVALUE:"; cout << "then e='" << e.getValue() << "'" << endl; e.setAttributeValue("attr1", String(Vec2(9,-9))); cout << "attr1 is " << e.getRequiredAttributeValueAs<Vec2>("attr1") << endl; cout << "isOrphan? " << String(c.isOrphan()) << ":" << c; cout << "isOrphan? " << String(u.isOrphan()) << ":" << u; cout << "isOrphan? " << String(t.isOrphan()) << ":" << t; cout << "isOrphan? " << String(e.isOrphan()) << ":" << e; e.setValue("this is the only value"); e.updValue() += " (but then I added this)"; cout << "e value=" << e.getValue() << endl; cout << "e = " << e << endl; e.setValue("9 10 -3.2e-4"); cout << "e value=" << e.getValueAs< Array_<float> >() << endl; cout << "e = " << e << endl; scratch.insertTopLevelNodeAfter(scratch.node_begin(), c); cout << "isOrphan? " << String(c.isOrphan()) << ":" << c; cout << scratch; scratch.insertTopLevelNodeBefore(scratch.node_begin(Xml::ElementNode), u); cout << "isOrphan? " << String(u.isOrphan()) << ":" << u; cout << scratch; scratch.insertTopLevelNodeBefore(scratch.node_begin(), Xml::Comment("This should be at the top of the file, except declaration.")); cout << scratch; Xml::Document scratch2; scratch2 = scratch; // deep copy scratch.eraseTopLevelNode(scratch.node_begin()); cout << "First node gone (scratch)?\n" << scratch; cout << "First node still there (scratch2)?\n" << scratch2; Xml::Element e2("anotherElt", Vec3(.1,.2,.3)); cout << e2; e.insertNodeAfter(e.element_end(), e2); cout << "now owns anotherElt:\n" << e; Xml::Element root = scratch.getRootElement(); root.insertNodeAfter(root.node_begin(), e); cout << scratch; scratch.setIndentString(".."); cout << scratch; Xml::Element ecopy = e.clone(); ecopy.setElementTag("elementTagCopy"); cout << "COPY of e: " << ecopy; //scratch.writeToFile("scratch.xml"); e.eraseNode(e.element_begin("anotherElt")); cout << "in-place removal of anotherElt from e: " << scratch; cout << "COPY of e: " << ecopy; root.insertNodeAfter(root.element_begin("elementTag"), ecopy); cout << "After copy insert, scratch=" << scratch; Xml::Node extract = root.removeNode(root.element_begin("elementTagCopy")); cout << "Extracted copy: " << extract << endl; cout << "Now scratch=" << scratch << endl; cout << "Duplicate scratch=" << Xml::Document(scratch) << endl; neverMind.clearOrphan(); }
/* Handle reading older formats/Versioning */ void InverseDynamicsTool::updateFromXMLNode(SimTK::Xml::Element& aNode, int versionNumber) { int documentVersion = versionNumber; if ( documentVersion < XMLDocument::getLatestVersion()){ std::string newFileName = getDocumentFileName(); if (documentVersion < 20300){ std::string origFilename = getDocumentFileName(); newFileName=IO::replaceSubstring(newFileName, ".xml", "_v23.xml"); cout << "Old version setup file encountered. Converting to new file "<< newFileName << endl; SimTK::Xml::Document doc = SimTK::Xml::Document(origFilename); doc.writeToFile(newFileName); } /*if (documentVersion < 20201) { AnalyzeTool updateAnalyzeTool(newFileName, false); updateAnalyzeTool.print(newFileName); }*/ if (documentVersion < 20202){ // get filename and use SimTK::Xml to parse it SimTK::Xml::Document doc = SimTK::Xml::Document(newFileName); Xml::Element oldRoot = doc.getRootElement(); SimTK::Xml::Document newDoc; string prefix = ""; if (oldRoot.getElementTag()=="AnalyzeTool"){ // Make OpenSimDocument node and copy root underneath it newDoc.getRootElement().setElementTag("OpenSimDocument"); newDoc.getRootElement().setAttributeValue("Version", "20201"); prefix = oldRoot.getRequiredAttributeValueAs<string>("name"); // Move all children of root to toolNode newDoc.getRootElement().insertNodeAfter(newDoc.getRootElement().node_end(), oldRoot.clone()); } else newDoc = doc; Xml::Element root = newDoc.getRootElement(); if (root.getElementTag()=="OpenSimDocument"){ int curVersion = root.getRequiredAttributeValueAs<int>("Version"); if (curVersion <= 20201) root.setAttributeValue("Version", "20300"); Xml::element_iterator iterTool(root.element_begin("AnalyzeTool")); iterTool->setElementTag("InverseDynamicsTool"); prefix = iterTool->getRequiredAttributeValueAs<string>("name"); // Remove children <output_precision>, <initial_time>, <final_time> Xml::element_iterator initTimeIter(iterTool->element_begin("initial_time")); double tool_initial_time = initTimeIter->getValueAs<double>(); if (initTimeIter->isValid()) iterTool->eraseNode(initTimeIter); Xml::element_iterator finalTimeIter(iterTool->element_begin("final_time")); double tool_final_time = finalTimeIter->getValueAs<double>(); if (finalTimeIter->isValid()) iterTool->eraseNode(finalTimeIter); Xml::element_iterator precisionIter(iterTool->element_begin("output_precision")); if (precisionIter->isValid()) iterTool->eraseNode(precisionIter); bool use_model_forces=false; // Handle missing or uninitialized values after parsing the old InverseDynamics "Analysis" // Find Analyses underneath it AnalyzeTool Xml::element_iterator iterAnalysisSet(iterTool->element_begin("AnalysisSet")); Xml::element_iterator iterObjects(iterAnalysisSet->element_begin("objects")); Xml::element_iterator iterAnalysis(iterObjects->element_begin("InverseDynamics")); if (iterAnalysis!= iterObjects->element_end()){ // move children to top level Xml::element_iterator p = iterAnalysis->element_begin(); //std::vector<std::string> deprectaed({"on", "in_degrees", "step_interval"}); for (; p!= iterAnalysis->element_end(); ++p) { // skip <on>, <step_interval>, <in_degrees> if (p->getElementTag()=="on" || p->getElementTag()=="in_degrees" || p->getElementTag()=="step_interval" || p->getElementTag()=="start_time" || p->getElementTag()=="end_time") continue; else if (p->getElementTag()=="use_model_force_set"){ String use_model_forcesStr = p->getValueAs<String>(); use_model_forces = (use_model_forcesStr=="true"); } else iterTool->insertNodeAfter( iterTool->node_end(), p->clone()); } // insert elements for "forces_to_exclude" & "time_range" std::ostringstream stream; stream << tool_initial_time << " " << tool_final_time; iterTool->insertNodeAfter( iterTool->node_end(), Xml::Element("time_range", stream.str())); iterTool->insertNodeAfter( iterTool->node_end(), Xml::Element("forces_to_exclude", use_model_forces?"":"Muscles")); iterTool->insertNodeAfter( iterTool->node_end(), Xml::Element("output_gen_force_file", prefix+"_InverseDynamics.sto")); iterTool->insertNodeAfter( iterTool->node_end(), Xml::Element("coordinates_in_degrees", "true")); iterTool->eraseNode(iterAnalysisSet); } newDoc.writeToFile(newFileName); setDocument(new XMLDocument(newFileName)); aNode = updDocument()->getRootDataElement(); } } } Object::updateFromXMLNode(aNode, versionNumber); }
void testXmlFromString() { Xml::Document fromString; fromString.readFromString(xmlJustAComment); cout << "Just a comment: '" << fromString << "'\n"; fromString.readFromString(xmlPlainTextFile); cout << "Plain text file: '" << fromString << "'\n"; // Note that the "condense white space" setting is global, not // document-specific. Xml::Document preserveWhite; Xml::Document::setXmlCondenseWhiteSpace(false); SimTK_TEST(!Xml::Document::isXmlWhiteSpaceCondensed()); preserveWhite.readFromString(xmlPlainTextFile); cout << "Plain text file with white space preserved (raw): " << preserveWhite.getRootElement().getValue() << "\n"; cout << "... (formatted with condense=false): " << preserveWhite << "\n"; Xml::Document::setXmlCondenseWhiteSpace(true); cout << "... (formatted with condense=true): " << preserveWhite << "\n"; SimTK_TEST_MUST_THROW(fromString.readFromString(xmlEmpty)); SimTK_TEST_MUST_THROW(fromString.readFromString(xmlUnclosedComment)); fromString.readFromString(String(xmlPainting)); cout << "Painting: '" << fromString << "'\n"; cout << "Doc type is: " << fromString.getRootTag() << endl; cout << " version: " << fromString.getXmlVersion() << endl; cout << " encoding: " << fromString.getXmlEncoding() << endl; cout << " standalone: " << String(fromString.getXmlIsStandalone() ? "yes" : "no") << endl; cout << "All nodes in doc:\n"; Xml::node_iterator np = fromString.node_begin(); for (; np != fromString.node_end(); ++np) cout << " " << np->getNodeTypeAsString() << endl; Xml::Element root = fromString.getRootElement(); cout << "hasNode()=" << root.hasNode() << endl; cout << "hasNode(Comment)=" << root.hasNode(Xml::CommentNode) << endl; cout << "hasNode(Unknown)=" << root.hasNode(Xml::UnknownNode) << endl; showElement(root); Xml::node_iterator p = root.node_begin(Xml::NoJunkNodes); for (; p != root.node_end(); ++p) cout << p->getNodeTypeAsString() << endl; cout << "Caption elements:\n"; Xml::element_iterator ep(root.element_begin("caption")); for (; ep != root.element_end(); ++ep) cout << ep->getNodeTypeAsString() << ": <" << ep->getElementTag() << ">" << endl; cout << "All elements:\n"; Array_<Xml::Element> all = root.getAllElements(); for (unsigned i=0; i < all.size(); ++i) cout << "<" << all[i].getElementTag() << ">" << endl; Array_<Xml::Node> allNodes(root.node_begin(Xml::NoJunkNodes), root.node_end()); for (unsigned i=0; i < allNodes.size(); ++i) cout << "Node " << allNodes[i].getNodeTypeAsString() << endl; String prettyString, compactString; fromString.writeToString(prettyString); cout << "String pretty: " << prettyString.size() << "\n'" << prettyString << "'\n"; fromString.writeToString(compactString, true); // compact cout << "String compact: " << compactString.size() << "\n'" << compactString << "'\n"; SimTK_TEST(compactString.size() < prettyString.size()); cout << "painting.allNode=" << root.getRequiredElement("painting") .getAllNodes() << endl; cout << "painting.img.allAttr=" << root.getRequiredElement("painting").getRequiredElement("img") .getAllAttributes() << endl; //fromString.writeToFile("TestXml.xml"); //Xml ex("TestXml.xml"); //cout << "Document tag: " << ex.getDocumentTag() << endl; //for (Xml::nodu;e_iterator xp=ex.node_begin(); xp != ex.node_end(); ++xp) // cout << "Node type: " << xp->getNodeTypeAsString() << endl; //PolygonalMesh mesh; //mesh.loadVtpFile("arm_r_humerus.vtp"); //cout << "num vertices=" << mesh.getNumVertices() << " faces=" // << mesh.getNumFaces() << endl; }