summaryrefslogtreecommitdiff
path: root/libs/pbd
diff options
context:
space:
mode:
Diffstat (limited to 'libs/pbd')
-rw-r--r--libs/pbd/pbd/xml++.h4
-rw-r--r--libs/pbd/xml++.cc51
2 files changed, 38 insertions, 17 deletions
diff --git a/libs/pbd/pbd/xml++.h b/libs/pbd/pbd/xml++.h
index 6b6ba34f6d..9c3782e3c2 100644
--- a/libs/pbd/pbd/xml++.h
+++ b/libs/pbd/pbd/xml++.h
@@ -60,11 +60,14 @@ public:
const std::string& write_buffer() const;
+ boost::shared_ptr<XMLSharedNodeList> find(const std::string xpath, XMLNode* = 0) const;
+
private:
bool read_internal(bool validate);
std::string _filename;
XMLNode* _root;
+ xmlDocPtr _doc;
int _compression;
};
@@ -90,7 +93,6 @@ public:
XMLNode* add_child_copy(const XMLNode&);
void add_child_nocopy(XMLNode&);
- boost::shared_ptr<XMLSharedNodeList> find(const std::string xpath) const;
std::string attribute_value();
const XMLPropertyList& properties() const { return _proplist; }
diff --git a/libs/pbd/xml++.cc b/libs/pbd/xml++.cc
index b97310eea5..e2ccd67738 100644
--- a/libs/pbd/xml++.cc
+++ b/libs/pbd/xml++.cc
@@ -22,6 +22,7 @@ static XMLSharedNodeList* find_impl(xmlXPathContext* ctxt, const string& xpath);
XMLTree::XMLTree()
: _filename()
, _root(0)
+ , _doc (0)
, _compression(0)
{
}
@@ -29,6 +30,7 @@ XMLTree::XMLTree()
XMLTree::XMLTree(const string& fn, bool validate)
: _filename(fn)
, _root(0)
+ , _doc (0)
, _compression(0)
{
read_internal(validate);
@@ -37,13 +39,19 @@ XMLTree::XMLTree(const string& fn, bool validate)
XMLTree::XMLTree(const XMLTree* from)
: _filename(from->filename())
, _root(new XMLNode(*from->root()))
+ , _doc (xmlCopyDoc (from->_doc, 1))
, _compression(from->compression())
{
+
}
XMLTree::~XMLTree()
{
delete _root;
+
+ if (_doc) {
+ xmlFreeDoc (_doc);
+ }
}
int
@@ -69,8 +77,12 @@ XMLTree::read_internal(bool validate)
delete _root;
_root = 0;
+ if (_doc) {
+ xmlFreeDoc (_doc);
+ _doc = 0;
+ }
+
xmlParserCtxtPtr ctxt = NULL; /* the parser context */
- xmlDocPtr doc; /* the resulting document tree */
xmlKeepBlanksDefault(0);
/* parse the file, activating the DTD validation option */
@@ -80,13 +92,13 @@ XMLTree::read_internal(bool validate)
if (ctxt == NULL) {
return false;
}
- doc = xmlCtxtReadFile(ctxt, _filename.c_str(), NULL, XML_PARSE_DTDVALID);
+ _doc = xmlCtxtReadFile(ctxt, _filename.c_str(), NULL, XML_PARSE_DTDVALID);
} else {
- doc = xmlParseFile(_filename.c_str());
+ _doc = xmlParseFile(_filename.c_str());
}
-
+
/* check if parsing suceeded */
- if (doc == NULL) {
+ if (_doc == NULL) {
if (validate) {
xmlFreeParserCtxt(ctxt);
}
@@ -95,19 +107,17 @@ XMLTree::read_internal(bool validate)
/* check if validation suceeded */
if (validate && ctxt->valid == 0) {
xmlFreeParserCtxt(ctxt);
- xmlFreeDoc(doc);
throw XMLException("Failed to validate document " + _filename);
}
}
- _root = readnode(xmlDocGetRootElement(doc));
+ _root = readnode(xmlDocGetRootElement(_doc));
/* free up the parser context */
if (validate) {
xmlFreeParserCtxt(ctxt);
}
- xmlFreeDoc(doc);
-
+
return true;
}
@@ -342,17 +352,26 @@ XMLNode::add_child_copy(const XMLNode& n)
}
boost::shared_ptr<XMLSharedNodeList>
-XMLNode::find(const string xpath) const
+XMLTree::find(const string xpath, XMLNode* node) const
{
- xmlDocPtr doc = xmlNewDoc((xmlChar*) XML_VERSION);
- writenode(doc, (XMLNode*)this, doc->children, 1);
- xmlXPathContext* ctxt = xmlXPathNewContext(doc);
+ xmlXPathContext* ctxt;
+ xmlDocPtr doc = 0;
+ if (node) {
+ doc = xmlNewDoc((xmlChar*) XML_VERSION);
+ writenode(doc, node, doc->children, 1);
+ ctxt = xmlXPathNewContext(doc);
+ } else {
+ ctxt = xmlXPathNewContext(_doc);
+ }
+
boost::shared_ptr<XMLSharedNodeList> result =
- boost::shared_ptr<XMLSharedNodeList>(find_impl(ctxt, xpath));
-
+ boost::shared_ptr<XMLSharedNodeList>(find_impl(ctxt, xpath));
+
xmlXPathFreeContext(ctxt);
- xmlFreeDoc(doc);
+ if (doc) {
+ xmlFreeDoc (doc);
+ }
return result;
}