summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2015-02-17 17:15:10 +0100
committerAndreas Stöckel <astoecke@techfak.uni-bielefeld.de>2015-02-17 17:15:10 +0100
commitfcc6a49d8124a0fe1130e242191cc3dc3d701309 (patch)
treea07a96509ff9a415d0f9f1265c754a5af77ba20c
parente8df5877aa9bbeeb34ab0fe13f41d8096919c748 (diff)
parent1bfa8739ed66a25397286ea8be98c3eeb1c695af (diff)
Merge branch 'master' of somweyr.de:ousia
-rw-r--r--src/cli/Main.cpp11
-rw-r--r--src/core/XML.cpp14
-rw-r--r--src/core/XML.hpp25
-rw-r--r--src/core/model/Document.hpp10
-rw-r--r--src/plugins/xml/XmlOutput.cpp95
-rw-r--r--src/plugins/xml/XmlOutput.hpp5
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);
};
}