summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/plugins/xml/XmlParser.cpp73
-rw-r--r--testdata/xmlparser/simple_book.oxd15
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>