mirror of
https://projects.vdr-developer.org/git/vdr-plugin-skindesigner.git
synced 2023-10-19 17:58:31 +02:00
190 lines
4.6 KiB
C
190 lines
4.6 KiB
C
#include "helpers.h"
|
|
#include "libxmlwrapper.h"
|
|
|
|
void SkinDesignerXMLErrorHandler (void * userData, xmlErrorPtr error) {
|
|
esyslog("skindesigner: Error in XML: %s", error->message);
|
|
}
|
|
|
|
cLibXMLWrapper::cLibXMLWrapper(void) {
|
|
ctxt = NULL;
|
|
doc = NULL;
|
|
root = NULL;
|
|
|
|
initGenericErrorDefaultFunc(NULL);
|
|
xmlSetStructuredErrorFunc(NULL, SkinDesignerXMLErrorHandler);
|
|
ctxt = xmlNewParserCtxt();
|
|
}
|
|
|
|
cLibXMLWrapper::~cLibXMLWrapper() {
|
|
DeleteDocument();
|
|
xmlFreeParserCtxt(ctxt);
|
|
}
|
|
|
|
void cLibXMLWrapper::InitLibXML() {
|
|
xmlInitParser();
|
|
}
|
|
|
|
void cLibXMLWrapper::CleanupLibXML() {
|
|
xmlCleanupParser();
|
|
}
|
|
|
|
void cLibXMLWrapper::DeleteDocument(void) {
|
|
if (doc) {
|
|
xmlFreeDoc(doc);
|
|
doc = NULL;
|
|
}
|
|
while (!nodeStack.empty())
|
|
nodeStack.pop();
|
|
}
|
|
|
|
bool cLibXMLWrapper::ReadXMLFile(const char *path, bool validate) {
|
|
if (!ctxt) {
|
|
esyslog("skindesigner: Failed to allocate parser context");
|
|
return false;
|
|
}
|
|
if (!FileExists(path)) {
|
|
dsyslog("skindesigner: reading XML Template %s failed", path);
|
|
return false;
|
|
}
|
|
if (validate)
|
|
doc = xmlCtxtReadFile(ctxt, path, NULL, XML_PARSE_NOENT | XML_PARSE_DTDVALID);
|
|
else
|
|
doc = xmlCtxtReadFile(ctxt, path, NULL, XML_PARSE_NOENT);
|
|
|
|
if (!doc) {
|
|
dsyslog("skindesigner: reading XML Template %s failed", path);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool cLibXMLWrapper::SetDocument(void) {
|
|
if (!doc)
|
|
return false;
|
|
root = xmlDocGetRootElement(doc);
|
|
nodeStack.push(root);
|
|
if (root == NULL) {
|
|
esyslog("skindesigner: ERROR: XML File is empty");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool cLibXMLWrapper::Validate(void) {
|
|
if (!ctxt)
|
|
return false;
|
|
if (ctxt->valid == 0) {
|
|
esyslog("skindesigner: Failed to validate XML File");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool cLibXMLWrapper::CheckNodeName(const char *name) {
|
|
if (nodeStack.empty())
|
|
return false;
|
|
xmlNodePtr current = nodeStack.top();
|
|
if (xmlStrcmp(current->name, (const xmlChar *) name)) {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
const char *cLibXMLWrapper::NodeName(void) {
|
|
xmlNodePtr current = nodeStack.top();
|
|
return (const char*)current->name;
|
|
}
|
|
|
|
vector<stringpair> cLibXMLWrapper::ParseAttributes(void) {
|
|
vector<stringpair> attributes;
|
|
if (nodeStack.empty())
|
|
return attributes;
|
|
xmlNodePtr current = nodeStack.top();
|
|
xmlAttrPtr attrPtr = current->properties;
|
|
if (attrPtr == NULL) {
|
|
return attributes;
|
|
}
|
|
while (NULL != attrPtr) {
|
|
string name = (const char*)attrPtr->name;
|
|
xmlChar *value = NULL;
|
|
value = xmlGetProp(current, attrPtr->name);
|
|
if (value)
|
|
attributes.push_back(stringpair((const char*)attrPtr->name, (const char*)value));
|
|
attrPtr = attrPtr->next;
|
|
if (value)
|
|
xmlFree(value);
|
|
}
|
|
return attributes;
|
|
}
|
|
|
|
bool cLibXMLWrapper::LevelDown(void) {
|
|
if (nodeStack.empty())
|
|
return false;
|
|
xmlNodePtr current = nodeStack.top();
|
|
xmlNodePtr child = current->xmlChildrenNode;
|
|
while (child && child->type != XML_ELEMENT_NODE) {
|
|
child = child->next;
|
|
}
|
|
if (!child)
|
|
return false;
|
|
nodeStack.push(child);
|
|
return true;
|
|
}
|
|
|
|
bool cLibXMLWrapper::LevelUp(void) {
|
|
if (nodeStack.size() == 1)
|
|
return false;
|
|
nodeStack.pop();
|
|
return true;
|
|
}
|
|
|
|
bool cLibXMLWrapper::NextNode(void) {
|
|
xmlNodePtr current = nodeStack.top();
|
|
current = current->next;
|
|
while (current && current->type != XML_ELEMENT_NODE) {
|
|
current = current->next;
|
|
}
|
|
if (!current)
|
|
return false;
|
|
nodeStack.pop();
|
|
nodeStack.push(current);
|
|
return true;
|
|
}
|
|
|
|
bool cLibXMLWrapper::GetAttribute(string &name, string &value) {
|
|
bool ok = false;
|
|
xmlNodePtr current = nodeStack.top();
|
|
xmlAttrPtr attr = current->properties;
|
|
if (attr == NULL) {
|
|
return ok;
|
|
}
|
|
xmlChar *xmlValue = NULL;
|
|
while (NULL != attr) {
|
|
if (xmlStrcmp(attr->name, (const xmlChar *) name.c_str())) {
|
|
attr = attr->next;
|
|
continue;
|
|
}
|
|
ok = true;
|
|
xmlValue = xmlGetProp(current, attr->name);
|
|
if (xmlValue) {
|
|
value = (const char*)xmlValue;
|
|
xmlFree(xmlValue);
|
|
}
|
|
break;
|
|
}
|
|
return ok;
|
|
}
|
|
|
|
bool cLibXMLWrapper::GetNodeValue(string &value) {
|
|
xmlChar *val = NULL;
|
|
xmlNodePtr current = nodeStack.top();
|
|
val = xmlNodeListGetString(doc, current->xmlChildrenNode, 1);
|
|
if (val) {
|
|
value = (const char*)val;
|
|
xmlFree(val);
|
|
return true;
|
|
}
|
|
value = "";
|
|
return false;
|
|
}
|