#include <string>
using nlib_ns::exi::ExiAllocator;
using nlib_ns::exi::ExiAllocatorEx;
using nlib_ns::exi::XmlStreamReader;
using nlib_ns::exi::XmlStreamReaderSettings;
using nlib_ns::exi::XmlStreamWriter;
using nlib_ns::exi::XmlStreamWriterSettings;
#define N(x) NLIB_EXI_LITERAL(x)
#define M(x) NLIB_EXI_UTF8(x)
const int kBufSize = 1024 * 64;
unsigned char g_readerbuf[kBufSize];
unsigned char g_writerbuf[kBufSize];
const int kDataBufSize = 1024;
unsigned char g_data_buf[kDataBufSize];
bool WriteXml() {
ExiAllocatorEx al;
if (al.Init(g_writerbuf, kBufSize) != 0) return false;
MemoryOutputStream os(g_data_buf, kDataBufSize);
XmlStreamWriterSettings settings;
#ifndef USE_TEXT
settings.encodeCookie = true;
settings.encodeOptions = true;
settings.preserve.comments = true;
settings.preserve.prefixes = true;
#else
#endif
UniquePtr<XmlStreamWriter> w(XmlStreamWriter::Create(&os, settings, al));
if (!w.get()) return false;
w->WriteStartDocument();
w->WriteStartElement(N("root"));
{
w->WriteStartElement(N("e"));
w->WriteAttribute(N("attr0"), N("value0"));
w->WriteAttribute(N(""), N(""), N("attr1"), N("value1"));
w->WriteAttribute(N("pfx"), N("http://example.com"), N("attr2"), N("value2"));
w->WriteEndElement();
}
{
w->WriteComment(N("comment"));
}
{
w->WriteStartElement(N("pfx"), N("http://example.com"), N("e"));
w->WriteEmptyElement(N("pfx"), N("http://example.com"), N("c"));
w->WriteEmptyElement(N("c"));
w->WriteEmptyElement(N(""), N("http://example.com"), N("c"));
w->WriteEmptyElement(N("pfx"), N("http://example.com/2"), N("c"));
w->WriteEndElement();
}
{
w->WriteStartElement(N(""), N("http://example.com/defaultns"), N("e"));
w->WriteAttribute(N("att"), N("value"));
w->WriteEmptyElement(N(""), N("http://example.com/defaultns"), N("c"));
w->WriteEmptyElement(N("c"));
w->WriteEndElement();
}
{
w->WriteStartElement(N("pfx"), N("http://example.com"), N("e"));
w->WriteNamespace(N("pfx2"), N("http://example.com/2"));
w->WriteEmptyElement(N("pfx2"), N("http://example.com/2"), N("e"));
w->WriteEndElement();
}
w->WriteEndElement();
w->WriteEndDocument();
w->Close();
return !!*w;
}
class SimplePrinter {
int indent;
XmlStreamReader* r;
ConsoleOutputStream out_;
TextWriter out;
public:
explicit SimplePrinter(XmlStreamReader* reader) : indent(0), r(reader) {
out.Init();
out.Open(&out_);
}
void Indent() {
for (int i = 0; i < indent; ++i) {
out.Write(" ");
}
}
void Print();
};
void SimplePrinter::Print() {
while (r->HasNext()) {
switch (r->Next()) {
case XmlStreamReader::START_ELEMENT: {
Indent();
prefix = r->GetPrefix();
uri = r->GetNamespaceUri();
if (uri[0] == '\0')
out.WriteFormat("<%s", M(r->GetLocalName()));
else
out.WriteFormat("<%s(%s):%s", M(prefix), M(r->GetNamespaceUri()),
M(r->GetLocalName()));
{
size_t num_ns = r->GetNamespaceCount();
size_t i;
for (i = 0; i < num_ns; ++i) {
prefix = r->GetNamespacePrefix(i);
if (prefix[0] == '\0') {
out.WriteFormat(" xmlns=\"%s\"", M(r->GetNamespaceUri(i)));
} else {
out.WriteFormat(" xmlns:%s=\"%s\"", M(prefix), M(r->GetNamespaceUri(i)));
}
}
}
{
size_t num_att = r->GetAttributeCount();
size_t i;
for (i = 0; i < num_att; ++i) {
prefix = r->GetAttributePrefix(i);
uri = r->GetAttributeNamespaceUri(i);
if (uri[0] == '\0') {
out.WriteFormat(" %s=\"%s\"", M(r->GetAttributeLocalName(i)),
M(r->GetAttributeValue(i)));
} else {
out.WriteFormat(" %s(%s):%s=\"%s\"", M(prefix), M(uri),
M(r->GetAttributeLocalName(i)), M(r->GetAttributeValue(i)));
}
}
}
out.Write(">\n");
++indent;
} break;
case XmlStreamReader::END_ELEMENT: {
--indent;
Indent();
prefix = r->GetPrefix();
if (prefix[0] == '\0') {
out.WriteFormat("</%s>\n", M(r->GetLocalName()));
} else {
out.WriteFormat("</%s:%s>\n", M(prefix), M(r->GetLocalName()));
}
} break;
case XmlStreamReader::COMMENT:
Indent();
out.WriteFormat("<!--%s-->\n", M(r->GetText()));
break;
default:
break;
}
}
}
bool ReadXml() {
ExiAllocatorEx al;
if (al.Init(g_readerbuf, kBufSize) != 0) return false;
MemoryInputStream is(g_data_buf, kDataBufSize);
XmlStreamReaderSettings settings;
#ifndef USE_TEXT
#else
#endif
UniquePtr<XmlStreamReader> r(XmlStreamReader::Create(&is, settings, al));
if (!r.get()) return false;
SimplePrinter printer(r.get());
printer.Print();
return !!*r;
}
bool SampleMain(int, char**) {
NLIB_ASSERT(!ExiAllocator::GetAllocator());
nlib_printf(
"Write and Read an XML with xmlnamespace\n\n");
bool result = WriteXml() && ReadXml();
NLIB_ASSERT(!ExiAllocator::GetAllocator());
return result;
}
NLIB_MAINFUNC