| 371 | } |
| 372 | |
| 373 | static void start_element(void* user, const xmlChar* tag, const xmlChar** attrs) { |
| 374 | ifcxml_parse_state* state = (ifcxml_parse_state*)user; |
| 375 | std::string tagname = (char*)tag; |
| 376 | |
| 377 | #ifndef NDEBUG |
| 378 | std::cout << "stack:" << std::endl; |
| 379 | { |
| 380 | int i = 1; |
| 381 | for (auto& node : state->stack) { |
| 382 | std::cout << " " << (i++) << ":" << node.repr() << std::endl; |
| 383 | } |
| 384 | } |
| 385 | std::cout << std::string(state->stack.size(), ' ') << "<" << tagname << ">"; |
| 386 | #endif |
| 387 | |
| 388 | std::vector<std::pair<std::string, std::string>> attributes; |
| 389 | |
| 390 | if (attrs != nullptr) { |
| 391 | std::string attrname; |
| 392 | int i = 0; |
| 393 | while (attrs[i] != NULL) { |
| 394 | if ((i % 2) != 0) { |
| 395 | const std::string value = (char*)attrs[i]; |
| 396 | #ifndef NDEBUG |
| 397 | std::cout << " " << attrname << "='" << value << "'"; |
| 398 | #endif |
| 399 | attributes.push_back(std::make_pair(attrname, value)); |
| 400 | |
| 401 | if ((tagname == "ifc:ifcXML" || tagname == "ifcXML") && attrname == "xsi:schemaLocation" && |
| 402 | (boost::starts_with(value, "http://www.buildingsmart-tech.org/ifcXML/IFC4") || |
| 403 | boost::starts_with(value, "http://www.buildingsmart-tech.org/ifc/IFC4"))) { |
| 404 | // We're expecting a schemaLocation like "http://www.buildingsmart-tech.org/ifcXML/IFC4/Add2 IFC4_ADD2_TC1.xsd" |
| 405 | // With token compression this is split into: |
| 406 | // [0] http: |
| 407 | // [1] www.buildingsmart-tech.org |
| 408 | // [2] ifcXML |
| 409 | // [3] IFC4 |
| 410 | // [4] Add2 |
| 411 | // [5] IFC4_ADD2_TC1.xsd |
| 412 | // The hosstname will likely change though. |
| 413 | auto it = boost::algorithm::make_split_iterator(value, boost::algorithm::token_finder(boost::algorithm::is_any_of("/ "), boost::algorithm::token_compress_on)); |
| 414 | decltype(it) end; |
| 415 | for (int tok = 0; it != end && tok < 3; ++it, ++tok) { |
| 416 | } |
| 417 | if (it != end) { |
| 418 | std::string schema_name(&it->front(), it->size()); |
| 419 | boost::to_upper(schema_name); |
| 420 | state->file = new IfcParse::IfcFile(IfcParse::schema_by_name(schema_name)); |
| 421 | state->dialect = ifcxml_dialect_ifc4; |
| 422 | } |
| 423 | goto end; |
| 424 | } else if (tagname == "ex:iso_10303_28" && attrname == "xsi:schemaLocation" && boost::starts_with(value, "http://www.iai-tech.org/ifcXML/IFC2x3")) { |
| 425 | state->file = new IfcParse::IfcFile(IfcParse::schema_by_name("IFC2X3")); |
| 426 | state->dialect = ifcxml_dialect_ifc2x3; |
| 427 | goto end; |
| 428 | } |
| 429 | } else { |
| 430 | attrname = (char*)attrs[i]; |
nothing calls this directly
no test coverage detected