00001 #include "xml_tree_writer.h"
00002
00003 #include <cassert>
00004 #include <ostream>
00005 #include <vector>
00006 #include <string>
00007
00008 #include "SyntaxTree.h"
00009 #include "XmlTree.h"
00010
00011
00012 namespace MosesTraining {
00013 namespace Syntax {
00014
00015 void XmlTreeWriter::Write(const SyntaxTree &tree) const {
00016 assert(!tree.IsLeaf());
00017
00018
00019 out_ << "<tree label=\"" << Escape(tree.value().label) << "\"";
00020 for (SyntaxNode::AttributeMap::const_iterator
00021 p = tree.value().attributes.begin();
00022 p != tree.value().attributes.end(); ++p) {
00023 if (p->first != "label") {
00024 out_ << " " << p->first << "=\"" << p->second << "\"";
00025 }
00026 }
00027 out_ << ">";
00028
00029
00030 for (std::vector<SyntaxTree *>::const_iterator p = tree.children().begin();
00031 p != tree.children().end(); ++p) {
00032 SyntaxTree &child = **p;
00033 if (child.IsLeaf()) {
00034 out_ << " " << Escape(child.value().label);
00035 } else {
00036 out_ << " ";
00037 Write(child);
00038 }
00039 }
00040
00041
00042 out_ << " </tree>";
00043
00044 if (tree.parent() == 0) {
00045 out_ << std::endl;
00046 }
00047 }
00048
00049
00050 std::string XmlTreeWriter::Escape(const std::string &s) const {
00051 if (!escape_) {
00052 return s;
00053 }
00054 std::string t;
00055 std::size_t len = s.size();
00056 t.reserve(len);
00057 for (std::size_t i = 0; i < len; ++i) {
00058 if (s[i] == '<') {
00059 t += "<";
00060 } else if (s[i] == '>') {
00061 t += ">";
00062 } else if (s[i] == '[') {
00063 t += "[";
00064 } else if (s[i] == ']') {
00065 t += "]";
00066 } else if (s[i] == '|') {
00067 t += "|";
00068 } else if (s[i] == '&') {
00069 t += "&";
00070 } else if (s[i] == '\'') {
00071 t += "'";
00072 } else if (s[i] == '"') {
00073 t += """;
00074 } else {
00075 t += s[i];
00076 }
00077 }
00078 return t;
00079 }
00080
00081 }
00082 }