A sample demonstrating reading and writing of XML data that includes namespace prefixes and comments.
It reads and writes XML that includes namespaces. To include the names of the namespace prefixes in the binary XML, you must change the XmlStreamWriterSettings
defaults and create a XmlStreamWriter
.
#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