extLst element round tripped

This commit is contained in:
Crzyrndm 2018-06-25 23:12:35 +12:00
parent 4ff68319b0
commit 3d3a59012a
3 changed files with 31 additions and 13 deletions

View File

@ -47,7 +47,7 @@ public:
struct ext struct ext
{ {
public: public:
ext(xml::parser &parser); ext(xml::parser &parser, const std::string& ns);
ext(const uri& ID, const std::string& serialised); ext(const uri& ID, const std::string& serialised);
void serialise(xml::serializer &serialiser, const std::string& ns); void serialise(xml::serializer &serialiser, const std::string& ns);
@ -55,7 +55,7 @@ public:
std::string serialised_value_; std::string serialised_value_;
}; };
ext_list() = default; // default ctor required by xlnt::optional ext_list() = default; // default ctor required by xlnt::optional
explicit ext_list(xml::parser &parser); explicit ext_list(xml::parser &parser, const std::string& ns);
void serialize(xml::serializer &serialiser, const std::string& ns); void serialize(xml::serializer &serialiser, const std::string& ns);
void add_extension(const uri &ID, const std::string &element); void add_extension(const uri &ID, const std::string &element);

View File

@ -1190,7 +1190,7 @@ worksheet xlsx_consumer::read_worksheet_end(const std::string &rel_id)
} }
else if (current_worksheet_element == qn("spreadsheetml", "extLst")) else if (current_worksheet_element == qn("spreadsheetml", "extLst"))
{ {
ext_list extensions(parser()); ext_list extensions(parser(), current_worksheet_element.namespace_());
ws.d_->extension_list_.set(extensions); ws.d_->extension_list_.set(extensions);
} }
else else

View File

@ -17,12 +17,25 @@ namespace {
case xml::parser::start_element: case xml::parser::start_element:
{ {
++nest_level; ++nest_level;
s.start_element(p.name()); auto attribs = p.attribute_map();
if (nest_level == 1) if (nest_level == 1)
{ {
ext_uri = p.attribute("uri"); s.start_element(p.qname());
ext_uri = xlnt::uri(attribs.at(xml::qname("uri")).value);
} }
for (auto &ele : p.attribute_map()) else
{
s.start_element(p.qname());
}
auto current_ns = p.namespace_();
p.peek(); // to look into the new namespace
auto new_ns = p.namespace_(); // only before attributes?
if (new_ns != current_ns)
{
auto pref = p.prefix();
s.namespace_decl(new_ns, pref);
}
for (auto &ele : attribs)
{ {
s.attribute(ele.first.string(), ele.second.value); s.attribute(ele.first.string(), ele.second.value);
} }
@ -62,11 +75,14 @@ namespace {
namespace xlnt { namespace xlnt {
ext_list::ext::ext(xml::parser &parser) ext_list::ext::ext(xml::parser &parser, const std::string& ns)
{ {
std::ostringstream serialisation_stream; std::ostringstream serialisation_stream;
xml::serializer s(serialisation_stream, "", 0); xml::serializer s(serialisation_stream, "", 0);
s.start_element(xml::qname(ns, "wrap")); // wrapper for the xmlns declaration
s.namespace_decl(ns, "");
extension_ID_ = roundtrip(parser, s); extension_ID_ = roundtrip(parser, s);
s.end_element(xml::qname(ns, "wrap"));
serialised_value_ = serialisation_stream.str(); serialised_value_ = serialisation_stream.str();
} }
@ -74,29 +90,31 @@ ext_list::ext::ext(const uri &ID, const std::string &serialised)
: extension_ID_(ID), serialised_value_(serialised) : extension_ID_(ID), serialised_value_(serialised)
{} {}
void ext_list::ext::serialise(xml::serializer &serialiser, const std::string&) void ext_list::ext::serialise(xml::serializer &serialiser, const std::string& ns)
{ {
std::istringstream ser(serialised_value_); std::istringstream ser(serialised_value_);
xml::parser p(ser, "", xml::parser::receive_default); xml::parser p(ser, "", xml::parser::receive_default);
p.next_expect(xml::parser::event_type::start_element, xml::qname(ns, "wrap"));
roundtrip(p, serialiser); roundtrip(p, serialiser);
p.next_expect(xml::parser::event_type::end_element, xml::qname(ns, "wrap"));
} }
ext_list::ext_list(xml::parser &parser) ext_list::ext_list(xml::parser &parser, const std::string& ns)
{ {
// begin with the start element already parsed // begin with the start element already parsed
while (parser.peek() == xml::parser::start_element) while (parser.peek() == xml::parser::start_element)
{ {
extensions_.push_back(ext(parser)); extensions_.push_back(ext(parser, ns));
} }
// end without parsing the end element // end without parsing the end element
} }
void ext_list::serialize(xml::serializer &serialiser, const std::string& namesp) void ext_list::serialize(xml::serializer &serialiser, const std::string& ns)
{ {
serialiser.start_element(namesp, "extLst"); serialiser.start_element(ns, "extLst");
for (auto &ext : extensions_) for (auto &ext : extensions_)
{ {
ext.serialise(serialiser, namesp); ext.serialise(serialiser, ns);
} }
serialiser.end_element(); serialiser.end_element();
} }