| 610 | ) { } |
| 611 | |
| 612 | virtual void start_element ( |
| 613 | const unsigned long /*line_number*/, |
| 614 | const std::string& name, |
| 615 | const dlib::attribute_list& atts |
| 616 | ) |
| 617 | { |
| 618 | if (!seen_first_tag) |
| 619 | { |
| 620 | if (name != "net") |
| 621 | throw dlib::error("The top level XML tag must be a 'net' tag."); |
| 622 | seen_first_tag = true; |
| 623 | } |
| 624 | |
| 625 | if (name == "layer") |
| 626 | { |
| 627 | next_layer = layer(); |
| 628 | if (atts["type"] == "skip") |
| 629 | { |
| 630 | // Don't make a new layer, just apply the tag id to the previous layer |
| 631 | if (layers.size() == 0) |
| 632 | throw dlib::error("A skip layer was found as the first layer, but the first layer should be an input layer."); |
| 633 | layers.back().skip_id = sa = atts["id"]; |
| 634 | |
| 635 | // We intentionally leave next_layer empty so the end_element() callback |
| 636 | // don't add it as another layer when called. |
| 637 | } |
| 638 | else if (atts["type"] == "tag") |
| 639 | { |
| 640 | // Don't make a new layer, just remember the tag id so we can apply it on |
| 641 | // the next layer. |
| 642 | tag_id = sa = atts["id"]; |
| 643 | |
| 644 | // We intentionally leave next_layer empty so the end_element() callback |
| 645 | // don't add it as another layer when called. |
| 646 | } |
| 647 | else |
| 648 | { |
| 649 | next_layer.idx = sa = atts["idx"]; |
| 650 | next_layer.type = atts["type"]; |
| 651 | if (tag_id != -1) |
| 652 | { |
| 653 | next_layer.tag_id = tag_id; |
| 654 | tag_id = -1; |
| 655 | } |
| 656 | } |
| 657 | } |
| 658 | else if (current_tag.size() != 0 && current_tag.top() == "layer") |
| 659 | { |
| 660 | next_layer.detail_name = name; |
| 661 | // copy all the XML tag's attributes into the layer struct |
| 662 | atts.reset(); |
| 663 | while (atts.move_next()) |
| 664 | next_layer.attributes[atts.element().key()] = sa = atts.element().value(); |
| 665 | } |
| 666 | |
| 667 | current_tag.push(name); |
| 668 | } |
| 669 | |