#ifndef _PLT_XML_HELPER_H_
#define _PLT_XML_HELPER_H_
#include "Neptune.h"
class PLT_XmlAttributeFinder
{
public:
PLT_XmlAttributeFinder(const NPT_XmlElementNode& element,
const char* name,
const char* namespc) :
m_Element(element), m_Name(name), m_Namespace(namespc) {}
bool operator()(const NPT_XmlAttribute* const & attribute) const {
if (attribute->GetName() == m_Name) {
if (m_Namespace) {
const NPT_String& prefix = attribute->GetPrefix();
if (m_Namespace[0] == '\0') {
return prefix.IsEmpty();
} else {
const NPT_String* namespc = m_Element.GetNamespaceUri(prefix);
return namespc && *namespc == m_Namespace;
}
} else {
return true;
}
} else {
return false;
}
}
private:
const NPT_XmlElementNode& m_Element;
const char* m_Name;
const char* m_Namespace;
};
class PLT_XmlHelper
{
public:
static NPT_Result GetChildText(NPT_XmlElementNode* node,
const char* tag,
NPT_String& value,
const char* namespc = "") {
value = "";
if (!node) return NPT_FAILURE;
if (namespc && namespc[0] == '\0') namespc = node->GetNamespace()?node->GetNamespace()->GetChars():NPT_XML_NO_NAMESPACE;
NPT_XmlElementNode* child = node->GetChild(tag, namespc);
if (!child) return NPT_FAILURE;
const NPT_String* text = child->GetText();
value = text?*text:"";
return NPT_SUCCESS;
}
static NPT_Result RemoveAttribute(NPT_XmlElementNode* node,
const char* name,
const char* namespc = "") {
if (!node) return NPT_FAILURE;
if (namespc && namespc[0] == '\0') namespc = node->GetNamespace()?node->GetNamespace()->GetChars():NPT_XML_NO_NAMESPACE;
NPT_List<NPT_XmlAttribute*>::Iterator attribute;
attribute = node->GetAttributes().Find(PLT_XmlAttributeFinder(*node, name, namespc));
if (!attribute) return NPT_FAILURE;
delete *attribute;
NPT_CHECK(node->GetAttributes().Erase(attribute));
return NPT_SUCCESS;
}
static NPT_Result GetAttribute(NPT_XmlElementNode* node,
const char* name,
NPT_XmlAttribute*& attr,
const char* namespc = "") {
attr = NULL;
if (!node) return NPT_FAILURE;
if (namespc && namespc[0] == '\0') namespc = node->GetNamespace()?node->GetNamespace()->GetChars():NPT_XML_NO_NAMESPACE;
NPT_List<NPT_XmlAttribute*>::Iterator attribute;
attribute = node->GetAttributes().Find(PLT_XmlAttributeFinder(*node, name, namespc));
if (!attribute) return NPT_FAILURE;
attr = (*attribute);
return NPT_SUCCESS;
}
static NPT_Result GetAttribute(NPT_XmlElementNode* node,
const char* name,
NPT_String& value,
const char* namespc = "") {
value = "";
NPT_XmlAttribute* attribute = NULL;
NPT_CHECK(GetAttribute(node, name, attribute, namespc));
if (!attribute) return NPT_FAILURE;
value = attribute->GetValue();
return NPT_SUCCESS;
}
static NPT_Result SetAttribute(NPT_XmlElementNode* node,
const char* name,
NPT_String& value,
const char* namespc = "") {
NPT_XmlAttribute* attribute = NULL;
NPT_CHECK(GetAttribute(node, name, attribute, namespc));
if (!attribute) return NPT_FAILURE;
attribute->SetValue(value);
return NPT_SUCCESS;
}
static NPT_Result AddChildText(NPT_XmlElementNode* node,
const char* tag,
const char* text,
const char* prefix = NULL) {
if (!node) return NPT_FAILURE;
NPT_XmlElementNode* child = new NPT_XmlElementNode(prefix, tag);
child->AddText(text);
return node->AddChild(child);
}
static bool IsMatch(const NPT_XmlNode* const & node, const char* tag, const char* namespc_mapped) {
const NPT_XmlElementNode* element = node->AsElementNode();
if (element && element->GetTag() == tag) {
if (namespc_mapped) {
const NPT_String* namespc = element->GetNamespace();
if (namespc) {
return *namespc == namespc_mapped;
} else {
return namespc_mapped[0] == '\0';
}
} else {
return true;
}
}
return false;
}
static NPT_Result GetChildren(NPT_XmlElementNode* node,
NPT_Array<NPT_XmlElementNode*>& children,
const char* tag,
const char* namespc = "") {
if (!node) return NPT_FAILURE;
if (namespc && namespc[0] == '\0') namespc = node->GetNamespace()?node->GetNamespace()->GetChars():NPT_XML_NO_NAMESPACE;
const char* namespc_mapped = (namespc==NULL)?"":(namespc[0]=='*' && namespc[1]=='\0')?NULL:namespc;
NPT_List<NPT_XmlNode*>& allchildren = node->GetChildren();
NPT_List<NPT_XmlNode*>::Iterator child = allchildren.GetFirstItem();
while (child) {
if (IsMatch(*child, tag, namespc_mapped)) {
children.Add((*child)->AsElementNode());
}
++child;
}
return NPT_SUCCESS;
}
static NPT_XmlElementNode* GetChild(NPT_XmlElementNode* node,
const char* tag,
const char* namespc = "") {
if (!node) return NULL;
if (namespc && namespc[0] == '\0') namespc = node->GetNamespace()?node->GetNamespace()->GetChars():NPT_XML_NO_NAMESPACE;
return node->GetChild(tag, namespc);
}
static NPT_Result GetChild(NPT_XmlElementNode* parent,
NPT_XmlElementNode*& child,
NPT_Ordinal n = 0) {
if (!parent) return NPT_FAILURE;
child = NULL;
NPT_List<NPT_XmlNode*>::Iterator children = parent->GetChildren().GetFirstItem();
while (children) {
if ((*children)->AsElementNode() && n-- == 0) {
child = (*children)->AsElementNode();
return NPT_SUCCESS;
}
children++;
}
return NPT_FAILURE;
}
static NPT_Result Serialize(NPT_XmlNode& node, NPT_String& xml, bool add_header = true) {
NPT_XmlWriter writer(0);
NPT_StringOutputStreamReference stream(new NPT_StringOutputStream(&xml));
NPT_CHECK(writer.Serialize(node, *stream, add_header));
return NPT_SUCCESS;
}
static NPT_String Serialize(NPT_XmlNode& node, bool add_header = true) {
NPT_XmlWriter writer(0);
NPT_String xml;
NPT_StringOutputStreamReference stream(new NPT_StringOutputStream(&xml));
if (NPT_FAILED(writer.Serialize(node, *stream, add_header))) {
NPT_Debug("Failed to serialize xml node");
return "";
}
return xml;
}
private:
};
#endif