From b708dd4cce828c1089a18fefcc22804f7cdad908 Mon Sep 17 00:00:00 2001 From: Benjamin Paassen Date: Sat, 14 Feb 2015 00:09:44 +0100 Subject: added first version of XML output. --- src/plugins/xml/XmlOutput.cpp | 116 ++++++++++++++++++++++++++++++++++++++++++ src/plugins/xml/XmlOutput.hpp | 67 ++++++++++++++++++++++++ 2 files changed, 183 insertions(+) create mode 100644 src/plugins/xml/XmlOutput.cpp create mode 100644 src/plugins/xml/XmlOutput.hpp (limited to 'src/plugins') 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 . +*/ + +#include "XmlOutput.hpp" + +#include +#include + +namespace ousia { +namespace xml { + +void XmlTransformer::writeXml(Handle doc, std::ostream &out, + Logger &logger, bool pretty) +{ + Manager &mgr = doc->getManager(); + // the outermost tag is the document itself. + Rooted document{new Element{mgr, {nullptr}, "document"}}; + // then write imports for all references domains. + for (auto d : doc->getDomains()) { + Rooted 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 root = + transformStructuredEntity(document, doc->getRoot(), logger, pretty); + document->addChild(root); + // then serialize. + document->serialize(out, "", pretty); +} + +Rooted XmlTransformer::transformStructuredEntity( + Handle parent, Handle 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 as = + s->getDescriptor()->getAttributesDescriptor()->getAttributes(); + std::map 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 elem{ + new Element{mgr, parent, s->getDescriptor()->getName(), xmlAttrs}}; + // then transform the fields. + NodeVector fieldDescs = + s->getDescriptor()->getFieldDescriptors(); + for (size_t f = 0; f < fieldDescs.size(); f++) { + NodeVector field = s->getField(f); + Rooted fieldDesc = fieldDescs[f]; + // if this is not the default node create an intermediate node for it. + Rooted par = elem; + if (fieldDesc->getFieldType() != FieldDescriptor::FieldType::TREE && + !fieldDesc->isPrimitive()) { + par = Rooted{new Element(mgr, elem, fieldDesc->getName())}; + elem->addChild(par); + } + for (auto c : field) { + // transform each child. + Rooted child; + if (c->isa(&RttiTypes::StructuredEntity)) { + child = transformStructuredEntity( + par, c.cast(), logger, pretty); + } else if (c->isa(&RttiTypes::DocumentPrimitive)) { + child = transformPrimitive(par, c.cast(), + logger, pretty); + } + // TODO: Handle Anchors + if (child != nullptr) { + par->addChild(child); + } + } + } + return elem; +} +Rooted XmlTransformer::transformPrimitive(Handle parent, + Handle p, + Logger &logger, bool pretty) +{ + Manager &mgr = parent->getManager(); + // transform the primitive content. + std::string textcontent = + VariantWriter::writeJsonToString(p->getContent(), pretty); + Rooted 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 . +*/ + +/** + * @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 + +#include +#include + +namespace ousia { +namespace xml { + +class XmlTransformer { +private: + Rooted transformStructuredEntity(Handle parent, + Handle s, + Logger &logger, bool pretty); + + Rooted transformPrimitive(Handle parent, + Handle 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 doc, std::ostream &out, Logger &logger, + bool pretty); +}; +} +} +#endif \ No newline at end of file -- cgit v1.2.3