summaryrefslogtreecommitdiff
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/xml/XmlOutput.cpp116
-rw-r--r--src/plugins/xml/XmlOutput.hpp67
2 files changed, 183 insertions, 0 deletions
diff --git a/src/plugins/xml/XmlOutput.cpp b/src/plugins/xml/XmlOutput.cpp
new file mode 100644
index 0000000..00aae04
--- /dev/null
+++ b/src/plugins/xml/XmlOutput.cpp
@@ -0,0 +1,116 @@
+/*
+ Ousía
+ Copyright (C) 2014 Benjamin Paaßen, Andreas Stöckel
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "XmlOutput.hpp"
+
+#include <core/common/Variant.hpp>
+#include <core/common/VariantWriter.hpp>
+
+namespace ousia {
+namespace xml {
+
+void XmlTransformer::writeXml(Handle<Document> doc, std::ostream &out,
+ Logger &logger, bool pretty)
+{
+ Manager &mgr = doc->getManager();
+ // the outermost tag is the document itself.
+ Rooted<Element> document{new Element{mgr, {nullptr}, "document"}};
+ // then write imports for all references domains.
+ for (auto d : doc->getDomains()) {
+ Rooted<Element> import{
+ new Element{mgr,
+ document,
+ "import",
+ {{"rel", "domain"}, {"src", d->getName() + ".oxm"}}}};
+ document->addChild(import);
+ }
+ // transform the root element (and, using recursion, everything below it)
+ Rooted<Element> root =
+ transformStructuredEntity(document, doc->getRoot(), logger, pretty);
+ document->addChild(root);
+ // then serialize.
+ document->serialize(out, "<?xml version=\"1.0\"?>", pretty);
+}
+
+Rooted<Element> XmlTransformer::transformStructuredEntity(
+ Handle<Element> parent, Handle<StructuredEntity> s, Logger &logger,
+ bool pretty)
+{
+ Manager &mgr = parent->getManager();
+ // TODO: Is this the right handling?
+ // copy the attributes.
+ Variant attrs = s->getAttributes();
+ // build them.
+ s->getDescriptor()->getAttributesDescriptor()->build(attrs, logger);
+ // get the array representation.
+ Variant::arrayType attrArr = attrs.asArray();
+ // transform them to string key-value pairs.
+ NodeVector<Attribute> as =
+ s->getDescriptor()->getAttributesDescriptor()->getAttributes();
+ std::map<std::string, std::string> xmlAttrs;
+ for (size_t a = 0; a < as.size(); a++) {
+ xmlAttrs.emplace(as[a]->getName(),
+ VariantWriter::writeJsonToString(attrArr[a], pretty));
+ }
+ // create the XML element itself.
+ Rooted<Element> elem{
+ new Element{mgr, parent, s->getDescriptor()->getName(), xmlAttrs}};
+ // then transform the fields.
+ NodeVector<FieldDescriptor> fieldDescs =
+ s->getDescriptor()->getFieldDescriptors();
+ for (size_t f = 0; f < fieldDescs.size(); f++) {
+ NodeVector<StructureNode> field = s->getField(f);
+ Rooted<FieldDescriptor> fieldDesc = fieldDescs[f];
+ // if this is not the default node create an intermediate node for it.
+ Rooted<Element> par = elem;
+ if (fieldDesc->getFieldType() != FieldDescriptor::FieldType::TREE &&
+ !fieldDesc->isPrimitive()) {
+ par = Rooted<Element>{new Element(mgr, elem, fieldDesc->getName())};
+ elem->addChild(par);
+ }
+ for (auto c : field) {
+ // transform each child.
+ Rooted<Node> child;
+ if (c->isa(&RttiTypes::StructuredEntity)) {
+ child = transformStructuredEntity(
+ par, c.cast<StructuredEntity>(), logger, pretty);
+ } else if (c->isa(&RttiTypes::DocumentPrimitive)) {
+ child = transformPrimitive(par, c.cast<DocumentPrimitive>(),
+ logger, pretty);
+ }
+ // TODO: Handle Anchors
+ if (child != nullptr) {
+ par->addChild(child);
+ }
+ }
+ }
+ return elem;
+}
+Rooted<Text> XmlTransformer::transformPrimitive(Handle<Element> parent,
+ Handle<DocumentPrimitive> p,
+ Logger &logger, bool pretty)
+{
+ Manager &mgr = parent->getManager();
+ // transform the primitive content.
+ std::string textcontent =
+ VariantWriter::writeJsonToString(p->getContent(), pretty);
+ Rooted<Text> text{new Text(mgr, parent, textcontent)};
+ return text;
+}
+}
+} \ No newline at end of file
diff --git a/src/plugins/xml/XmlOutput.hpp b/src/plugins/xml/XmlOutput.hpp
new file mode 100644
index 0000000..51d03f9
--- /dev/null
+++ b/src/plugins/xml/XmlOutput.hpp
@@ -0,0 +1,67 @@
+/*
+ Ousía
+ Copyright (C) 2014 Benjamin Paaßen, Andreas Stöckel
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file XmlOutput.hpp
+ *
+ * This provices an Output generator to serialize any given document to XML.
+ *
+ * @author Benjamin Paaßen (bpaassen@techfak.uni-bielefeld.de)
+ */
+#ifndef _OUSIA_XML_OUTPUT_HPP_
+#define _OUSIA_XML_OUTPUT_HPP_
+
+#include <ostream>
+
+#include <core/model/Document.hpp>
+#include <core/XML.hpp>
+
+namespace ousia {
+namespace xml {
+
+class XmlTransformer {
+private:
+ Rooted<Element> transformStructuredEntity(Handle<Element> parent,
+ Handle<StructuredEntity> s,
+ Logger &logger, bool pretty);
+
+ Rooted<Text> transformPrimitive(Handle<Element> parent,
+ Handle<DocumentPrimitive> p,
+ Logger &logger, bool pretty);
+
+public:
+ /**
+ * This writes an XML serialization of the given document to the given
+ * output stream. The serialization is equivalent to the input XML format,
+ * safe for the domain references. TODO: Can we change this? If so: how?
+ * Note, though, that the serialization will not exploit transparency.
+ * TODO: Can we change that?
+ *
+ * @param doc is some Document.
+ * @param out is the output stream the XML serialization of the document
+ * shall be written to.
+ * @param logger is the logger errors shall be written to.
+ * @param pretty is a flag that manipulates whether newlines and tabs are
+ * used.
+ */
+ void writeXml(Handle<Document> doc, std::ostream &out, Logger &logger,
+ bool pretty);
+};
+}
+}
+#endif \ No newline at end of file