diff options
-rw-r--r-- | src/plugins/xml/XmlParser.cpp | 73 | ||||
-rw-r--r-- | testdata/xmlparser/simple_book.oxd | 15 |
2 files changed, 59 insertions, 29 deletions
diff --git a/src/plugins/xml/XmlParser.cpp b/src/plugins/xml/XmlParser.cpp index 0c88c5d..bd9b681 100644 --- a/src/plugins/xml/XmlParser.cpp +++ b/src/plugins/xml/XmlParser.cpp @@ -132,7 +132,7 @@ public: // try to find a FieldDescriptor for the given tag if we are not in a // field already. - if (!inField && parent != nullptr && parent->hasField(fieldName)) { + if (!inField && parent != nullptr && parent->hasField(name())) { Rooted<DocumentField> field{new DocumentField( parentNode->getManager(), fieldName, parentNode)}; field->setLocation(location()); @@ -170,25 +170,56 @@ public: void end() override { scope().pop(); } - void data(const std::string &data, int field) override + void data(const std::string &data, int fieldIdx) override { - // Rooted<Node> parentNode = scope().selectOrThrow( - // { &RttiTypes::StructuredEntity, - // &RttiTypes::AnnotationEntity, &RttiTypes::DocumentField}); - - // std::string fieldName; - // DocumentEntity *parent; - // bool inField; - // - // preamble(parentNode, fieldName, parent, inField); - // - // // retrieve the correct FieldDescriptor. - // - // - // CharReader reader{data, location().getSourceId(), - // location().getStart()}; - // auto res = VariantReader::parseGeneric(reader, logger(), - // std::unordered_set<char>{}); + Rooted<Node> parentNode = scope().selectOrThrow( + {&RttiTypes::StructuredEntity, &RttiTypes::AnnotationEntity, + &RttiTypes::DocumentField}); + + std::string fieldName; + DocumentEntity *parent; + bool inField; + + preamble(parentNode, fieldName, parent, inField); + + // retrieve the correct FieldDescriptor. + Rooted<Descriptor> desc = parent->getDescriptor(); + Rooted<FieldDescriptor> field = nullptr; + // TODO: Use more convenient mechanism once possible. + for (auto &fd : desc->getFieldDescriptors()) { + if (fd->getName() == fieldName) { + field = fd; + break; + } + } + if (field == nullptr) { + logger().error( + std::string("Can't handle data because no field with name \"") + + fieldName + "\" exists in descriptor\"" + desc->getName() + + "\".", + location()); + return; + } + if (!field->isPrimitive()) { + logger().error(std::string("Can't handle data because field \"") + + fieldName + "\" of descriptor \"" + + desc->getName() + "\" is not primitive!", + location()); + return; + } + + // try to parse the content. + auto res = VariantReader::parseGenericString( + data, logger(), location().getSourceId(), location().getStart()); + if (!res.first) { + return; + } + // try to convert it to the correct type. + if (!field->getPrimitiveType()->build(res.second, logger())) { + return; + } + // add it as primitive content. + parent->createChildDocumentPrimitive(res.second, fieldName); } static Handler *create(const HandlerData &handlerData) @@ -864,7 +895,7 @@ static const ParserState Document = static const ParserState DocumentChild = ParserStateBuilder() - .parent(&Document) + .parents({&Document, &DocumentChild}) .createdNodeTypes({&RttiTypes::StructureNode, &RttiTypes::AnnotationEntity, &RttiTypes::DocumentField}) @@ -1265,6 +1296,7 @@ static void xmlStartElementHandler(void *p, const XML_Char *name, // Assemble the arguments Variant::mapType args; + const XML_Char **attr = attrs; while (*attr) { // Convert the C string to a std::string @@ -1283,6 +1315,7 @@ static void xmlStartElementHandler(void *p, const XML_Char *name, keyLoc.getStart()); args.emplace(key, value.second); } + // Call the start function std::string nameStr(name); diff --git a/testdata/xmlparser/simple_book.oxd b/testdata/xmlparser/simple_book.oxd index bb8cc16..97e7b79 100644 --- a/testdata/xmlparser/simple_book.oxd +++ b/testdata/xmlparser/simple_book.oxd @@ -14,20 +14,17 @@ referenced by their key-value pairs as defined in the according StructType. For an example please refer to the more complex book domain. --> - <!--<book:paragraph> + <paragraph> <text> - This might be some introductory text or a dedication. Ideally, of - course, such elements would be semantically specified as such in - additional domains (or in this one). + This might be some introductory text or a dedication. </text> - </book:paragraph>--> + </paragraph> <!-- Note that a better version of the book domain might specify headings here. --> <chapter name="myFirstChapter"> - <!--<paragraph> + <paragraph> <text> - Here we might have an introduction to the chapter, including some - overview of the chapters structure. + Here we might have an introduction to the chapter. </text> </paragraph> <section name="myFirstSection"> @@ -43,7 +40,7 @@ Here we might find the actual section content. </text> </paragraph> - </section>--> + </section> </chapter> </book> </document> |