[libxml++] Parser: Add [set|get]_include_default_attributes().
- From: Kjell Ahlstedt <kjellahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libxml++] Parser: Add [set|get]_include_default_attributes().
- Date: Fri, 2 Aug 2013 13:21:50 +0000 (UTC)
commit 06997287505cb50ec053b216bdc5912e93770a2d
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date: Fri Aug 2 15:18:26 2013 +0200
Parser: Add [set|get]_include_default_attributes().
* libxml++/parsers/parser.[h|cc]: Add [set|get]_include_default_attributes()
and [set|get]_parser_options().
* examples/dom_parser/main.cc: Add command option -a for testing
Parser::set_include_default_attributes().
* examples/dom_read_write/example.dtd:
* examples/dom_read_write/example.xml: Add an attribute with default value.
* examples/dom_read_write/main.cc: Add an optional call to
Parser::set_include_default_attributes(). Bug #701674.
examples/dom_parser/main.cc | 27 +++++++++----
examples/dom_read_write/example.dtd | 1 +
examples/dom_read_write/example.xml | 2 +-
examples/dom_read_write/main.cc | 21 ++++++++++-
libxml++/parsers/parser.cc | 70 +++++++++++++++++++++++++++++------
libxml++/parsers/parser.h | 52 +++++++++++++++++++++++++-
6 files changed, 149 insertions(+), 24 deletions(-)
---
diff --git a/examples/dom_parser/main.cc b/examples/dom_parser/main.cc
index 81e32b1..d8dd8c8 100644
--- a/examples/dom_parser/main.cc
+++ b/examples/dom_parser/main.cc
@@ -93,7 +93,12 @@ void print_node(const xmlpp::Node* node, unsigned int indentation = 0)
const xmlpp::Attribute* attribute = nodeElement->get_attribute("title");
if(attribute)
{
- std::cout << indent << "title = " << CatchConvertError(attribute->get_value()) << std::endl;
+ std::cout << indent;
+ if (dynamic_cast<const xmlpp::AttributeNode*>(attribute))
+ std::cout << "AttributeNode ";
+ else if (dynamic_cast<const xmlpp::AttributeDeclaration*>(attribute))
+ std::cout << "AttributeDeclaration ";
+ std::cout << "title = " << CatchConvertError(attribute->get_value()) << std::endl;
}
}
@@ -118,6 +123,7 @@ int main(int argc, char* argv[])
bool set_throw_messages = false;
bool throw_messages = false;
bool substitute_entities = true;
+ bool include_default_attributes = false;
int argi = 1;
while (argc > argi && *argv[argi] == '-') // option
@@ -128,22 +134,26 @@ int main(int argc, char* argv[])
validate = true;
break;
case 't':
- set_throw_messages = true;
- throw_messages = true;
- break;
+ set_throw_messages = true;
+ throw_messages = true;
+ break;
case 'e':
- set_throw_messages = true;
- throw_messages = false;
- break;
+ set_throw_messages = true;
+ throw_messages = false;
+ break;
case 'E':
substitute_entities = false;
break;
+ case 'a':
+ include_default_attributes = true;
+ break;
default:
std::cout << "Usage: " << argv[0] << " [-v] [-t] [-e] [filename]" << std::endl
<< " -v Validate" << std::endl
<< " -t Throw messages in an exception" << std::endl
<< " -e Write messages to stderr" << std::endl
- << " -E Do not substitute entities" << std::endl;
+ << " -E Do not substitute entities" << std::endl
+ << " -a Include default attributes in the node tree" << std::endl;
return EXIT_FAILURE;
}
argi++;
@@ -163,6 +173,7 @@ int main(int argc, char* argv[])
parser.set_throw_messages(throw_messages);
//We can have the text resolved/unescaped automatically.
parser.set_substitute_entities(substitute_entities);
+ parser.set_include_default_attributes(include_default_attributes);
parser.parse_file(filepath);
if(parser)
{
diff --git a/examples/dom_read_write/example.dtd b/examples/dom_read_write/example.dtd
index 925f074..2b09522 100644
--- a/examples/dom_read_write/example.dtd
+++ b/examples/dom_read_write/example.dtd
@@ -8,6 +8,7 @@ DTD for libxml++ example.
<!ELEMENT examplechild (child_of_child)+ >
<!ATTLIST examplechild
id CDATA #REQUIRED
+ title CDATA "No title"
<!ELEMENT child_of_child EMPTY >
diff --git a/examples/dom_read_write/example.xml b/examples/dom_read_write/example.xml
index 95c9305..7037f79 100644
--- a/examples/dom_read_write/example.xml
+++ b/examples/dom_read_write/example.xml
@@ -2,7 +2,7 @@
<!DOCTYPE example PUBLIC "" "example.dtd">
<example>
- <examplechild id="1">
+ <examplechild id="1" title="First child element">
<child_of_child/>
</examplechild>
<examplechild id="2">
diff --git a/examples/dom_read_write/main.cc b/examples/dom_read_write/main.cc
index bf7f3fe..9dc4f8c 100644
--- a/examples/dom_read_write/main.cc
+++ b/examples/dom_read_write/main.cc
@@ -35,7 +35,9 @@ main(int argc, char* argv[])
std::locale::global(std::locale(""));
//Parse command-line arguments:
- std::string filepath_in, filepath_out;
+ std::string filepath_in;
+ std::string filepath_out;
+ std::string filepath_out2; // With default attributes
if(argc > 1 )
filepath_in = argv[1]; //Allow the user to specify a different XML file to parse.
else
@@ -46,6 +48,10 @@ main(int argc, char* argv[])
else
filepath_out = "example_output.xml";
+ //Allow the user to specify an extra output file with set_include_default_attributes(true).
+ if(argc > 3 )
+ filepath_out2 = argv[3];
+
try
{
xmlpp::DomParser parser;
@@ -58,6 +64,19 @@ main(int argc, char* argv[])
if(document)
document->write_to_file(filepath_out);
}
+
+ if (!filepath_out2.empty())
+ {
+ parser.set_include_default_attributes();
+ parser.parse_file(filepath_in);
+ if(parser)
+ {
+ //Write it out again.
+ xmlpp::Document* document = parser.get_document();
+ if(document)
+ document->write_to_file(filepath_out2);
+ }
+ }
}
catch(const std::exception& ex)
{
diff --git a/libxml++/parsers/parser.cc b/libxml++/parsers/parser.cc
index 96250a5..e32567e 100644
--- a/libxml++/parsers/parser.cc
+++ b/libxml++/parsers/parser.cc
@@ -20,14 +20,19 @@ namespace // anonymous
// because it would break ABI.
struct ExtraParserData
{
- // Strange default values chosen for backward compatibility.
+ // Strange default values for throw_*_messages chosen for backward compatibility.
ExtraParserData()
- : throw_parser_messages_(false), throw_validity_messages_(true)
+ : throw_parser_messages_(false), throw_validity_messages_(true),
+ include_default_attributes_(false), set_options_(0), clear_options_(0)
{}
+
Glib::ustring parser_error_;
Glib::ustring parser_warning_;
bool throw_parser_messages_;
bool throw_validity_messages_;
+ bool include_default_attributes_;
+ int set_options_;
+ int clear_options_;
};
std::map<const xmlpp::Parser*, ExtraParserData> extra_parser_data;
@@ -99,15 +104,54 @@ bool Parser::get_throw_messages() const
return extra_parser_data[this].throw_parser_messages_;
}
+void Parser::set_include_default_attributes(bool val)
+{
+ Glib::Threads::Mutex::Lock lock(extra_parser_data_mutex);
+ extra_parser_data[this].include_default_attributes_ = val;
+}
+
+bool Parser::get_include_default_attributes()
+{
+ Glib::Threads::Mutex::Lock lock(extra_parser_data_mutex);
+ return extra_parser_data[this].include_default_attributes_;
+}
+
+void Parser::set_parser_options(int set_options, int clear_options)
+{
+ Glib::Threads::Mutex::Lock lock(extra_parser_data_mutex);
+ extra_parser_data[this].set_options_ = set_options;
+ extra_parser_data[this].clear_options_ = clear_options;
+}
+
+void Parser::get_parser_options(int& set_options, int& clear_options)
+{
+ Glib::Threads::Mutex::Lock lock(extra_parser_data_mutex);
+ set_options = extra_parser_data[this].set_options_;
+ clear_options = extra_parser_data[this].clear_options_;
+}
+
void Parser::initialize_context()
{
+ Glib::Threads::Mutex::Lock lock(extra_parser_data_mutex);
+
+ //Clear these temporary buffers:
+ extra_parser_data[this].parser_error_.erase();
+ extra_parser_data[this].parser_warning_.erase();
+ validate_error_.erase();
+ validate_warning_.erase();
+
+ // Take a copy of the extra data, so we don't have to access
+ // the extra_parser_data map more than necessary.
+ const ExtraParserData extra_parser_data_this = extra_parser_data[this];
+ lock.release();
+
//Disactivate any non-standards-compliant libxml1 features.
//These are disactivated by default, but if we don't deactivate them for each context
//then some other code which uses a global function, such as xmlKeepBlanksDefault(),
// could cause this to use the wrong settings:
context_->linenumbers = 1; // TRUE - This is the default anyway.
- //Turn on/off validation and entity substitution.
+ //Turn on/off validation, entity substitution and default attribute inclusion.
int options = context_->options;
if (validate_)
options |= XML_PARSE_DTDVALID;
@@ -119,10 +163,18 @@ void Parser::initialize_context()
else
options &= ~XML_PARSE_NOENT;
+ if (extra_parser_data_this.include_default_attributes_)
+ options |= XML_PARSE_DTDATTR;
+ else
+ options &= ~XML_PARSE_DTDATTR;
+
+ //Turn on/off any parser options.
+ options |= extra_parser_data_this.set_options_;
+ options &= ~extra_parser_data_this.clear_options_;
+
xmlCtxtUseOptions(context_, options);
- Glib::Threads::Mutex::Lock lock(extra_parser_data_mutex);
- if (context_->sax && extra_parser_data[this].throw_parser_messages_)
+ if (context_->sax && extra_parser_data_this.throw_parser_messages_)
{
//Tell the parser context about the callbacks.
context_->sax->fatalError = &callback_parser_error;
@@ -130,7 +182,7 @@ void Parser::initialize_context()
context_->sax->warning = &callback_parser_warning;
}
- if (extra_parser_data[this].throw_validity_messages_)
+ if (extra_parser_data_this.throw_validity_messages_)
{
//Tell the validity context about the callbacks:
//(These are only called if validation is on - see above)
@@ -140,12 +192,6 @@ void Parser::initialize_context()
//Allow the callback_validity_*() methods to retrieve the C++ instance:
context_->_private = this;
-
- //Clear these temporary buffers too:
- extra_parser_data[this].parser_error_.erase();
- extra_parser_data[this].parser_warning_.erase();
- validate_error_.erase();
- validate_warning_.erase();
}
void Parser::release_underlying()
diff --git a/libxml++/parsers/parser.h b/libxml++/parsers/parser.h
index f2c2f3f..66297de 100644
--- a/libxml++/parsers/parser.h
+++ b/libxml++/parsers/parser.h
@@ -42,7 +42,7 @@ public:
*/
virtual void set_validate(bool val = true);
- /** See set_validate()
+ /** See set_validate().
* @returns Whether the parser will validate the XML file.
*/
virtual bool get_validate() const;
@@ -83,7 +83,51 @@ public:
* The default with only validation messages thrown is returned as false.
*/
bool get_throw_messages() const;
-
+
+ /** Set whether default attribute values from the DTD shall be included in the node tree.
+ * If set, attributes not assigned a value in the XML file, but with a default value
+ * in the DTD file, will be included in the node tree that the parser creates.
+ * These attributes will be represented by AttributeNode instances (not AttributeDeclaration
+ * instances), just like attributes which are assigned a value in the XML file.
+ *
+ * @newin{2,38}
+ *
+ * @param val Whether attributes with default values will be included in the node tree.
+ */
+ void set_include_default_attributes(bool val = true);
+
+ /** See set_include_default_attributes().
+ *
+ * @newin{2,38}
+ *
+ * @returns Whether attributes with default values will be included in the node tree.
+ */
+ bool get_include_default_attributes();
+
+ /** Set and/or clear parser option flags.
+ * See the libxml2 documentation, enum xmlParserOption, for a list of parser options.
+ * This method overrides other methods that set parser options, such as set_validate(),
+ * set_substitute_entities() and set_include_default_attributes(). Use set_parser_options()
+ * only if no other method can set the parser options you want.
+ *
+ * @newin{2,38}
+ *
+ * @param set_options Set bits correspond to flags that shall be set during parsing.
+ * @param clear_options Set bits correspond to flags that shall be cleared during parsing.
+ * Bits that are set in neither @a set_options nor @a clear_options are not affected.
+ */
+ void set_parser_options(int set_options = 0, int clear_options = 0);
+
+ /** See set_parser_options().
+ *
+ * @newin{2,38}
+ *
+ * @param [out] set_options Set bits correspond to flags that shall be set during parsing.
+ * @param [out] clear_options Set bits correspond to flags that shall be cleared during parsing.
+ * Bits that are set in neither @a set_options nor @a clear_options are not affected.
+ */
+ void get_parser_options(int& set_options, int& clear_options);
+
/** Parse an XML document from a file.
* @throw exception
* @param filename The path to the file.
@@ -149,6 +193,10 @@ protected:
bool validate_;
bool substitute_entities_;
+ //TODO: In a future ABI-break, add these members.
+ //bool include_default_attributes_;
+ //int set_options_;
+ //int clear_options_;
};
} // namespace xmlpp
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]