diff options
author | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-02-17 17:15:10 +0100 |
---|---|---|
committer | Andreas Stöckel <astoecke@techfak.uni-bielefeld.de> | 2015-02-17 17:15:10 +0100 |
commit | fcc6a49d8124a0fe1130e242191cc3dc3d701309 (patch) | |
tree | a07a96509ff9a415d0f9f1265c754a5af77ba20c | |
parent | e8df5877aa9bbeeb34ab0fe13f41d8096919c748 (diff) | |
parent | 1bfa8739ed66a25397286ea8be98c3eeb1c695af (diff) |
Merge branch 'master' of somweyr.de:ousia
-rw-r--r-- | src/cli/Main.cpp | 11 | ||||
-rw-r--r-- | src/core/XML.cpp | 14 | ||||
-rw-r--r-- | src/core/XML.hpp | 25 | ||||
-rw-r--r-- | src/core/model/Document.hpp | 10 | ||||
-rw-r--r-- | src/plugins/xml/XmlOutput.cpp | 95 | ||||
-rw-r--r-- | src/plugins/xml/XmlOutput.hpp | 5 |
6 files changed, 113 insertions, 47 deletions
diff --git a/src/cli/Main.cpp b/src/cli/Main.cpp index 4e09e67..7ec7cf9 100644 --- a/src/cli/Main.cpp +++ b/src/cli/Main.cpp @@ -81,14 +81,15 @@ const char *MSG_COPYING = const std::set<std::string> formats{"html", "xml"}; static void createOutput(Handle<Document> doc, std::ostream &out, - const std::string &format, Logger &logger) + const std::string &format, Logger &logger, + ResourceManager &resMgr) { if (format == "html") { html::DemoHTMLTransformer transform; transform.writeHTML(doc, out, true); } else if (format == "xml") { xml::XmlTransformer transform; - transform.writeXml(doc, out, logger, true); + transform.writeXml(doc, out, logger, resMgr, true); } } @@ -247,10 +248,10 @@ int main(int argc, char **argv) // write output if (outputPath != "-") { std::ofstream out{outputPath}; - createOutput(doc, out, format, logger); + createOutput(doc, out, format, logger, resourceManager); } else { - createOutput(doc, std::cout, format, logger); + createOutput(doc, std::cout, format, logger, resourceManager); } return SUCCESS; -} +}
\ No newline at end of file diff --git a/src/core/XML.cpp b/src/core/XML.cpp index 0aedbd9..e25d18a 100644 --- a/src/core/XML.cpp +++ b/src/core/XML.cpp @@ -71,7 +71,11 @@ void Element::doSerialize(std::ostream &out, unsigned int tabdepth, bool pretty) out << '\t'; } } - out << '<' << name; + out << '<'; + if(!nspace.empty()){ + out << nspace << ":"; + } + out << name; for (auto &a : attributes) { out << ' ' << a.first << "=\"" << escapePredefinedEntities(a.second) << '\"'; @@ -95,7 +99,11 @@ void Element::doSerialize(std::ostream &out, unsigned int tabdepth, bool pretty) out << '\t'; } } - out << "</" << name << ">"; + out << "</"; + if(!nspace.empty()){ + out << nspace << ":"; + } + out << name << ">"; if (pretty) { out << std::endl; } @@ -125,7 +133,7 @@ namespace RttiTypes .composedOf(&XMLNode) .property("name", {&RttiTypes::String, {[](const xml::Element *obj) { - return Variant::fromString(obj->name); + return Variant::fromString(obj->getName()); }}}); const Rtti XMLText = RttiBuilder<xml::Text>("XMLText").parent(&XMLNode); } diff --git a/src/core/XML.hpp b/src/core/XML.hpp index a1021d3..02b0d89 100644 --- a/src/core/XML.hpp +++ b/src/core/XML.hpp @@ -113,22 +113,19 @@ public: class Element : public Node { private: ManagedVector<Node> children; - -public: - const std::string name; std::map<std::string, std::string> attributes; + const std::string nspace; + const std::string name; - Element(Manager &mgr, Handle<Element> parent, std::string name) - : Node(mgr, parent), children(this), name(std::move(name)) - { - } - +public: Element(Manager &mgr, Handle<Element> parent, std::string name, - std::map<std::string, std::string> attributes) + std::map<std::string, std::string> attributes = {}, + std::string nspace = "") : Node(mgr, parent), children(this), - name(std::move(name)), - attributes(std::move(attributes)) + attributes(std::move(attributes)), + nspace(std::move(nspace)), + name(std::move(name)) { } @@ -151,10 +148,16 @@ public: children.insert(children.end(), c.begin(), c.end()); } + const std::string &getNamespace() const { return nspace; } + + const std::string &getName() const { return name; } + const std::map<std::string, std::string> &getAttributes() const { return attributes; } + + std::map<std::string, std::string> &getAttributes() { return attributes; } }; class Text : public Node { diff --git a/src/core/model/Document.hpp b/src/core/model/Document.hpp index 6903bb3..a5e40ce 100644 --- a/src/core/model/Document.hpp +++ b/src/core/model/Document.hpp @@ -1014,6 +1014,13 @@ public: } /** + * Returns a const reference to the NodeVector of referenced Typesystems. + * + * @return a const reference to the NodeVector of referenced Typesystems. + */ + const NodeVector<Typesystem> getTypesystems() const { return typesystems; } + + /** * Adds a Typesystem reference to this Document. */ void referenceTypesystem(Handle<Typesystem> d) @@ -1031,7 +1038,6 @@ public: typesystems.insert(typesystems.end(), d.begin(), d.end()); } - /** * Returns true if and only if the given StructureNode is part of this * document, meaning that there is a path of parent references in the @@ -1055,4 +1061,4 @@ extern const Rtti Anchor; } } -#endif /* _OUSIA_MODEL_DOCUMENT_HPP_ */ +#endif /* _OUSIA_MODEL_DOCUMENT_HPP_ */
\ No newline at end of file diff --git a/src/plugins/xml/XmlOutput.cpp b/src/plugins/xml/XmlOutput.cpp index e1f1c31..e17b4ab 100644 --- a/src/plugins/xml/XmlOutput.cpp +++ b/src/plugins/xml/XmlOutput.cpp @@ -24,27 +24,76 @@ namespace ousia { namespace xml { +static Rooted<Element> createImportElement(Handle<Element> parent, + Handle<ousia::Node> referenced, + ResourceManager &resourceManager, + const std::string &rel) +{ + SourceLocation loc = referenced->getLocation(); + Resource res = resourceManager.getResource(loc.getSourceId()); + if (!res.isValid()) { + return nullptr; + } + Rooted<Element> import{ + new Element{parent->getManager(), + parent, + "import", + {{"rel", rel}, {"src", res.getLocation()}}}}; + return import; +} + void XmlTransformer::writeXml(Handle<Document> doc, std::ostream &out, - Logger &logger, bool pretty) + Logger &logger, ResourceManager &resourceManager, + 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. + // write imports for all referenced domains. for (auto d : doc->getDomains()) { - Rooted<Element> import{ - new Element{mgr, - document, - "import", - {{"rel", "domain"}, {"src", d->getName() + ".oxm"}}}}; - document->addChild(import); + Rooted<Element> import = + createImportElement(document, d, resourceManager, "domain"); + if (import != nullptr) { + document->addChild(import); + } else { + logger.warning(std::string( + "The location of domain \")" + d->getName() + + "\" could not be retrieved using the given ResourceManager.")); + } + // add the import as namespace information to the document node as well. + document->getAttributes().emplace(std::string("xmlns:") + d->getName(), + import->getAttributes()["src"]); } + // write imports for all referenced typesystems. + for (auto t : doc->getTypesystems()) { + Rooted<Element> import = + createImportElement(document, t, resourceManager, "typesystem"); + if (import != nullptr) { + document->addChild(import); + } else { + logger.warning(std::string( + "The location of typesystem \")" + t->getName() + + "\" could not be retrieved using the given ResourceManager.")); + } + } + // 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\" encoding=\"UTF-8\" standalone=\"yes\"?>", pretty); + document->serialize( + out, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>", + pretty); +} + +static std::string toString(Variant v, bool pretty) +{ + if (v.isString()) { + return v.asString(); + } else { + return VariantWriter::writeJsonToString(v, pretty); + } } Rooted<Element> XmlTransformer::transformStructuredEntity( @@ -64,19 +113,24 @@ Rooted<Element> XmlTransformer::transformStructuredEntity( 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)); + xmlAttrs.emplace(as[a]->getName(), toString(attrArr[a], pretty)); + } + // copy the name attribute. + if (!s->getName().empty()) { + xmlAttrs.emplace("name", s->getName()); } + // create the XML element itself. Rooted<Element> elem{ - new Element{mgr, parent, s->getDescriptor()->getName(), xmlAttrs}}; + new Element{mgr, parent, s->getDescriptor()->getName(), xmlAttrs, + s->getDescriptor()->getParent().cast<Domain>()->getName()}}; // 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. + // if this is not the default field create an intermediate node for it. Rooted<Element> par = elem; if (fieldDesc->getFieldType() != FieldDescriptor::FieldType::TREE && !fieldDesc->isPrimitive()) { @@ -101,24 +155,15 @@ Rooted<Element> XmlTransformer::transformStructuredEntity( } return elem; } + Rooted<Text> XmlTransformer::transformPrimitive(Handle<Element> parent, Handle<DocumentPrimitive> p, Logger &logger, bool pretty) { Manager &mgr = parent->getManager(); // transform the primitive content. - Variant v = p->getContent(); - std::string textcontent = - VariantWriter::writeJsonToString(p->getContent(), pretty); - if (v.isString() && ((textcontent[0] == '\"' && - textcontent[textcontent.size() - 1] == '\"') || - (textcontent[0] == '\'' && - textcontent[textcontent.size() - 1] == '\''))) { - // cut the start and end quote - textcontent = textcontent.substr(1, textcontent.size() - 2); - } - Rooted<Text> text{new Text(mgr, parent, textcontent)}; + Rooted<Text> text{new Text(mgr, parent, toString(p->getContent(), pretty))}; return text; } } -} +}
\ No newline at end of file diff --git a/src/plugins/xml/XmlOutput.hpp b/src/plugins/xml/XmlOutput.hpp index 51d03f9..2bb4190 100644 --- a/src/plugins/xml/XmlOutput.hpp +++ b/src/plugins/xml/XmlOutput.hpp @@ -28,6 +28,7 @@ #include <ostream> +#include <core/resource/ResourceManager.hpp> #include <core/model/Document.hpp> #include <core/XML.hpp> @@ -56,10 +57,12 @@ public: * @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 resMgr is the ResourceManager to locate the domains and + * typesystems that were imported in this document. * @param pretty is a flag that manipulates whether newlines and tabs are * used. */ - void writeXml(Handle<Document> doc, std::ostream &out, Logger &logger, + void writeXml(Handle<Document> doc, std::ostream &out, Logger &logger,ResourceManager& resMgr, bool pretty); }; } |