[libxml++] Add XInclude processing.



commit 87e6b75f8ee8408adee9226a988ca8b0c3766b7e
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date:   Tue Aug 28 17:08:19 2012 +0200

    Add XInclude processing.
    
    * Makefile.am: Add XIncludeStart and XIncludeEnd nodes.
    * examples/Makefile.am: Add dom_xinclude example.
    * examples/README: Add dom_xinclude example and other missing examples.
    * examples/dom_xinclude/example.xml:
    * examples/dom_xinclude/include1.txt:
    * examples/dom_xinclude/include2.xml:
    * examples/dom_xinclude/main.cc: New files.
    * libxml++/document.[h|cc]: Add process_xinclude().
    * libxml++/libxml++.h: Add new header files.
    * libxml++/nodes/node.cc: create_wrapper(): Create XIncludeStart and
    XIncludeEnd nodes.
    * libxml++/nodes/xincludeend.[h|cc]:
    * libxml++/nodes/xincludestart.[h|cc]: New files.
    * .gitignore: Ignore /examples/dom_xinclude/dom_xinclude. Bug #338521.

 .gitignore                         |    1 +
 ChangeLog                          |   19 ++++
 Makefile.am                        |    6 +-
 examples/Makefile.am               |    6 +
 examples/README                    |   31 ++++--
 examples/dom_xinclude/example.xml  |    7 ++
 examples/dom_xinclude/include1.txt |    1 +
 examples/dom_xinclude/include2.xml |    4 +
 examples/dom_xinclude/main.cc      |  198 ++++++++++++++++++++++++++++++++++++
 libxml++/document.cc               |  151 +++++++++++++++++++++++++++
 libxml++/document.h                |   16 +++
 libxml++/libxml++.h                |    4 +
 libxml++/nodes/node.cc             |   12 ++
 libxml++/nodes/xincludeend.cc      |   32 ++++++
 libxml++/nodes/xincludeend.h       |   41 ++++++++
 libxml++/nodes/xincludestart.cc    |   32 ++++++
 libxml++/nodes/xincludestart.h     |   41 ++++++++
 17 files changed, 592 insertions(+), 10 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 507deb8..aea0202 100644
--- a/.gitignore
+++ b/.gitignore
@@ -50,6 +50,7 @@ stamp-h?
 /examples/dom_parser_raw/dom_parser_raw
 /examples/dom_read_write/dom_read_write
 /examples/dom_read_write/example_output.xml
+/examples/dom_xinclude/dom_xinclude
 /examples/dom_xpath/dom_xpath
 /examples/dtdvalidation/dtdvalidation
 /examples/import_node/import_node
diff --git a/ChangeLog b/ChangeLog
index 5aa8735..495dec2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,24 @@
 2012-08-28  Kjell Ahlstedt  <kjell ahlstedt bredband net>
 
+	Add XInclude processing.
+
+	* Makefile.am: Add XIncludeStart and XIncludeEnd nodes.
+	* examples/Makefile.am: Add dom_xinclude example.
+	* examples/README: Add dom_xinclude example and other missing examples.
+	* examples/dom_xinclude/example.xml:
+	* examples/dom_xinclude/include1.txt:
+	* examples/dom_xinclude/include2.xml:
+	* examples/dom_xinclude/main.cc: New files.
+	* libxml++/document.[h|cc]: Add process_xinclude().
+	* libxml++/libxml++.h: Add new header files.
+	* libxml++/nodes/node.cc: create_wrapper(): Create XIncludeStart and
+	XIncludeEnd nodes.
+	* libxml++/nodes/xincludeend.[h|cc]:
+	* libxml++/nodes/xincludestart.[h|cc]: New files.
+	* .gitignore: Ignore /examples/dom_xinclude/dom_xinclude. Bug #338521.
+
+2012-08-28  Kjell Ahlstedt  <kjell ahlstedt bredband net>
+
 	Parser: Make it thread-safe.
 
 	* configure.ac: Require glibmm-2.4 >= 2.32.0.
diff --git a/Makefile.am b/Makefile.am
index 17e63e5..be64b57 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -44,7 +44,9 @@ h_nodes_sources_public = libxml++/nodes/cdatanode.h \
 	libxml++/nodes/entityreference.h \
 	libxml++/nodes/node.h \
 	libxml++/nodes/processinginstructionnode.h \
-	libxml++/nodes/textnode.h
+	libxml++/nodes/textnode.h \
+	libxml++/nodes/xincludeend.h \
+	libxml++/nodes/xincludestart.h
 h_parsers_sources_public = libxml++/parsers/parser.h \
 	libxml++/parsers/saxparser.h \
 	libxml++/parsers/domparser.h \
@@ -84,6 +86,8 @@ cc_sources = libxml++/attribute.cc \
 	libxml++/nodes/node.cc \
 	libxml++/nodes/processinginstructionnode.cc \
 	libxml++/nodes/textnode.cc \
+	libxml++/nodes/xincludeend.cc \
+	libxml++/nodes/xincludestart.cc \
 	libxml++/parsers/parser.cc \
 	libxml++/parsers/saxparser.cc \
 	libxml++/parsers/domparser.cc \
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 63e873e..1f43f08 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -25,6 +25,7 @@ check_PROGRAMS = \
   dom_parser/dom_parser \
   dom_parser_raw/dom_parser_raw \
   dom_read_write/dom_read_write \
+  dom_xinclude/dom_xinclude \
   dom_xpath/dom_xpath \
   dtdvalidation/dtdvalidation \
   import_node/import_node \
@@ -49,6 +50,8 @@ dom_parser_raw_dom_parser_raw_SOURCES = \
   dom_parser_raw/main.cc
 dom_read_write_dom_read_write_SOURCES = \
   dom_read_write/main.cc
+dom_xinclude_dom_xinclude_SOURCES = \
+  dom_xinclude/main.cc
 dom_xpath_dom_xpath_SOURCES = \
   dom_xpath/main.cc
 dtdvalidation_dtdvalidation_SOURCES = \
@@ -96,6 +99,9 @@ dist_noinst_DATA = \
   dom_read_write/README \
   dom_read_write/example.xml \
   dom_read_write/example.dtd \
+  dom_xinclude/example.xml \
+  dom_xinclude/include1.txt \
+  dom_xinclude/include2.xml \
   dom_xpath/example.xml \
   dtdvalidation/example.dtd \
   import_node/example1.xml \
diff --git a/examples/README b/examples/README
index c72a324..573e64d 100644
--- a/examples/README
+++ b/examples/README
@@ -1,23 +1,36 @@
-Examples: Enable building with the --enable-examples argument to configure
+Examples: Built and executed by "make check"
 
 Simple parsing examples:
   dom_parser - Shows how to parse an XML Document with the DOM parser.
   sax_parser - Shows how to parse an XML Document with the SAX parser.
+  textreader - Shows how to parse an XML Document with the TextReader parser.
 
-Building XML doxuments:
+Building XML documents:
   dom_build - Shows how to build an XML document using the DOM Parser API.
-  sax_parser_build_dom - Shows how to parse an XML document with the SAX parser, building a separate custom DOM as you parse.
-  dom_read_write: Reads an XML document with the DOM parser and writes it again. The output should be the same as the input.
+  sax_parser_build_dom - Shows how to parse an XML document with the SAX parser,
+                         building a separate custom DOM as you parse.
+  dom_read_write: Reads an XML document with the DOM parser and writes it again.
+                  The output should be the same as the input.
   import_node: Adds a part of an XML document to another, using the DOM parser.
+  dom_xinclude: Adds the contents of other files to an XML document, using the
+                DOM parser and XInclude processing.
   
 Entity parsing:
-  dom_parser_entities: Shows how to detect entity references when using the DOM parser.
-  sax_parser_entities: Shows how to detect (and maybe resolve) entity references when using the SAX Parser.
+  dom_parse_entities: Shows how to detect entity references when using the DOM parser.
+  sax_parser_entities: Shows how to detect (and maybe resolve) entity references
+                       when using the SAX Parser.
 
 XPath:
-  dom_xpath: Shows how to get XML nodes by specifying them with an XPath, when using the DOM parser.
+  dom_xpath: Shows how to get XML nodes by specifying them with an XPath,
+             when using the DOM parser.
 
 Others:
-  sax_exception: Shows how to implement a libxml++ exception that can be thrown by your SAX parser.
-  dom_parser_raw: Test parse_memory_raw() by converting a UTF-8-encoded XML document to UCS-2 and passing the raw memory to the parser.
+  sax_exception: Shows how to implement a libxml++ exception that can be thrown
+                 by your SAX parser.
+  dom_parser_raw: Test parse_memory_raw() by converting a UTF-8-encoded XML document
+                  to UCS-2 and passing the raw memory to the parser.
+  dtdvalidation: Shows how to parse a DTD (document type definition),
+                 and use it for validating a document.
+  schemavalidation: Shows how to parse a schema definition, and use it for
+                    validating a document, using the DOM parser.
 
diff --git a/examples/dom_xinclude/example.xml b/examples/dom_xinclude/example.xml
new file mode 100644
index 0000000..e99a4a4
--- /dev/null
+++ b/examples/dom_xinclude/example.xml
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<document xmlns:xi="http://www.w3.org/2001/XInclude";>
+  <p><xi:include href="include1.txt" parse="text">
+    <xi:fallback>Did not find include1.txt.</xi:fallback>
+  </xi:include></p>
+  <xi:include href="include2.xml"/>
+</document>
diff --git a/examples/dom_xinclude/include1.txt b/examples/dom_xinclude/include1.txt
new file mode 100644
index 0000000..6683a84
--- /dev/null
+++ b/examples/dom_xinclude/include1.txt
@@ -0,0 +1 @@
+This is the contents of file include1.txt.
\ No newline at end of file
diff --git a/examples/dom_xinclude/include2.xml b/examples/dom_xinclude/include2.xml
new file mode 100644
index 0000000..19b2c9d
--- /dev/null
+++ b/examples/dom_xinclude/include2.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0"?>
+<chapter id="chapter-introduction">
+  <p>This is the contents of file include2.xml.</p>
+</chapter>
diff --git a/examples/dom_xinclude/main.cc b/examples/dom_xinclude/main.cc
new file mode 100644
index 0000000..601348b
--- /dev/null
+++ b/examples/dom_xinclude/main.cc
@@ -0,0 +1,198 @@
+/* Copyright (C) 2012 The libxml++ development team
+ *
+ * This file is part of libxml++.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <libxml++/libxml++.h>
+#include <iostream>
+#include <stdlib.h>
+
+void print_node(const xmlpp::Node* node, unsigned int indentation = 0)
+{
+  const Glib::ustring indent(indentation, ' ');
+
+  const xmlpp::ContentNode* nodeContent = dynamic_cast<const xmlpp::ContentNode*>(node);
+  const xmlpp::TextNode* nodeText = dynamic_cast<const xmlpp::TextNode*>(node);
+  const xmlpp::CommentNode* nodeComment = dynamic_cast<const xmlpp::CommentNode*>(node);
+
+  //Let's ignore the indenting - you don't always want to do this.
+  if (nodeText && nodeText->is_white_space())
+    return;
+
+  const Glib::ustring nodename = node->get_name();
+
+  if (!nodeText && !nodeComment && !nodename.empty()) //Let's not say "name: text".
+  {
+    const Glib::ustring namespace_prefix = node->get_namespace_prefix();
+
+    std::cout << indent << "Node name = ";
+    if (!namespace_prefix.empty())
+      std::cout << namespace_prefix << ":";
+    std::cout << nodename << std::endl;
+  }
+  else if (nodeText) //Let's say when it's text.
+  {
+    std::cout << indent << "Text Node" << std::endl;
+  }
+
+  //Treat the various node types differently:
+  if (nodeText)
+  {
+    std::cout << indent << "text = \"" << nodeText->get_content() << "\"" << std::endl;
+  }
+  else if (nodeComment)
+  {
+    std::cout << indent << "comment = " << nodeComment->get_content() << std::endl;
+  }
+  else if (nodeContent)
+  {
+    std::cout << indent << "content = " << nodeContent->get_content() << std::endl;
+  }
+  else if (const xmlpp::Element* nodeElement = dynamic_cast<const xmlpp::Element*>(node))
+  {
+    //A normal Element node:
+    std::cout << indent << "     Element line = " << node->get_line() << std::endl;
+
+    //Print attributes:
+    const xmlpp::Element::AttributeList attributes = nodeElement->get_attributes();
+    for (xmlpp::Element::AttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter)
+    {
+      const xmlpp::Attribute* attribute = *iter;
+      const Glib::ustring namespace_prefix = attribute->get_namespace_prefix();
+
+      std::cout << indent << "  Attribute ";
+      if (!namespace_prefix.empty())
+        std::cout << namespace_prefix  << ":";
+      std::cout << attribute->get_name() << " = " << attribute->get_value() << std::endl;
+    }
+
+    const xmlpp::Attribute* attribute = nodeElement->get_attribute("title");
+    if (attribute)
+    {
+      std::cout << indent << "title = " << attribute->get_value() << std::endl;
+    }
+  }
+  else if (dynamic_cast<const xmlpp::XIncludeStart*>(node))
+  {
+    std::cout << indent << "     " << "XIncludeStart line = " << node->get_line() << std::endl;
+  }
+  else if (dynamic_cast<const xmlpp::XIncludeEnd*>(node))
+  {
+    std::cout << indent << "     " << "XIncludeEnd" << std::endl;
+  }
+
+  if (!nodeContent)
+  {
+    //Recurse through child nodes:
+    xmlpp::Node::NodeList list = node->get_children();
+    for (xmlpp::Node::NodeList::iterator iter = list.begin(); iter != list.end(); ++iter)
+    {
+      print_node(*iter, indentation + 2); //recursive
+    }
+  }
+}
+
+int main(int argc, char* argv[])
+{
+  // Set the global C++ locale to the user-configured locale,
+  // so we can use std::cout with UTF-8, via Glib::ustring, without exceptions.
+  std::locale::global(std::locale(""));
+
+  bool validate = false;
+  bool set_throw_messages = false;
+  bool throw_messages = false;
+  bool substitute_entities = true;
+  bool generate_xinclude_nodes = true;
+
+  int argi = 1;
+  while (argc > argi && *argv[argi] == '-') // option
+  {
+    switch (*(argv[argi]+1))
+    {
+      case 'v':
+        validate = true;
+        break;
+      case 't':
+       set_throw_messages = true;
+       throw_messages = true;
+       break;
+      case 'e':
+       set_throw_messages = true;
+       throw_messages = false;
+       break;
+      case 'E':
+        substitute_entities = false;
+        break;
+      case 'X':
+        generate_xinclude_nodes = false;
+        break;
+     default:
+       std::cout << "Usage: " << argv[0] << " [-v] [-t] [-e] [-x] [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
+                 << "       -X  Do not generate XInclude nodes" << std::endl;
+       return EXIT_FAILURE;
+     }
+     argi++;
+  }
+  std::string filepath;
+  if (argc > argi)
+    filepath = argv[argi]; //Allow the user to specify a different XML file to parse.
+  else
+    filepath = "example.xml";
+ 
+  try
+  {
+    xmlpp::DomParser parser;
+    if (validate)
+      parser.set_validate();
+    if (set_throw_messages)
+      parser.set_throw_messages(throw_messages);
+    //We can have the text resolved/unescaped automatically.
+    parser.set_substitute_entities(substitute_entities);
+    parser.parse_file(filepath);
+    if (parser)
+    {
+      //Walk the tree:
+      xmlpp::Node* pNode = parser.get_document()->get_root_node(); //deleted by DomParser.
+      print_node(pNode);
+
+      std::cout << std::endl << ">>>>> Number of XInclude substitutions: "
+                << parser.get_document()->process_xinclude(generate_xinclude_nodes)
+                << std::endl << std::endl;
+      pNode = parser.get_document()->get_root_node();
+      print_node(pNode);
+
+      const Glib::ustring whole = parser.get_document()->write_to_string();
+      std::cout << std::endl << ">>>>> XML after XInclude processing: " << std::endl
+                << whole << std::endl;
+    }
+  }
+  catch (const std::exception& ex)
+  {
+    std::cerr << "Exception caught: " << ex.what() << std::endl;
+    return EXIT_FAILURE;
+  }
+
+  return EXIT_SUCCESS;
+}
+
diff --git a/libxml++/document.cc b/libxml++/document.cc
index 99854e7..6bc3112 100644
--- a/libxml++/document.cc
+++ b/libxml++/document.cc
@@ -16,8 +16,121 @@
 #include <libxml++/io/ostreamoutputbuffer.h>
 
 #include <libxml/tree.h>
+#include <libxml/xinclude.h>
+#include <libxml/parser.h> // XML_PARSE_NOXINCNODE
 
 #include <iostream>
+#include <map>
+
+namespace // anonymous
+{
+typedef std::map<xmlpp::Node*, xmlElementType> NodeMap;
+
+// Find all C++ wrappers of 'node' and its descendants.
+// Compare xmlpp::Node::free_wrappers().
+void find_wrappers(xmlNode* node, NodeMap& node_map)
+{
+  if (!node)
+    return;
+    
+  //If an entity declaration contains an entity reference, there can be cyclic
+  //references between entity declarations and entity references. (It's not
+  //a tree.) We must avoid an infinite recursion.
+  //Compare xmlFreeNode(), which frees the children of all node types except
+  //XML_ENTITY_REF_NODE.
+  if (node->type != XML_ENTITY_REF_NODE)
+  {
+    // Walk the children list.
+    for (xmlNode* child = node->children; child; child = child->next)
+      find_wrappers(child, node_map);
+  }
+
+  // Find the local one
+  bool has_attributes = true;
+  switch (node->type)
+  {
+    // Node types that have no attributes.
+    // These are not represented by struct xmlNode.
+    case XML_DTD_NODE:
+    case XML_ATTRIBUTE_NODE:
+    case XML_ELEMENT_DECL:
+    case XML_ATTRIBUTE_DECL:
+    case XML_ENTITY_DECL:
+    case XML_DOCUMENT_NODE:
+      has_attributes = false;
+      break;
+    default:
+      break;
+  }
+
+  if (node->_private)
+    node_map[static_cast<xmlpp::Node*>(node->_private)] = node->type;
+
+  if (!has_attributes)
+    return;
+
+  //Walk the attributes list.
+  //Note that some "derived" structs have a different layout, so 
+  //_xmlNode::properties would be a nonsense value, leading to crashes
+  //(and shown as valgrind warnings), so we return above, to avoid 
+  //checking it here.
+  for (xmlAttr* attr = node->properties; attr; attr = attr->next)
+    find_wrappers(reinterpret_cast<xmlNode*>(attr), node_map);
+}
+
+// Remove from 'node_map' the pointers to the C++ wrappers that are found with
+// unchanged type in 'node' and its descendants.
+void remove_found_wrappers(xmlNode* node, NodeMap& node_map)
+{
+  if (!node)
+    return;
+    
+  if (node->type != XML_ENTITY_REF_NODE)
+  {
+    // Walk the children list.
+    for (xmlNode* child = node->children; child; child = child->next)
+      remove_found_wrappers(child, node_map);
+  }
+
+  // Find the local one
+  bool has_attributes = true;
+  switch (node->type)
+  {
+    // Node types that have no attributes
+    case XML_DTD_NODE:
+    case XML_ATTRIBUTE_NODE:
+    case XML_ELEMENT_DECL:
+    case XML_ATTRIBUTE_DECL:
+    case XML_ENTITY_DECL:
+    case XML_DOCUMENT_NODE:
+      has_attributes = false;
+      break;
+    default:
+      break;
+  }
+
+  if (node->_private)
+  {
+    const NodeMap::iterator iter =
+      node_map.find(static_cast<xmlpp::Node*>(node->_private));
+    if (iter != node_map.end())
+    {
+      if (iter->second == node->type)
+        node_map.erase(iter);
+      else
+        node->_private = 0; // node->type has changed. The wrapper will be deleted.
+    }
+  }
+
+  if (!has_attributes)
+    return;
+
+  // Walk the attributes list.
+  for (xmlAttr* attr = node->properties; attr; attr = attr->next)
+    remove_found_wrappers(reinterpret_cast<xmlNode*>(attr), node_map);
+
+}
+} // anonymous
 
 namespace xmlpp
 {
@@ -306,6 +419,44 @@ void Document::set_entity_declaration(const Glib::ustring& name, XmlEntityType t
     throw internal_error("Could not add entity declaration " + name);
 }
 
+int Document::process_xinclude(bool generate_xinclude_nodes)
+{
+  NodeMap node_map;
+
+  xmlNode* root = xmlDocGetRootElement(impl_);
+
+  find_wrappers(root, node_map);
+
+  xmlResetLastError();
+  const int n_substitutions = xmlXIncludeProcessTreeFlags(root,
+    generate_xinclude_nodes ? 0 : XML_PARSE_NOXINCNODE);
+
+  remove_found_wrappers(reinterpret_cast<xmlNode*>(impl_), node_map);
+  // Delete wrappers of nodes that have been deleted or have got their type changed.
+  for (NodeMap::iterator iter = node_map.begin(); iter != node_map.end(); ++iter)
+  {
+    switch (iter->second)
+    {
+    case XML_DTD_NODE:
+      delete reinterpret_cast<Dtd*>(iter->first);
+      break;
+    case XML_DOCUMENT_NODE:
+      delete reinterpret_cast<Document*>(iter->first);
+      break;
+    default:
+      delete iter->first; // Node*
+      break;
+    }
+  }
+
+  if (n_substitutions < 0)
+  {
+    throw exception("Couldn't process XInclude\n" + format_xml_error());
+  }
+
+  return n_substitutions;
+}
+
 _xmlEntity* Document::get_entity(const Glib::ustring& name)
 {
   return xmlGetDocEntity(impl_, (const xmlChar*) name.c_str());
diff --git a/libxml++/document.h b/libxml++/document.h
index d2c238e..798b332 100644
--- a/libxml++/document.h
+++ b/libxml++/document.h
@@ -216,6 +216,22 @@ public:
                                       const Glib::ustring& publicId, const Glib::ustring& systemId,
                                       const Glib::ustring& content);
 
+  /** Perform XInclude substitution on the XML document.
+   * XInclude substitution may both add and delete nodes in the document,
+   * as well as change the type of some nodes. All pointers to deleted nodes
+   * and nodes whose type is changed become invalid.
+   * (The node type represented by an underlying xmlNode struct can change.
+   * The type of a C++ wrapper can't change. The old wrapper is deleted, and a
+   * new one is created if and when it's required.)
+   *
+   * @newin{2,36}
+   *
+   * @param generate_xinclude_nodes Generate XIncludeStart and XIncludeEnd nodes.
+   * @returns The number of substitutions.
+   * @throws xmlpp::exception
+   */
+  int process_xinclude(bool generate_xinclude_nodes = true);
+
   ///Access the underlying libxml implementation.
   _xmlDoc* cobj();
 
diff --git a/libxml++/libxml++.h b/libxml++/libxml++.h
index 05a5806..91c2dd0 100644
--- a/libxml++/libxml++.h
+++ b/libxml++/libxml++.h
@@ -53,11 +53,15 @@
 #include <libxml++/parsers/saxparser.h>
 #include <libxml++/parsers/textreader.h>
 #include <libxml++/nodes/node.h>
+#include <libxml++/nodes/cdatanode.h>
 #include <libxml++/nodes/commentnode.h>
 #include <libxml++/nodes/element.h>
 #include <libxml++/nodes/entitydeclaration.h>
 #include <libxml++/nodes/entityreference.h>
+#include <libxml++/nodes/processinginstructionnode.h>
 #include <libxml++/nodes/textnode.h>
+#include <libxml++/nodes/xincludeend.h>
+#include <libxml++/nodes/xincludestart.h>
 #include <libxml++/attribute.h>
 #include <libxml++/attributedeclaration.h>
 #include <libxml++/attributenode.h>
diff --git a/libxml++/nodes/node.cc b/libxml++/nodes/node.cc
index d9af71c..44bcf91 100644
--- a/libxml++/nodes/node.cc
+++ b/libxml++/nodes/node.cc
@@ -12,6 +12,8 @@
 #include <libxml++/nodes/commentnode.h>
 #include <libxml++/nodes/cdatanode.h>
 #include <libxml++/nodes/processinginstructionnode.h>
+#include <libxml++/nodes/xincludestart.h>
+#include <libxml++/nodes/xincludeend.h>
 #include <libxml++/exceptions/internal_error.h>
 #include <libxml++/attributedeclaration.h>
 #include <libxml++/attributenode.h>
@@ -640,6 +642,16 @@ void Node::create_wrapper(xmlNode* node)
       node->_private = new xmlpp::EntityReference(node);
       break;
     }
+    case XML_XINCLUDE_START:
+    {
+      node->_private = new xmlpp::XIncludeStart(node);
+      break;
+    }
+    case XML_XINCLUDE_END:
+    {
+      node->_private = new xmlpp::XIncludeEnd(node);
+      break;
+    }
     case XML_DOCUMENT_NODE:
     {
       // do nothing. For Documents it's the wrapper that is the owner.
diff --git a/libxml++/nodes/xincludeend.cc b/libxml++/nodes/xincludeend.cc
new file mode 100644
index 0000000..3187920
--- /dev/null
+++ b/libxml++/nodes/xincludeend.cc
@@ -0,0 +1,32 @@
+/* Copyright (C) 2012 The libxml++ development team
+ *
+ * This file is part of libxml++.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libxml++/nodes/xincludeend.h>
+#include <libxml/tree.h>
+
+namespace xmlpp
+{
+
+XIncludeEnd::XIncludeEnd(xmlNode* node)
+: Node(node)
+{}
+
+XIncludeEnd::~XIncludeEnd()
+{}
+
+} //namespace xmlpp
diff --git a/libxml++/nodes/xincludeend.h b/libxml++/nodes/xincludeend.h
new file mode 100644
index 0000000..7071cbe
--- /dev/null
+++ b/libxml++/nodes/xincludeend.h
@@ -0,0 +1,41 @@
+/* Copyright (C) 2012 The libxml++ development team
+ *
+ * This file is part of libxml++.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LIBXMLPP_NODES_XINCLUDEEND_H
+#define __LIBXMLPP_NODES_XINCLUDEEND_H
+
+#include <libxml++/nodes/node.h>
+
+namespace xmlpp
+{
+
+/** XIncludeEnd node.
+ * This will be instantiated by xmlpp::Document::process_xinclude().
+ *
+ * @newin{2,36}
+ */
+class XIncludeEnd : public Node
+{
+public:
+  explicit XIncludeEnd(_xmlNode* node);
+  virtual ~XIncludeEnd();
+};
+
+} // namespace xmlpp
+
+#endif //__LIBXMLPP_NODES_XINCLUDEEND_H
diff --git a/libxml++/nodes/xincludestart.cc b/libxml++/nodes/xincludestart.cc
new file mode 100644
index 0000000..c2bc0f3
--- /dev/null
+++ b/libxml++/nodes/xincludestart.cc
@@ -0,0 +1,32 @@
+/* Copyright (C) 2012 The libxml++ development team
+ *
+ * This file is part of libxml++.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <libxml++/nodes/xincludestart.h>
+#include <libxml/tree.h>
+
+namespace xmlpp
+{
+
+XIncludeStart::XIncludeStart(xmlNode* node)
+: Node(node)
+{}
+
+XIncludeStart::~XIncludeStart()
+{}
+
+} //namespace xmlpp
diff --git a/libxml++/nodes/xincludestart.h b/libxml++/nodes/xincludestart.h
new file mode 100644
index 0000000..2b046b6
--- /dev/null
+++ b/libxml++/nodes/xincludestart.h
@@ -0,0 +1,41 @@
+/* Copyright (C) 2012 The libxml++ development team
+ *
+ * This file is part of libxml++.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __LIBXMLPP_NODES_XINCLUDESTART_H
+#define __LIBXMLPP_NODES_XINCLUDESTART_H
+
+#include <libxml++/nodes/node.h>
+
+namespace xmlpp
+{
+
+/** XIncludeStart node.
+ * This will be instantiated by xmlpp::Document::process_xinclude().
+ *
+ * @newin{2,36}
+ */
+class XIncludeStart : public Node
+{
+public:
+  explicit XIncludeStart(_xmlNode* node);
+  virtual ~XIncludeStart();
+};
+
+} // namespace xmlpp
+
+#endif //__LIBXMLPP_NODES_XINCLUDESTART_H



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]