From 616e9bfeee29556952ebdccf57cb1fd304744acb Mon Sep 17 00:00:00 2001 From: Benjamin Paassen Date: Sun, 8 Feb 2015 21:42:04 +0100 Subject: first attempt on incorporating transparency: It does work now, even though only if we have a stable "anchor" at the bottom, meaning an explicit structuredclass. We can build the bridge in between. A mechanism to incorporate transparency when only fields are referenced is still missing, though. --- src/plugins/xml/XmlParser.cpp | 31 +++++++++++++++++++++++-------- testdata/xmlparser/simple_book.oxd | 4 ++-- 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/src/plugins/xml/XmlParser.cpp b/src/plugins/xml/XmlParser.cpp index 6d77138..c46d9de 100644 --- a/src/plugins/xml/XmlParser.cpp +++ b/src/plugins/xml/XmlParser.cpp @@ -132,6 +132,7 @@ public: // try to find a FieldDescriptor for the given tag if we are not in a // field already. + // TODO: Consider fields of transparent classes if (!inField && parent != nullptr && parent->getDescriptor()->hasField(name())) { Rooted field{new DocumentField( @@ -151,17 +152,37 @@ public: std::string("\"") + name() + "\" could not be resolved.", location()); } + std::string name; auto it = args.find("name"); if (it != args.end()) { name = it->second.asString(); args.erase(it); } + Rooted entity; if (parentNode->isa(&RttiTypes::Document)) { entity = parentNode.cast()->createRootStructuredEntity( strct, args, name); } else { + // calculate a path if transparent entities are needed in between. + auto path = parent->getDescriptor()->pathTo(strct); + if (path.empty()) { + throw LoggableException( + std::string("An instance of \"") + strct->getName() + + "\" is not allowed as child of an instance of \"" + + parent->getDescriptor()->getName() + "\"", + location()); + } + + // create all transparent entities until the last field. + for (size_t p = 1; p < path.size() - 1; p = p + 2) { + parent = static_cast( + parent->createChildStructuredEntity( + path[p].cast(), + Variant::mapType{}, path[p - 1]->getName(), + "").get()); + } entity = parent->createChildStructuredEntity(strct, args, fieldName, name); } @@ -184,15 +205,9 @@ public: preamble(parentNode, fieldName, parent, inField); // retrieve the correct FieldDescriptor. + // TODO: Consider fields of transparent classes Rooted desc = parent->getDescriptor(); - Rooted field = nullptr; - // TODO: Use more convenient mechanism once possible. - for (auto &fd : desc->getFieldDescriptors()) { - if (fd->getName() == fieldName) { - field = fd; - break; - } - } + Rooted field = desc->getFieldDescriptor(fieldName); if (field == nullptr) { logger().error( std::string("Can't handle data because no field with name \"") + diff --git a/testdata/xmlparser/simple_book.oxd b/testdata/xmlparser/simple_book.oxd index 97e7b79..de33536 100644 --- a/testdata/xmlparser/simple_book.oxd +++ b/testdata/xmlparser/simple_book.oxd @@ -14,11 +14,11 @@ referenced by their key-value pairs as defined in the according StructType. For an example please refer to the more complex book domain. --> - + This might be some introductory text or a dedication. - + -- cgit v1.2.3