├── contrib └── foreach.hpp ├── docs ├── images │ ├── caution.png │ ├── dom_tree.png │ ├── dom_tree_thumb.png │ ├── home.png │ ├── next.png │ ├── note.png │ ├── prev.png │ ├── up.png │ ├── vs2005_link1.png │ ├── vs2005_link1_thumb.png │ ├── vs2005_link2.png │ ├── vs2005_link2_thumb.png │ ├── vs2005_pch1.png │ ├── vs2005_pch1_thumb.png │ ├── vs2005_pch2.png │ ├── vs2005_pch2_thumb.png │ ├── vs2005_pch3.png │ ├── vs2005_pch3_thumb.png │ ├── vs2005_pch4.png │ ├── vs2005_pch4_thumb.png │ ├── vs2010_link1.png │ ├── vs2010_link1_thumb.png │ ├── vs2010_link2.png │ └── vs2010_link2_thumb.png ├── manual.html ├── manual │ ├── access.html │ ├── apiref.html │ ├── changes.html │ ├── dom.html │ ├── install.html │ ├── loading.html │ ├── modify.html │ ├── saving.html │ ├── toc.html │ └── xpath.html ├── pugixml.css ├── quickstart.html └── samples │ ├── character.xml │ ├── custom_memory_management.cpp │ ├── include.cpp │ ├── load_error_handling.cpp │ ├── load_file.cpp │ ├── load_memory.cpp │ ├── load_options.cpp │ ├── load_stream.cpp │ ├── modify_add.cpp │ ├── modify_base.cpp │ ├── modify_remove.cpp │ ├── save_custom_writer.cpp │ ├── save_file.cpp │ ├── save_file_output.xml │ ├── save_options.cpp │ ├── save_stream.cpp │ ├── save_subtree.cpp │ ├── transitions.xml │ ├── traverse_base.cpp │ ├── traverse_iter.cpp │ ├── traverse_predicate.cpp │ ├── traverse_walker.cpp │ ├── tree.xml │ ├── weekly-shift_jis.xml │ ├── weekly-utf-16.xml │ ├── weekly-utf-8.xml │ ├── xgconsole.xml │ ├── xpath_error.cpp │ ├── xpath_query.cpp │ ├── xpath_select.cpp │ └── xpath_variables.cpp ├── license.txt ├── readme.txt ├── scripts ├── CMakeLists.txt ├── premake4.lua ├── pugihtml_codeblocks.cbp ├── pugihtml_codelite.project ├── pugihtml_vs2010.vcxproj ├── pugihtml_vs2010.vcxproj.user └── pugihtml_vs2010_static.vcxproj └── src ├── common.hpp ├── memory.cpp ├── memory.hpp ├── pugiconfig.hpp ├── pugihtml.cpp ├── pugihtml.hpp └── pugiutil.hpp /contrib/foreach.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Boost.Foreach support for pugihtml classes. 3 | * This file is provided to the public domain. 4 | * Written by Arseny Kapoulkine (arseny.kapoulkine@gmail.com) 5 | */ 6 | 7 | #ifndef HEADER_PUGIHTML_FOREACH_HPP 8 | #define HEADER_PUGIHTML_FOREACH_HPP 9 | 10 | #include "pugihtml.hpp" 11 | 12 | /* 13 | * These types add support for BOOST_FOREACH macro to html_node and html_document classes (child iteration only). 14 | * Example usage: 15 | * BOOST_FOREACH(html_node n, doc) {} 16 | */ 17 | 18 | namespace boost 19 | { 20 | template struct range_mutable_iterator; 21 | template struct range_const_iterator; 22 | 23 | template<> struct range_mutable_iterator 24 | { 25 | typedef pugi::html_node::iterator type; 26 | }; 27 | 28 | template<> struct range_const_iterator 29 | { 30 | typedef pugi::html_node::iterator type; 31 | }; 32 | 33 | template<> struct range_mutable_iterator 34 | { 35 | typedef pugi::html_document::iterator type; 36 | }; 37 | 38 | template<> struct range_const_iterator 39 | { 40 | typedef pugi::html_document::iterator type; 41 | }; 42 | } 43 | 44 | /* 45 | * These types add support for BOOST_FOREACH macro to html_node and html_document classes (child/attribute iteration). 46 | * Example usage: 47 | * BOOST_FOREACH(html_node n, children(doc)) {} 48 | * BOOST_FOREACH(html_node n, attributes(doc)) {} 49 | */ 50 | 51 | namespace pugi 52 | { 53 | struct html_node_children_adapter 54 | { 55 | typedef pugi::html_node::iterator iterator; 56 | typedef pugi::html_node::iterator const_iterator; 57 | 58 | html_node node; 59 | 60 | const_iterator begin() const 61 | { 62 | return node.begin(); 63 | } 64 | 65 | const_iterator end() const 66 | { 67 | return node.end(); 68 | } 69 | }; 70 | 71 | html_node_children_adapter children(const pugi::html_node& node) 72 | { 73 | html_node_children_adapter result = {node}; 74 | return result; 75 | } 76 | 77 | struct html_node_attribute_adapter 78 | { 79 | typedef pugi::html_node::attribute_iterator iterator; 80 | typedef pugi::html_node::attribute_iterator const_iterator; 81 | 82 | html_node node; 83 | 84 | const_iterator begin() const 85 | { 86 | return node.attributes_begin(); 87 | } 88 | 89 | const_iterator end() const 90 | { 91 | return node.attributes_end(); 92 | } 93 | }; 94 | 95 | html_node_attribute_adapter attributes(const pugi::html_node& node) 96 | { 97 | html_node_attribute_adapter result = {node}; 98 | return result; 99 | } 100 | } 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /docs/images/caution.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rofldev/pugihtml/a7e4c33c8b59d6e92d5f1f4b849b5b8a1ec0bc06/docs/images/caution.png -------------------------------------------------------------------------------- /docs/images/dom_tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rofldev/pugihtml/a7e4c33c8b59d6e92d5f1f4b849b5b8a1ec0bc06/docs/images/dom_tree.png -------------------------------------------------------------------------------- /docs/images/dom_tree_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rofldev/pugihtml/a7e4c33c8b59d6e92d5f1f4b849b5b8a1ec0bc06/docs/images/dom_tree_thumb.png -------------------------------------------------------------------------------- /docs/images/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rofldev/pugihtml/a7e4c33c8b59d6e92d5f1f4b849b5b8a1ec0bc06/docs/images/home.png -------------------------------------------------------------------------------- /docs/images/next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rofldev/pugihtml/a7e4c33c8b59d6e92d5f1f4b849b5b8a1ec0bc06/docs/images/next.png -------------------------------------------------------------------------------- /docs/images/note.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rofldev/pugihtml/a7e4c33c8b59d6e92d5f1f4b849b5b8a1ec0bc06/docs/images/note.png -------------------------------------------------------------------------------- /docs/images/prev.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rofldev/pugihtml/a7e4c33c8b59d6e92d5f1f4b849b5b8a1ec0bc06/docs/images/prev.png -------------------------------------------------------------------------------- /docs/images/up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rofldev/pugihtml/a7e4c33c8b59d6e92d5f1f4b849b5b8a1ec0bc06/docs/images/up.png -------------------------------------------------------------------------------- /docs/images/vs2005_link1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rofldev/pugihtml/a7e4c33c8b59d6e92d5f1f4b849b5b8a1ec0bc06/docs/images/vs2005_link1.png -------------------------------------------------------------------------------- /docs/images/vs2005_link1_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rofldev/pugihtml/a7e4c33c8b59d6e92d5f1f4b849b5b8a1ec0bc06/docs/images/vs2005_link1_thumb.png -------------------------------------------------------------------------------- /docs/images/vs2005_link2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rofldev/pugihtml/a7e4c33c8b59d6e92d5f1f4b849b5b8a1ec0bc06/docs/images/vs2005_link2.png -------------------------------------------------------------------------------- /docs/images/vs2005_link2_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rofldev/pugihtml/a7e4c33c8b59d6e92d5f1f4b849b5b8a1ec0bc06/docs/images/vs2005_link2_thumb.png -------------------------------------------------------------------------------- /docs/images/vs2005_pch1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rofldev/pugihtml/a7e4c33c8b59d6e92d5f1f4b849b5b8a1ec0bc06/docs/images/vs2005_pch1.png -------------------------------------------------------------------------------- /docs/images/vs2005_pch1_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rofldev/pugihtml/a7e4c33c8b59d6e92d5f1f4b849b5b8a1ec0bc06/docs/images/vs2005_pch1_thumb.png -------------------------------------------------------------------------------- /docs/images/vs2005_pch2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rofldev/pugihtml/a7e4c33c8b59d6e92d5f1f4b849b5b8a1ec0bc06/docs/images/vs2005_pch2.png -------------------------------------------------------------------------------- /docs/images/vs2005_pch2_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rofldev/pugihtml/a7e4c33c8b59d6e92d5f1f4b849b5b8a1ec0bc06/docs/images/vs2005_pch2_thumb.png -------------------------------------------------------------------------------- /docs/images/vs2005_pch3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rofldev/pugihtml/a7e4c33c8b59d6e92d5f1f4b849b5b8a1ec0bc06/docs/images/vs2005_pch3.png -------------------------------------------------------------------------------- /docs/images/vs2005_pch3_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rofldev/pugihtml/a7e4c33c8b59d6e92d5f1f4b849b5b8a1ec0bc06/docs/images/vs2005_pch3_thumb.png -------------------------------------------------------------------------------- /docs/images/vs2005_pch4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rofldev/pugihtml/a7e4c33c8b59d6e92d5f1f4b849b5b8a1ec0bc06/docs/images/vs2005_pch4.png -------------------------------------------------------------------------------- /docs/images/vs2005_pch4_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rofldev/pugihtml/a7e4c33c8b59d6e92d5f1f4b849b5b8a1ec0bc06/docs/images/vs2005_pch4_thumb.png -------------------------------------------------------------------------------- /docs/images/vs2010_link1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rofldev/pugihtml/a7e4c33c8b59d6e92d5f1f4b849b5b8a1ec0bc06/docs/images/vs2010_link1.png -------------------------------------------------------------------------------- /docs/images/vs2010_link1_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rofldev/pugihtml/a7e4c33c8b59d6e92d5f1f4b849b5b8a1ec0bc06/docs/images/vs2010_link1_thumb.png -------------------------------------------------------------------------------- /docs/images/vs2010_link2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rofldev/pugihtml/a7e4c33c8b59d6e92d5f1f4b849b5b8a1ec0bc06/docs/images/vs2010_link2.png -------------------------------------------------------------------------------- /docs/images/vs2010_link2_thumb.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rofldev/pugihtml/a7e4c33c8b59d6e92d5f1f4b849b5b8a1ec0bc06/docs/images/vs2010_link2_thumb.png -------------------------------------------------------------------------------- /docs/manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | pugixml 1.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 22 | 23 |
13 | pugixml 1.0 manual | 14 | Overview | 15 | Installation | 16 | Document: 17 | Object model · Loading · Accessing · Modifying · Saving | 18 | XPath | 19 | API Reference | 20 | Table of Contents 21 |
Next
24 |
25 |
26 |

27 | Overview 28 |

29 | 35 |
36 |

37 | Introduction 38 |

39 |

40 | pugixml is a light-weight C++ XML 41 | processing library. It consists of a DOM-like interface with rich traversal/modification 42 | capabilities, an extremely fast XML parser which constructs the DOM tree 43 | from an XML file/buffer, and an XPath 1.0 implementation 44 | for complex data-driven tree queries. Full Unicode support is also available, 45 | with two Unicode interface variants 46 | and conversions between different Unicode encodings (which happen automatically 47 | during parsing/saving). The library is extremely 48 | portable and easy to integrate and use. pugixml is developed and maintained 49 | since 2006 and has many users. All code is distributed under the MIT 50 | license, making it completely free to use in both open-source and 51 | proprietary applications. 52 |

53 |

54 | pugixml enables very fast, convenient and memory-efficient XML document processing. 55 | However, since pugixml has a DOM parser, it can't process XML documents that 56 | do not fit in memory; also the parser is a non-validating one, so if you 57 | need DTD or XML Schema validation, the library is not for you. 58 |

59 |

60 | This is the complete manual for pugixml, which describes all features of 61 | the library in detail. If you want to start writing code as quickly as possible, 62 | you are advised to read the quick start guide 63 | first. 64 |

65 |
66 | 67 | 68 | 69 | 70 | 79 |
[Note]Note

71 | No documentation is perfect, neither is this one. If you encounter a description 72 | that is unclear, please file an issue as described in Feedback. 73 | Also if you can spare the time for a full proof-reading, including spelling 74 | and grammar, that would be great! Please send me 75 | an e-mail; as a token of appreciation, your name will be included 76 | into the corresponding section 77 | of this documentation. 78 |

80 |
81 |
82 |

83 | Feedback 84 |

85 |

86 | If you believe you've found a bug in pugixml (bugs include compilation problems 87 | (errors/warnings), crashes, performance degradation and incorrect behavior), 88 | please file an issue via issue 89 | submission form. Be sure to include the relevant information so that 90 | the bug can be reproduced: the version of pugixml, compiler version and target 91 | architecture, the code that uses pugixml and exhibits the bug, etc. 92 |

93 |

94 | Feature requests can be reported the same way as bugs, so if you're missing 95 | some functionality in pugixml or if the API is rough in some places and you 96 | can suggest an improvement, file 97 | an issue. However please note that there are many factors when considering 98 | API changes (compatibility with previous versions, API redundancy, etc.), 99 | so generally features that can be implemented via a small function without 100 | pugixml modification are not accepted. However, all rules have exceptions. 101 |

102 |

103 | If you have a contribution to pugixml, such as build script for some build 104 | system/IDE, or a well-designed set of helper functions, or a binding to some 105 | language other than C++, please file 106 | an issue. You can include the relevant patches as issue attachments. 107 | Your contribution has to be distributed under the terms of a license that's 108 | compatible with pugixml license; i.e. GPL/LGPL licensed code is not accepted. 109 |

110 |

111 | If filing an issue is not possible due to privacy or other concerns, you 112 | can contact pugixml author by e-mail directly: arseny.kapoulkine@gmail.com. 113 |

114 |
115 |
116 |

117 | Acknowledgments 118 |

119 |

120 | pugixml could not be developed without the help from many people; some of 121 | them are listed in this section. If you've played a part in pugixml development 122 | and you can not find yourself on this list, I'm truly sorry; please send me an e-mail so I can fix this. 123 |

124 |

125 | Thanks to Kristen Wegner for pugxml parser, 126 | which was used as a basis for pugixml. 127 |

128 |

129 | Thanks to Neville Franks for contributions 130 | to pugxml parser. 131 |

132 |

133 | Thanks to Artyom Palvelev for suggesting 134 | a lazy gap contraction approach. 135 |

136 |

137 | Thanks to Vyacheslav Egorov for documentation 138 | proofreading. 139 |

140 |
141 |
142 |

143 | License 144 |

145 |

146 | The pugixml library is distributed under the MIT license: 147 |

148 |
149 |

150 | Copyright (c) 2006-2010 Arseny Kapoulkine 151 |

152 |

153 | Permission is hereby granted, free of charge, to any person obtaining a 154 | copy of this software and associated documentation files (the "Software"), 155 | to deal in the Software without restriction, including without limitation 156 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 157 | and/or sell copies of the Software, and to permit persons to whom the Software 158 | is furnished to do so, subject to the following conditions: 159 |

160 |

161 | The above copyright notice and this permission notice shall be included 162 | in all copies or substantial portions of the Software. 163 |

164 |

165 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 166 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 167 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 168 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 169 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 170 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 171 | IN THE SOFTWARE. 172 |

173 |
174 |

175 | This means that you can freely use pugixml in your applications, both open-source 176 | and proprietary. If you use pugixml in a product, it is sufficient to add 177 | an acknowledgment like this to the product distribution: 178 |

179 |

180 | This software is based on pugixml library (http://pugixml.org).
181 | pugixml 182 | is Copyright (C) 2006-2010 Arseny Kapoulkine. 183 |

184 |
185 |
186 | 187 | 188 | 189 |

Last revised: October 31, 2010 at 17:44:02 GMT

190 |
191 | 192 | 202 | 203 |
193 | pugixml 1.0 manual | 194 | Overview | 195 | Installation | 196 | Document: 197 | Object model · Loading · Accessing · Modifying · Saving | 198 | XPath | 199 | API Reference | 200 | Table of Contents 201 |
Next
204 | 205 | 206 | -------------------------------------------------------------------------------- /docs/manual/changes.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Changelog 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 24 | 27 |
15 | pugixml 1.0 manual | 16 | Overview | 17 | Installation | 18 | Document: 19 | Object model · Loading · Accessing · Modifying · Saving | 20 | XPath | 21 | API Reference | 22 | Table of Contents 23 |
25 | PrevUpHomeNext 26 |
28 |
29 |
30 |

31 | Changelog 32 |

33 |
34 | 1.11.2010 - version 35 | 1.0 36 |
37 |

38 | Major release, featuring many XPath enhancements, wide character filename support, 39 | miscellaneous performance improvements, bug fixes and more. 40 |

41 |
    42 |
  • 43 | XPath: 44 |
      45 |
    1. 46 | XPath implementation is moved to pugixml.cpp (which is the only source 47 | file now); use PUGIXML_NO_XPATH if you want to disable XPath to reduce 48 | code size 49 |
    2. 50 |
    3. 51 | XPath is now supported without exceptions (PUGIXML_NO_EXCEPTIONS); 52 | the error handling mechanism depends on the presence of exception 53 | support 54 |
    4. 55 |
    5. 56 | XPath is now supported without STL (PUGIXML_NO_STL) 57 |
    6. 58 |
    7. 59 | Introduced variable support 60 |
    8. 61 |
    9. 62 | Introduced new xpath_query::evaluate_string, which works without 63 | STL 64 |
    10. 65 |
    11. 66 | Introduced new xpath_node_set constructor (from an iterator range) 67 |
    12. 68 |
    13. 69 | Evaluation function now accept attribute context nodes 70 |
    14. 71 |
    15. 72 | All internal allocations use custom allocation functions 73 |
    16. 74 |
    17. 75 | Improved error reporting; now a last parsed offset is returned together 76 | with the parsing error 77 |
    18. 78 |
    79 |
  • 80 |
  • 81 | Bug fixes: 82 |
      83 |
    1. 84 | Fixed memory leak for loading from streams with stream exceptions 85 | turned on 86 |
    2. 87 |
    3. 88 | Fixed custom deallocation function calling with null pointer in one 89 | case 90 |
    4. 91 |
    5. 92 | Fixed missing attributes for iterator category functions; all functions/classes 93 | can now be DLL-exported 94 |
    6. 95 |
    7. 96 | Worked around Digital Mars compiler bug, which lead to minor read 97 | overfetches in several functions 98 |
    8. 99 |
    9. 100 | load_file now works with 2+ Gb files in MSVC/MinGW 101 |
    10. 102 |
    11. 103 | XPath: fixed memory leaks for incorrect queries 104 |
    12. 105 |
    13. 106 | XPath: fixed xpath_node() attribute constructor with empty attribute 107 | argument 108 |
    14. 109 |
    15. 110 | XPath: fixed lang() function for non-ASCII arguments 111 |
    16. 112 |
    113 |
  • 114 |
  • 115 | Specification changes: 116 |
      117 |
    1. 118 | CDATA nodes containing ]]> are printed as several nodes; while 119 | this changes the internal structure, this is the only way to escape 120 | CDATA contents 121 |
    2. 122 |
    3. 123 | Memory allocation errors during parsing now preserve last parsed 124 | offset (to give an idea about parsing progress) 125 |
    4. 126 |
    5. 127 | If an element node has the only child, and it is of CDATA type, then 128 | the extra indentation is omitted (previously this behavior only held 129 | for PCDATA children) 130 |
    6. 131 |
    132 |
  • 133 |
  • 134 | Additional functionality: 135 |
      136 |
    1. 137 | Added xml_parse_result default constructor 138 |
    2. 139 |
    3. 140 | Added xml_document::load_file and xml_document::save_file with wide 141 | character paths 142 |
    4. 143 |
    5. 144 | Added as_utf8 and as_wide overloads for std::wstring/std::string 145 | arguments 146 |
    6. 147 |
    7. 148 | Added DOCTYPE node type (node_doctype) and a special parse flag, 149 | parse_doctype, to add such nodes to the document during parsing 150 |
    8. 151 |
    9. 152 | Added parse_full parse flag mask, which extends parse_default with 153 | all node type parsing flags except parse_ws_pcdata 154 |
    10. 155 |
    11. 156 | Added xml_node::hash_value() and xml_attribute::hash_value() functions 157 | for use in hash-based containers 158 |
    12. 159 |
    13. 160 | Added internal_object() and additional constructor for both xml_node 161 | and xml_attribute for easier marshalling (useful for language bindings) 162 |
    14. 163 |
    15. 164 | Added xml_document::document_element() function 165 |
    16. 166 |
    17. 167 | Added xml_node::prepend_attribute, xml_node::prepend_child and xml_node::prepend_copy 168 | functions 169 |
    18. 170 |
    19. 171 | Added xml_node::append_child, xml_node::prepend_child, xml_node::insert_child_before 172 | and xml_node::insert_child_after overloads for element nodes (with 173 | name instead of type) 174 |
    20. 175 |
    21. 176 | Added xml_document::reset() function 177 |
    22. 178 |
    179 |
  • 180 |
  • 181 | Performance improvements: 182 |
      183 |
    1. 184 | xml_node::root() and xml_node::offset_debug() are now O(1) instead 185 | of O(logN) 186 |
    2. 187 |
    3. 188 | Minor parsing optimizations 189 |
    4. 190 |
    5. 191 | Minor memory optimization for strings in DOM tree (set_name/set_value) 192 |
    6. 193 |
    7. 194 | Memory optimization for string memory reclaiming in DOM tree (set_name/set_value 195 | now reallocate the buffer if memory waste is too big) 196 |
    8. 197 |
    9. 198 | XPath: optimized document order sorting 199 |
    10. 200 |
    11. 201 | XPath: optimized child/attribute axis step 202 |
    12. 203 |
    13. 204 | XPath: optimized number-to-string conversions in MSVC 205 |
    14. 206 |
    15. 207 | XPath: optimized concat for many arguments 208 |
    16. 209 |
    17. 210 | XPath: optimized evaluation allocation mechanism: constant and document 211 | strings are not heap-allocated 212 |
    18. 213 |
    19. 214 | XPath: optimized evaluation allocation mechanism: all temporaries' 215 | allocations use fast stack-like allocator 216 |
    20. 217 |
    218 |
  • 219 |
  • 220 | Compatibility: 221 |
      222 |
    1. 223 | Removed wildcard functions (xml_node::child_w, xml_node::attribute_w, 224 | etc.) 225 |
    2. 226 |
    3. 227 | Removed xml_node::all_elements_by_name 228 |
    4. 229 |
    5. 230 | Removed xpath_type_t enumeration; use xpath_value_type instead 231 |
    6. 232 |
    7. 233 | Removed format_write_bom_utf8 enumeration; use format_write_bom instead 234 |
    8. 235 |
    9. 236 | Removed xml_document::precompute_document_order, xml_attribute::document_order 237 | and xml_node::document_order functions; document order sort optimization 238 | is now automatic 239 |
    10. 240 |
    11. 241 | Removed xml_document::parse functions and transfer_ownership struct; 242 | use xml_document::load_buffer_inplace and xml_document::load_buffer_inplace_own 243 | instead 244 |
    12. 245 |
    13. 246 | Removed as_utf16 function; use as_wide instead 247 |
    14. 248 |
    249 |
  • 250 |
251 |
252 | 1.07.2010 - version 253 | 0.9 254 |
255 |

256 | Major release, featuring extended and improved Unicode support, miscellaneous 257 | performance improvements, bug fixes and more. 258 |

259 |
    260 |
  • 261 | Major Unicode improvements: 262 |
      263 |
    1. 264 | Introduced encoding support (automatic/manual encoding detection 265 | on load, manual encoding selection on save, conversion from/to UTF8, 266 | UTF16 LE/BE, UTF32 LE/BE) 267 |
    2. 268 |
    3. 269 | Introduced wchar_t mode (you can set PUGIXML_WCHAR_MODE define to 270 | switch pugixml internal encoding from UTF8 to wchar_t; all functions 271 | are switched to their Unicode variants) 272 |
    4. 273 |
    5. 274 | Load/save functions now support wide streams 275 |
    6. 276 |
    277 |
  • 278 |
  • 279 | Bug fixes: 280 |
      281 |
    1. 282 | Fixed document corruption on failed parsing bug 283 |
    2. 284 |
    3. 285 | XPath string <-> number conversion improvements (increased 286 | precision, fixed crash for huge numbers) 287 |
    4. 288 |
    5. 289 | Improved DOCTYPE parsing: now parser recognizes all well-formed DOCTYPE 290 | declarations 291 |
    6. 292 |
    7. 293 | Fixed xml_attribute::as_uint() for large numbers (i.e. 2^32-1) 294 |
    8. 295 |
    9. 296 | Fixed xml_node::first_element_by_path for path components that are 297 | prefixes of node names, but are not exactly equal to them. 298 |
    10. 299 |
    300 |
  • 301 |
  • 302 | Specification changes: 303 |
      304 |
    1. 305 | parse() API changed to load_buffer/load_buffer_inplace/load_buffer_inplace_own; 306 | load_buffer APIs do not require zero-terminated strings. 307 |
    2. 308 |
    3. 309 | Renamed as_utf16 to as_wide 310 |
    4. 311 |
    5. 312 | Changed xml_node::offset_debug return type and xml_parse_result::offset 313 | type to ptrdiff_t 314 |
    6. 315 |
    7. 316 | Nodes/attributes with empty names are now printed as :anonymous 317 |
    8. 318 |
    319 |
  • 320 |
  • 321 | Performance improvements: 322 |
      323 |
    1. 324 | Optimized document parsing and saving 325 |
    2. 326 |
    3. 327 | Changed internal memory management: internal allocator is used for 328 | both metadata and name/value data; allocated pages are deleted if 329 | all allocations from them are deleted 330 |
    4. 331 |
    5. 332 | Optimized memory consumption: sizeof(xml_node_struct) reduced from 333 | 40 bytes to 32 bytes on x86 334 |
    6. 335 |
    7. 336 | Optimized debug mode parsing/saving by order of magnitude 337 |
    8. 338 |
    339 |
  • 340 |
  • 341 | Miscellaneous: 342 |
      343 |
    1. 344 | All STL includes except <exception> in pugixml.hpp are replaced 345 | with forward declarations 346 |
    2. 347 |
    3. 348 | xml_node::remove_child and xml_node::remove_attribute now return 349 | the operation result 350 |
    4. 351 |
    352 |
  • 353 |
  • 354 | Compatibility: 355 |
      356 |
    1. 357 | parse() and as_utf16 are left for compatibility (these functions 358 | are deprecated and will be removed in version 1.0) 359 |
    2. 360 |
    3. 361 | Wildcard functions, document_order/precompute_document_order functions, 362 | all_elements_by_name function and format_write_bom_utf8 flag are 363 | deprecated and will be removed in version 1.0 364 |
    4. 365 |
    5. 366 | xpath_type_t enumeration was renamed to xpath_value_type; xpath_type_t 367 | is deprecated and will be removed in version 1.0 368 |
    6. 369 |
    370 |
  • 371 |
372 |
373 | 8.11.2009 - version 374 | 0.5 375 |
376 |

377 | Major bugfix release. Changes: 378 |

379 |
    380 |
  • 381 | XPath bugfixes: 382 |
      383 |
    1. 384 | Fixed translate(), lang() and concat() functions (infinite loops/crashes) 385 |
    2. 386 |
    3. 387 | Fixed compilation of queries with empty literal strings ("") 388 |
    4. 389 |
    5. 390 | Fixed axis tests: they never add empty nodes/attributes to the resulting 391 | node set now 392 |
    6. 393 |
    7. 394 | Fixed string-value evaluation for node-set (the result excluded some 395 | text descendants) 396 |
    8. 397 |
    9. 398 | Fixed self:: axis (it behaved like ancestor-or-self::) 399 |
    10. 400 |
    11. 401 | Fixed following:: and preceding:: axes (they included descendent 402 | and ancestor nodes, respectively) 403 |
    12. 404 |
    13. 405 | Minor fix for namespace-uri() function (namespace declaration scope 406 | includes the parent element of namespace declaration attribute) 407 |
    14. 408 |
    15. 409 | Some incorrect queries are no longer parsed now (i.e. foo: *) 410 |
    16. 411 |
    17. 412 | Fixed text()/etc. node test parsing bug (i.e. foo[text()] failed 413 | to compile) 414 |
    18. 415 |
    19. 416 | Fixed root step (/) - it now selects empty node set if query is evaluated 417 | on empty node 418 |
    20. 419 |
    21. 420 | Fixed string to number conversion ("123 " converted to 421 | NaN, "123 .456" converted to 123.456 - now the results 422 | are 123 and NaN, respectively) 423 |
    22. 424 |
    23. 425 | Node set copying now preserves sorted type; leads to better performance 426 | on some queries 427 |
    24. 428 |
    429 |
  • 430 |
  • 431 | Miscellaneous bugfixes: 432 |
      433 |
    1. 434 | Fixed xml_node::offset_debug for PI nodes 435 |
    2. 436 |
    3. 437 | Added empty attribute checks to xml_node::remove_attribute 438 |
    4. 439 |
    5. 440 | Fixed node_pi and node_declaration copying 441 |
    6. 442 |
    7. 443 | Const-correctness fixes 444 |
    8. 445 |
    446 |
  • 447 |
  • 448 | Specification changes: 449 |
      450 |
    1. 451 | xpath_node::select_nodes() and related functions now throw exception 452 | if expression return type is not node set (instead of assertion) 453 |
    2. 454 |
    3. 455 | xml_node::traverse() now sets depth to -1 for both begin() and end() 456 | callbacks (was 0 at begin() and -1 at end()) 457 |
    4. 458 |
    5. 459 | In case of non-raw node printing a newline is output after PCDATA 460 | inside nodes if the PCDATA has siblings 461 |
    6. 462 |
    7. 463 | UTF8 -> wchar_t conversion now considers 5-byte UTF8-like sequences 464 | as invalid 465 |
    8. 466 |
    467 |
  • 468 |
  • 469 | New features: 470 |
      471 |
    1. 472 | Added xpath_node_set::operator[] for index-based iteration 473 |
    2. 474 |
    3. 475 | Added xpath_query::return_type() 476 |
    4. 477 |
    5. 478 | Added getter accessors for memory-management functions 479 |
    6. 480 |
    481 |
  • 482 |
483 |
484 | 17.09.2009 - version 485 | 0.42 486 |
487 |

488 | Maintenance release. Changes: 489 |

490 |
    491 |
  • 492 | Bug fixes: 493 |
      494 |
    1. 495 | Fixed deallocation in case of custom allocation functions or if delete[] 496 | / free are incompatible 497 |
    2. 498 |
    3. 499 | XPath parser fixed for incorrect queries (i.e. incorrect XPath queries 500 | should now always fail to compile) 501 |
    4. 502 |
    5. 503 | Const-correctness fixes for find_child_by_attribute 504 |
    6. 505 |
    7. 506 | Improved compatibility (miscellaneous warning fixes, fixed cstring 507 | include dependency for GCC) 508 |
    8. 509 |
    9. 510 | Fixed iterator begin/end and print function to work correctly for 511 | empty nodes 512 |
    10. 513 |
    514 |
  • 515 |
  • 516 | New features: 517 |
      518 |
    1. 519 | Added PUGIXML_API/PUGIXML_CLASS/PUGIXML_FUNCTION configuration macros 520 | to control class/function attributes 521 |
    2. 522 |
    3. 523 | Added xml_attribute::set_value overloads for different types 524 |
    4. 525 |
    526 |
  • 527 |
528 |
529 | 8.02.2009 - version 530 | 0.41 531 |
532 |

533 | Maintenance release. Changes: 534 |

535 |
  • 536 | Bug fixes: 537 |
    1. 538 | Fixed bug with node printing (occasionally some content was not written 539 | to output stream) 540 |
    541 |
542 |
543 | 18.01.2009 - version 544 | 0.4 545 |
546 |

547 | Changes: 548 |

549 |
    550 |
  • 551 | Bug fixes: 552 |
      553 |
    1. 554 | Documentation fix in samples for parse() with manual lifetime control 555 |
    2. 556 |
    3. 557 | Fixed document order sorting in XPath (it caused wrong order of nodes 558 | after xpath_node_set::sort and wrong results of some XPath queries) 559 |
    4. 560 |
    561 |
  • 562 |
  • 563 | Node printing changes: 564 |
      565 |
    1. 566 | Single quotes are no longer escaped when printing nodes 567 |
    2. 568 |
    3. 569 | Symbols in second half of ASCII table are no longer escaped when 570 | printing nodes; because of this, format_utf8 flag is deleted as it's 571 | no longer needed and format_write_bom is renamed to format_write_bom_utf8. 572 |
    4. 573 |
    5. 574 | Reworked node printing - now it works via xml_writer interface; implementations 575 | for FILE* and std::ostream are available. As a side-effect, xml_document::save_file 576 | now works without STL. 577 |
    6. 578 |
    579 |
  • 580 |
  • 581 | New features: 582 |
      583 |
    1. 584 | Added unsigned integer support for attributes (xml_attribute::as_uint, 585 | xml_attribute::operator=) 586 |
    2. 587 |
    3. 588 | Now document declaration (<?xml ...?>) is parsed as node with 589 | type node_declaration when parse_declaration flag is specified (access 590 | to encoding/version is performed as if they were attributes, i.e. 591 | doc.child("xml").attribute("version").as_float()); 592 | corresponding flags for node printing were also added 593 |
    4. 594 |
    5. 595 | Added support for custom memory management (see set_memory_management_functions 596 | for details) 597 |
    6. 598 |
    7. 599 | Implemented node/attribute copying (see xml_node::insert_copy_* and 600 | xml_node::append_copy for details) 601 |
    8. 602 |
    9. 603 | Added find_child_by_attribute and find_child_by_attribute_w to simplify 604 | parsing code in some cases (i.e. COLLADA files) 605 |
    10. 606 |
    11. 607 | Added file offset information querying for debugging purposes (now 608 | you're able to determine exact location of any xml_node in parsed 609 | file, see xml_node::offset_debug for details) 610 |
    12. 611 |
    13. 612 | Improved error handling for parsing - now load(), load_file() and 613 | parse() return xml_parse_result, which contains error code and last 614 | parsed offset; this does not break old interface as xml_parse_result 615 | can be implicitly casted to bool. 616 |
    14. 617 |
    618 |
  • 619 |
620 |
621 | 31.10.2007 - version 622 | 0.34 623 |
624 |

625 | Maintenance release. Changes: 626 |

627 |
    628 |
  • 629 | Bug fixes: 630 |
      631 |
    1. 632 | Fixed bug with loading from text-mode iostreams 633 |
    2. 634 |
    3. 635 | Fixed leak when transfer_ownership is true and parsing is failing 636 |
    4. 637 |
    5. 638 | Fixed bug in saving (\r and \n are now escaped in attribute values) 639 |
    6. 640 |
    7. 641 | Renamed free() to destroy() - some macro conflicts were reported 642 |
    8. 643 |
    644 |
  • 645 |
  • 646 | New features: 647 |
      648 |
    1. 649 | Improved compatibility (supported Digital Mars C++, MSVC 6, CodeWarrior 650 | 8, PGI C++, Comeau, supported PS3 and XBox360) 651 |
    2. 652 |
    3. 653 | PUGIXML_NO_EXCEPTION flag for platforms without exception handling 654 |
    4. 655 |
    656 |
  • 657 |
658 |
659 | 21.02.2007 - version 660 | 0.3 661 |
662 |

663 | Refactored, reworked and improved version. Changes: 664 |

665 |
    666 |
  • 667 | Interface: 668 |
      669 |
    1. 670 | Added XPath 671 |
    2. 672 |
    3. 673 | Added tree modification functions 674 |
    4. 675 |
    5. 676 | Added no STL compilation mode 677 |
    6. 678 |
    7. 679 | Added saving document to file 680 |
    8. 681 |
    9. 682 | Refactored parsing flags 683 |
    10. 684 |
    11. 685 | Removed xml_parser class in favor of xml_document 686 |
    12. 687 |
    13. 688 | Added transfer ownership parsing mode 689 |
    14. 690 |
    15. 691 | Modified the way xml_tree_walker works 692 |
    16. 693 |
    17. 694 | Iterators are now non-constant 695 |
    18. 696 |
    697 |
  • 698 |
  • 699 | Implementation: 700 |
      701 |
    1. 702 | Support of several compilers and platforms 703 |
    2. 704 |
    3. 705 | Refactored and sped up parsing core 706 |
    4. 707 |
    5. 708 | Improved standard compliancy 709 |
    6. 710 |
    7. 711 | Added XPath implementation 712 |
    8. 713 |
    9. 714 | Fixed several bugs 715 |
    10. 716 |
    717 |
  • 718 |
719 |
720 | 6.11.2006 - version 721 | 0.2 722 |
723 |

724 | First public release. Changes: 725 |

726 |
    727 |
  • 728 | Bug fixes: 729 |
      730 |
    1. 731 | Fixed child_value() (for empty nodes) 732 |
    2. 733 |
    3. 734 | Fixed xml_parser_impl warning at W4 735 |
    4. 736 |
    737 |
  • 738 |
  • 739 | New features: 740 |
      741 |
    1. 742 | Introduced child_value(name) and child_value_w(name) 743 |
    2. 744 |
    3. 745 | parse_eol_pcdata and parse_eol_attribute flags + parse_minimal optimizations 746 |
    4. 747 |
    5. 748 | Optimizations of strconv_t 749 |
    6. 750 |
    751 |
  • 752 |
753 |
754 | 15.07.2006 - version 755 | 0.1 756 |
757 |

758 | First private release for testing purposes 759 |

760 |
761 | 762 | 763 | 767 |
768 |
769 | 770 | 780 | 783 |
771 | pugixml 1.0 manual | 772 | Overview | 773 | Installation | 774 | Document: 775 | Object model · Loading · Accessing · Modifying · Saving | 776 | XPath | 777 | API Reference | 778 | Table of Contents 779 |
781 | PrevUpHomeNext 782 |
784 | 785 | 786 | -------------------------------------------------------------------------------- /docs/manual/install.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Installation 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 24 | 27 |
15 | pugixml 1.0 manual | 16 | Overview | 17 | Installation | 18 | Document: 19 | Object model · Loading · Accessing · Modifying · Saving | 20 | XPath | 21 | API Reference | 22 | Table of Contents 23 |
25 | PrevUpHomeNext 26 |
28 |
29 |
30 |

31 | Installation 32 |

33 | 52 |
53 |

54 | Getting pugixml 55 |

56 |

57 | pugixml is distributed in source form. You can either download a source distribution 58 | or checkout the Subversion repository. 59 |

60 |
61 | 64 |

65 | You can download the latest source distribution via one of the following 66 | links: 67 |

68 |
http://pugixml.googlecode.com/files/pugixml-1.0.zip
 69 | http://pugixml.googlecode.com/files/pugixml-1.0.tar.gz
 70 | 
71 |

72 | The distribution contains library source, documentation (the manual you're 73 | reading now and the quick start guide) and some code examples. After downloading 74 | the distribution, install pugixml by extracting all files from the compressed 75 | archive. The files have different line endings depending on the archive 76 | format - .zip archive has Windows line endings, .tar.gz archive has Unix 77 | line endings. Otherwise the files in both archives are identical. 78 |

79 |

80 | If you need an older version, you can download it from the version 81 | archive. 82 |

83 |
84 |
85 | 88 |

89 | The Subversion repository is located at http://pugixml.googlecode.com/svn/. 90 | There is a Subversion tag "release-{version}" for each version; 91 | also there is the "latest" tag, which always points to the latest 92 | stable release. 93 |

94 |

95 | For example, to checkout the current version, you can use this command: 96 |

97 |
svn checkout http://pugixml.googlecode.com/svn/tags/release-1.0 pugixml
98 |

99 | To checkout the latest version, you can use this command: 100 |

101 |
svn checkout http://pugixml.googlecode.com/svn/tags/latest pugixml
102 |

103 | The repository contains library source, documentation, code examples and 104 | full unit test suite. 105 |

106 |

107 | Use latest version tag if you want to automatically get new versions via 108 | svn update. Use other tags if you want to switch to 109 | new versions only explicitly (for example, using svn switch 110 | command). Also please note that Subversion trunk contains the work-in-progress 111 | version of the code; while this means that you can get new features and 112 | bug fixes from trunk without waiting for a new release, this also means 113 | that occasionally the code can be broken in some configurations. 114 |

115 |
116 |
117 |
118 |

119 | Building pugixml 120 |

121 |

122 | pugixml is distributed in source form without any pre-built binaries; you 123 | have to build them yourself. 124 |

125 |

126 | The complete pugixml source consists of three files - one source file, pugixml.cpp, 127 | and two header files, pugixml.hpp and pugiconfig.hpp. pugixml.hpp is the primary 128 | header which you need to include in order to use pugixml classes/functions; 129 | pugiconfig.hpp is a supplementary configuration file (see Additional configuration 130 | options). 131 | The rest of this guide assumes that pugixml.hpp is either in the current directory 132 | or in one of include directories of your projects, so that #include "pugixml.hpp" 133 | can find the header; however you can also use relative path (i.e. #include "../libs/pugixml/src/pugixml.hpp") 134 | or include directory-relative path (i.e. #include 135 | <xml/thirdparty/pugixml/src/pugixml.hpp>). 136 |

137 |
138 | 142 |

143 | The easiest way to build pugixml is to compile the source file, pugixml.cpp, 144 | along with the existing library/executable. This process depends on the 145 | method of building your application; for example, if you're using Microsoft 146 | Visual Studio[1], Apple Xcode, Code::Blocks or any other IDE, just add pugixml.cpp to 147 | one of your projects. 148 |

149 |

150 | If you're using Microsoft Visual Studio and the project has precompiled 151 | headers turned on, you'll see the following error messages: 152 |

153 |
pugixml.cpp(3477) : fatal error C1010: unexpected end of file while looking for precompiled header. Did you forget to add '#include "stdafx.h"' to your source?
154 |

155 | The correct way to resolve this is to disable precompiled headers for pugixml.cpp; 156 | you have to set "Create/Use Precompiled Header" option (Properties 157 | dialog -> C/C++ -> Precompiled Headers -> Create/Use Precompiled 158 | Header) to "Not Using Precompiled Headers". You'll have to do 159 | it for all project configurations/platforms (you can select Configuration 160 | "All Configurations" and Platform "All Platforms" before 161 | editing the option): 162 |

163 |
164 | 165 | 170 |
166 |

167 | vs2005_pch1_thumb next vs2005_pch2_thumb next vs2005_pch3_thumb next vs2005_pch4_thumb 168 |

169 |
171 |
172 |
173 | 177 |

178 | It's possible to compile pugixml as a standalone static library. This process 179 | depends on the method of building your application; pugixml distribution 180 | comes with project files for several popular IDEs/build systems. There 181 | are project files for Apple XCode3, Code::Blocks, Codelite, Microsoft Visual 182 | Studio 2005, 2008, 2010, and configuration scripts for CMake and premake4. 183 | You're welcome to submit project files/build scripts for other software; 184 | see Feedback. 185 |

186 |

187 | There are two projects for each version of Microsoft Visual Studio: one 188 | for dynamically linked CRT, which has a name like pugixml_vs2008.vcproj, 189 | and another one for statically linked CRT, which has a name like pugixml_vs2008_static.vcproj. 190 | You should select the version that matches the CRT used in your application; 191 | the default option for new projects created by Microsoft Visual Studio 192 | is dynamically linked CRT, so unless you changed the defaults, you should 193 | use the version with dynamic CRT (i.e. pugixml_vs2008.vcproj for Microsoft 194 | Visual Studio 2008). 195 |

196 |

197 | In addition to adding pugixml project to your workspace, you'll have to 198 | make sure that your application links with pugixml library. If you're using 199 | Microsoft Visual Studio 2005/2008, you can add a dependency from your application 200 | project to pugixml one. If you're using Microsoft Visual Studio 2010, you'll 201 | have to add a reference to your application project instead. For other 202 | IDEs/systems, consult the relevant documentation. 203 |

204 |
205 | 206 | 207 | 208 | 209 | 210 | 215 | 220 | 221 | 222 | 227 | 232 | 233 |
211 |

212 | Microsoft Visual Studio 2005/2008 213 |

214 |
216 |

217 | Microsoft Visual Studio 2010 218 |

219 |
223 |

224 | vs2005_link1_thumb next vs2005_link2_thumb 225 |

226 |
228 |

229 | vs2010_link1_thumb next vs2010_link2_thumb 230 |

231 |
234 |
235 |
236 | 240 |

241 | It's possible to compile pugixml as a standalone shared library. The process 242 | is usually similar to the static library approach; however, no preconfigured 243 | projects/scripts are included into pugixml distribution, so you'll have 244 | to do it yourself. Generally, if you're using GCC-based toolchain, the 245 | process does not differ from building any other library as DLL (adding 246 | -shared to compilation flags should suffice); if you're using MSVC-based 247 | toolchain, you'll have to explicitly mark exported symbols with a declspec 248 | attribute. You can do it by defining PUGIXML_API 249 | macro, i.e. via pugiconfig.hpp: 250 |

251 |
#ifdef _DLL
252 | #define PUGIXML_API __declspec(dllexport)
253 | #else
254 | #define PUGIXML_API __declspec(dllimport)
255 | #endif
256 | 
257 |
258 | 259 | 260 | 261 | 262 | 270 |
[Caution]Caution

263 | If you're using STL-related functions, you should use the shared runtime 264 | library to ensure that a single heap is used for STL allocations in your 265 | application and in pugixml; in MSVC, this means selecting the 'Multithreaded 266 | DLL' or 'Multithreaded Debug DLL' to 'Runtime library' property (/MD 267 | or /MDd linker switch). You should also make sure that your runtime library 268 | choice is consistent between different projects. 269 |

271 |
272 |
273 | 277 |

278 | pugixml uses several defines to control the compilation process. There 279 | are two ways to define them: either put the needed definitions to pugiconfig.hpp (it 280 | has some examples that are commented out) or provide them via compiler 281 | command-line. Consistency is important: the definitions should match in 282 | all source files that include pugixml.hpp (including pugixml sources) throughout 283 | the application. Adding defines to pugiconfig.hpp lets you guarantee this, 284 | unless your macro definition is wrapped in preprocessor #if/#ifdef directive and this directive 285 | is not consistent. pugiconfig.hpp will never contain anything but comments, 286 | which means that when upgrading to a new version, you can safely leave 287 | your modified version intact. 288 |

289 |

290 | PUGIXML_WCHAR_MODE define toggles 291 | between UTF-8 style interface (the in-memory text encoding is assumed to 292 | be UTF-8, most functions use char 293 | as character type) and UTF-16/32 style interface (the in-memory text encoding 294 | is assumed to be UTF-16/32, depending on wchar_t 295 | size, most functions use wchar_t 296 | as character type). See Unicode interface for more details. 297 |

298 |

299 | PUGIXML_NO_XPATH define disables XPath. 300 | Both XPath interfaces and XPath implementation are excluded from compilation. 301 | This option is provided in case you do not need XPath functionality and 302 | need to save code space. 303 |

304 |

305 | PUGIXML_NO_STL define disables use of 306 | STL in pugixml. The functions that operate on STL types are no longer present 307 | (i.e. load/save via iostream) if this macro is defined. This option is 308 | provided in case your target platform does not have a standard-compliant 309 | STL implementation. 310 |

311 |

312 | PUGIXML_NO_EXCEPTIONS define disables 313 | use of exceptions in pugixml. This option is provided in case your target 314 | platform does not have exception handling capabilities. 315 |

316 |

317 | PUGIXML_API, PUGIXML_CLASS 318 | and PUGIXML_FUNCTION defines let you 319 | specify custom attributes (i.e. declspec or calling conventions) for pugixml 320 | classes and non-member functions. In absence of PUGIXML_CLASS 321 | or PUGIXML_FUNCTION definitions, 322 | PUGIXML_API definition 323 | is used instead. For example, to specify fixed calling convention, you 324 | can define PUGIXML_FUNCTION 325 | to i.e. __fastcall. Another 326 | example is DLL import/export attributes in MSVC (see Building pugixml as 327 | a standalone shared library). 328 |

329 |
330 | 331 | 332 | 333 | 334 | 339 |
[Note]Note

335 | In that example PUGIXML_API 336 | is inconsistent between several source files; this is an exception to 337 | the consistency rule. 338 |

340 |
341 |
342 |
343 |

344 | Portability 345 |

346 |

347 | pugixml is written in standard-compliant C++ with some compiler-specific 348 | workarounds where appropriate. pugixml is compatible with the upcoming C++0x 349 | standard (verified using GCC 4.5). Each version is tested with a unit test 350 | suite (with code coverage about 99%) on the following platforms: 351 |

352 |
    353 |
  • 354 | Microsoft Windows: 355 |
      356 |
    • 357 | Borland C++ Compiler 5.82 358 |
    • 359 |
    • 360 | Digital Mars C++ Compiler 8.51 361 |
    • 362 |
    • 363 | Intel C++ Compiler 8.0, 9.0 x86/x64, 10.0 x86/x64, 11.0 x86/x64 364 |
    • 365 |
    • 366 | Metrowerks CodeWarrior 8.0 367 |
    • 368 |
    • 369 | Microsoft Visual C++ 6.0, 7.0 (2002), 7.1 (2003), 8.0 (2005) x86/x64, 370 | 9.0 (2008) x86/x64, 10.0 (2010) x86/x64 371 |
    • 372 |
    • 373 | MinGW (GCC) 3.4, 4.4, 4.5, 4.6 x64 374 |
    • 375 |
    376 |
  • 377 |
  • 378 | Linux (GCC 4.4.3 x86/x64) 379 |
  • 380 |
  • 381 | FreeBSD (GCC 4.2.1 x86/x64) 382 |
  • 383 |
  • 384 | Apple MacOSX (GCC 4.0.1 x86/x64/PowerPC) 385 |
  • 386 |
  • 387 | Microsoft Xbox 360 388 |
  • 389 |
  • 390 | Nintendo Wii (Metrowerks CodeWarrior 4.1) 391 |
  • 392 |
  • 393 | Sony Playstation Portable (GCC 3.4.2) 394 |
  • 395 |
  • 396 | Sony Playstation 3 (GCC 4.1.1, SNC 310.1) 397 |
  • 398 |
399 |
400 |
401 |

402 |

[1] All trademarks used are properties of their respective 403 | owners.

404 |
405 |
406 | 407 | 408 | 412 |
413 |
414 | 415 | 425 | 428 |
416 | pugixml 1.0 manual | 417 | Overview | 418 | Installation | 419 | Document: 420 | Object model · Loading · Accessing · Modifying · Saving | 421 | XPath | 422 | API Reference | 423 | Table of Contents 424 |
426 | PrevUpHomeNext 427 |
429 | 430 | 431 | -------------------------------------------------------------------------------- /docs/manual/toc.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Table of Contents 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 23 | 26 |
14 | pugixml 1.0 manual | 15 | Overview | 16 | Installation | 17 | Document: 18 | Object model · Loading · Accessing · Modifying · Saving | 19 | XPath | 20 | API Reference | 21 | Table of Contents 22 |
24 | PrevUpHome 25 |
27 |
28 |
29 | 32 |
33 |
Overview
34 |
35 |
Introduction
36 |
Feedback
37 |
Acknowledgments
38 |
License
39 |
40 |
Installation
41 |
42 |
Getting pugixml
43 |
44 |
Source distributions
45 |
Subversion repository
46 |
47 |
Building pugixml
48 |
49 |
Building pugixml as 50 | a part of another static library/executable
51 |
Building pugixml as 52 | a standalone static library
53 |
Building pugixml as 54 | a standalone shared library
55 |
Additional configuration 56 | options
57 |
58 |
Portability
59 |
60 |
Document object model
61 |
62 |
Tree structure
63 |
C++ interface
64 |
Unicode interface
65 |
Thread-safety guarantees
66 |
Exception guarantees
67 |
Memory management
68 |
69 |
Custom memory allocation/deallocation 70 | functions
71 |
Document memory management 72 | internals
73 |
74 |
75 |
Loading document
76 |
77 |
Loading document from file
78 |
Loading document from memory
79 |
Loading document from C++ IOstreams
80 |
Handling parsing errors
81 |
Parsing options
82 |
Encodings
83 |
Conformance to W3C specification
84 |
85 |
Accessing document data
86 |
87 |
Basic traversal functions
88 |
Getting node data
89 |
Getting attribute data
90 |
Contents-based traversal functions
91 |
Traversing node/attribute lists 92 | via iterators
93 |
Recursive traversal with xml_tree_walker
94 |
Searching for nodes/attributes 95 | with predicates
96 |
Miscellaneous functions
97 |
98 |
Modifying document data
99 |
100 |
Setting node data
101 |
Setting attribute data
102 |
Adding nodes/attributes
103 |
Removing nodes/attributes
104 |
Cloning nodes/attributes
105 |
106 |
Saving document
107 |
108 |
Saving document to a file
109 |
Saving document to C++ IOstreams
110 |
Saving document via writer interface
111 |
Saving a single subtree
112 |
Output options
113 |
Encodings
114 |
115 |
XPath
116 |
117 |
XPath types
118 |
Selecting nodes via XPath expression
119 |
Using query objects
120 |
Using variables
121 |
Error handling
122 |
Conformance to W3C specification
123 |
124 |
Changelog
125 |
API Reference
126 |
Table of Contents
127 |
128 |
129 | 130 | 131 | 135 |
136 |
137 | 138 | 148 | 151 |
139 | pugixml 1.0 manual | 140 | Overview | 141 | Installation | 142 | Document: 143 | Object model · Loading · Accessing · Modifying · Saving | 144 | XPath | 145 | API Reference | 146 | Table of Contents 147 |
149 | PrevUpHome 150 |
152 | 153 | 154 | -------------------------------------------------------------------------------- /docs/pugixml.css: -------------------------------------------------------------------------------- 1 | /*============================================================================= 2 | Copyright (c) 2004 Joel de Guzman 3 | http://spirit.sourceforge.net/ 4 | 5 | Distributed under the Boost Software License, Version 1.0. (See accompany- 6 | ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 | =============================================================================*/ 8 | 9 | /*============================================================================= 10 | Body defaults 11 | =============================================================================*/ 12 | 13 | body 14 | { 15 | margin: 1em; 16 | font-family: sans-serif; 17 | } 18 | 19 | /*============================================================================= 20 | Paragraphs 21 | =============================================================================*/ 22 | 23 | p 24 | { 25 | text-align: left; 26 | font-size: 10pt; 27 | line-height: 1.15; 28 | } 29 | 30 | /*============================================================================= 31 | Program listings 32 | =============================================================================*/ 33 | 34 | /* Code on paragraphs */ 35 | p tt.computeroutput 36 | { 37 | font-size: 9pt; 38 | } 39 | 40 | pre.synopsis 41 | { 42 | font-size: 90%; 43 | margin: 1pc 4% 0pc 4%; 44 | padding: 0.5pc 0.5pc 0.5pc 0.5pc; 45 | } 46 | 47 | .programlisting, 48 | .screen 49 | { 50 | font-size: 9pt; 51 | display: block; 52 | margin: 1pc 4% 0pc 4%; 53 | padding: 0.5pc 0.5pc 0.5pc 0.5pc; 54 | } 55 | 56 | /* Program listings in tables don't get borders */ 57 | td .programlisting, 58 | td .screen 59 | { 60 | margin: 0pc 0pc 0pc 0pc; 61 | padding: 0pc 0pc 0pc 0pc; 62 | } 63 | 64 | /*============================================================================= 65 | Headings 66 | =============================================================================*/ 67 | 68 | h1, h2, h3, h4, h5, h6 69 | { 70 | text-align: left; 71 | margin: 1em 0em 0.5em 0em; 72 | font-weight: bold; 73 | } 74 | 75 | h1 { font: 140% } 76 | h2 { font: bold 140% } 77 | h3 { font: bold 130% } 78 | h4 { font: bold 120% } 79 | h5 { font: italic 110% } 80 | h6 { font: italic 100% } 81 | 82 | /* Top page titles */ 83 | title, 84 | h1.title, 85 | h2.title 86 | h3.title, 87 | h4.title, 88 | h5.title, 89 | h6.title, 90 | .refentrytitle 91 | { 92 | font-weight: bold; 93 | margin-bottom: 1pc; 94 | } 95 | 96 | h1.title { font-size: 140% } 97 | h2.title { font-size: 140% } 98 | h3.title { font-size: 130% } 99 | h4.title { font-size: 120% } 100 | h5.title { font-size: 110% } 101 | h6.title { font-size: 100% } 102 | 103 | .section h1 104 | { 105 | margin: 0em 0em 0.5em 0em; 106 | font-size: 140%; 107 | } 108 | 109 | .section h2 { font-size: 140% } 110 | .section h3 { font-size: 130% } 111 | .section h4 { font-size: 120% } 112 | .section h5 { font-size: 110% } 113 | .section h6 { font-size: 100% } 114 | 115 | /* Code on titles */ 116 | h1 tt.computeroutput { font-size: 140% } 117 | h2 tt.computeroutput { font-size: 140% } 118 | h3 tt.computeroutput { font-size: 130% } 119 | h4 tt.computeroutput { font-size: 130% } 120 | h5 tt.computeroutput { font-size: 130% } 121 | h6 tt.computeroutput { font-size: 130% } 122 | 123 | 124 | /*============================================================================= 125 | Author 126 | =============================================================================*/ 127 | 128 | h3.author 129 | { 130 | font-size: 100% 131 | } 132 | 133 | /*============================================================================= 134 | Lists 135 | =============================================================================*/ 136 | 137 | li 138 | { 139 | font-size: 10pt; 140 | line-height: 1.3; 141 | } 142 | 143 | /* Unordered lists */ 144 | ul 145 | { 146 | text-align: left; 147 | } 148 | 149 | /* Ordered lists */ 150 | ol 151 | { 152 | text-align: left; 153 | } 154 | 155 | /*============================================================================= 156 | Links 157 | =============================================================================*/ 158 | 159 | a 160 | { 161 | text-decoration: none; /* no underline */ 162 | } 163 | 164 | a:hover 165 | { 166 | text-decoration: underline; 167 | } 168 | 169 | /*============================================================================= 170 | Spirit style navigation 171 | =============================================================================*/ 172 | 173 | .spirit-nav 174 | { 175 | text-align: right; 176 | } 177 | 178 | .spirit-nav a 179 | { 180 | color: white; 181 | padding-left: 0.5em; 182 | } 183 | 184 | .spirit-nav img 185 | { 186 | border-width: 0px; 187 | } 188 | 189 | /*============================================================================= 190 | Copyright footer 191 | =============================================================================*/ 192 | .copyright-footer 193 | { 194 | text-align: right; 195 | font-size: 70%; 196 | } 197 | 198 | .copyright-footer p 199 | { 200 | text-align: right; 201 | font-size: 80%; 202 | } 203 | 204 | /*============================================================================= 205 | Table of contents 206 | =============================================================================*/ 207 | 208 | .toc 209 | { 210 | margin: 1pc 4% 0pc 4%; 211 | padding: 0.1pc 1pc 0.1pc 1pc; 212 | font-size: 80%; 213 | line-height: 1.15; 214 | } 215 | 216 | .boost-toc 217 | { 218 | float: right; 219 | padding: 0.5pc; 220 | } 221 | 222 | /* Code on toc */ 223 | .toc .computeroutput { font-size: 120% } 224 | 225 | /*============================================================================= 226 | Tables 227 | =============================================================================*/ 228 | 229 | .table-title, 230 | div.table p.title 231 | { 232 | margin-left: 4%; 233 | padding-right: 0.5em; 234 | padding-left: 0.5em; 235 | } 236 | 237 | .informaltable table, 238 | .table table 239 | { 240 | width: 92%; 241 | margin-left: 4%; 242 | margin-right: 4%; 243 | } 244 | 245 | div.informaltable table, 246 | div.table table 247 | { 248 | padding: 4px; 249 | } 250 | 251 | /* Table Cells */ 252 | div.informaltable table tr td, 253 | div.table table tr td 254 | { 255 | padding: 0.5em; 256 | text-align: left; 257 | font-size: 9pt; 258 | } 259 | 260 | div.informaltable table tr th, 261 | div.table table tr th 262 | { 263 | padding: 0.5em 0.5em 0.5em 0.5em; 264 | border: 1pt solid white; 265 | font-size: 80%; 266 | } 267 | 268 | table.simplelist 269 | { 270 | width: auto !important; 271 | margin: 0em !important; 272 | padding: 0em !important; 273 | border: none !important; 274 | } 275 | table.simplelist td 276 | { 277 | margin: 0em !important; 278 | padding: 0em !important; 279 | text-align: left !important; 280 | font-size: 9pt !important; 281 | border: none !important; 282 | } 283 | 284 | /*============================================================================= 285 | Blurbs 286 | =============================================================================*/ 287 | 288 | div.note, 289 | div.tip, 290 | div.important, 291 | div.caution, 292 | div.warning, 293 | p.blurb 294 | { 295 | font-size: 9pt; /* A little bit smaller than the main text */ 296 | line-height: 1.2; 297 | display: block; 298 | margin: 1pc 4% 0pc 4%; 299 | padding: 0.5pc 0.5pc 0.5pc 0.5pc; 300 | } 301 | 302 | p.blurb img 303 | { 304 | padding: 1pt; 305 | } 306 | 307 | /*============================================================================= 308 | Variable Lists 309 | =============================================================================*/ 310 | 311 | div.variablelist 312 | { 313 | margin: 1em 0; 314 | } 315 | 316 | /* Make the terms in definition lists bold */ 317 | div.variablelist dl dt, 318 | span.term 319 | { 320 | font-weight: bold; 321 | font-size: 10pt; 322 | } 323 | 324 | div.variablelist table tbody tr td 325 | { 326 | text-align: left; 327 | vertical-align: top; 328 | padding: 0em 2em 0em 0em; 329 | font-size: 10pt; 330 | margin: 0em 0em 0.5em 0em; 331 | line-height: 1; 332 | } 333 | 334 | div.variablelist dl dt 335 | { 336 | margin-bottom: 0.2em; 337 | } 338 | 339 | div.variablelist dl dd 340 | { 341 | margin: 0em 0em 0.5em 2em; 342 | font-size: 10pt; 343 | } 344 | 345 | div.variablelist table tbody tr td p, 346 | div.variablelist dl dd p 347 | { 348 | margin: 0em 0em 0.5em 0em; 349 | line-height: 1; 350 | } 351 | 352 | /*============================================================================= 353 | Misc 354 | =============================================================================*/ 355 | 356 | /* Title of books and articles in bibliographies */ 357 | span.title 358 | { 359 | font-style: italic; 360 | } 361 | 362 | span.underline 363 | { 364 | text-decoration: underline; 365 | } 366 | 367 | span.strikethrough 368 | { 369 | text-decoration: line-through; 370 | } 371 | 372 | /* Copyright, Legal Notice */ 373 | div div.legalnotice p 374 | { 375 | text-align: left 376 | } 377 | 378 | /*============================================================================= 379 | Colors 380 | =============================================================================*/ 381 | 382 | @media screen 383 | { 384 | body { 385 | background-color: #FFFFFF; 386 | color: #000000; 387 | } 388 | 389 | /* Links */ 390 | a 391 | { 392 | color: #005a9c; 393 | } 394 | 395 | a:visited 396 | { 397 | color: #9c5a9c; 398 | } 399 | 400 | h1 a, h2 a, h3 a, h4 a, h5 a, h6 a, 401 | h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover, 402 | h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited 403 | { 404 | text-decoration: none; /* no underline */ 405 | color: #000000; 406 | } 407 | 408 | /* Syntax Highlighting */ 409 | .keyword { color: #0000AA; } 410 | .identifier { color: #000000; } 411 | .special { color: #707070; } 412 | .preprocessor { color: #402080; } 413 | .char { color: teal; } 414 | .comment { color: #800000; } 415 | .string { color: teal; } 416 | .number { color: teal; } 417 | .white_bkd { background-color: #FFFFFF; } 418 | .dk_grey_bkd { background-color: #999999; } 419 | 420 | /* Copyright, Legal Notice */ 421 | .copyright 422 | { 423 | color: #666666; 424 | font-size: small; 425 | } 426 | 427 | div div.legalnotice p 428 | { 429 | color: #666666; 430 | } 431 | 432 | /* Program listing */ 433 | pre.synopsis 434 | { 435 | border: 1px solid #DCDCDC; 436 | } 437 | 438 | .programlisting, 439 | .screen 440 | { 441 | border: 1px solid #DCDCDC; 442 | } 443 | 444 | td .programlisting, 445 | td .screen 446 | { 447 | border: 0px solid #DCDCDC; 448 | } 449 | 450 | /* Blurbs */ 451 | div.note, 452 | div.tip, 453 | div.important, 454 | div.caution, 455 | div.warning, 456 | p.blurb 457 | { 458 | border: 1px solid #DCDCDC; 459 | } 460 | 461 | /* Table of contents */ 462 | .toc 463 | { 464 | border: 1px solid #DCDCDC; 465 | } 466 | 467 | /* Tables */ 468 | div.informaltable table tr td, 469 | div.table table tr td 470 | { 471 | border: 1px solid #DCDCDC; 472 | } 473 | 474 | div.informaltable table tr th, 475 | div.table table tr th 476 | { 477 | background-color: #F0F0F0; 478 | border: 1px solid #DCDCDC; 479 | } 480 | 481 | .copyright-footer 482 | { 483 | color: #8F8F8F; 484 | } 485 | 486 | /* Misc */ 487 | span.highlight 488 | { 489 | color: #00A000; 490 | } 491 | } 492 | 493 | @media print 494 | { 495 | /* Links */ 496 | a 497 | { 498 | color: black; 499 | } 500 | 501 | a:visited 502 | { 503 | color: black; 504 | } 505 | 506 | .spirit-nav 507 | { 508 | display: none; 509 | } 510 | 511 | /* Program listing */ 512 | pre.synopsis 513 | { 514 | border: 1px solid gray; 515 | } 516 | 517 | .programlisting, 518 | .screen 519 | { 520 | border: 1px solid gray; 521 | } 522 | 523 | td .programlisting, 524 | td .screen 525 | { 526 | border: 0px solid #DCDCDC; 527 | } 528 | 529 | /* Table of contents */ 530 | .toc 531 | { 532 | border: 1px solid gray; 533 | } 534 | 535 | .informaltable table, 536 | .table table 537 | { 538 | border: 1px solid gray; 539 | border-collapse: collapse; 540 | } 541 | 542 | /* Tables */ 543 | div.informaltable table tr td, 544 | div.table table tr td 545 | { 546 | border: 1px solid gray; 547 | } 548 | 549 | div.informaltable table tr th, 550 | div.table table tr th 551 | { 552 | border: 1px solid gray; 553 | } 554 | 555 | table.simplelist tr td 556 | { 557 | border: none !important; 558 | } 559 | 560 | /* Misc */ 561 | span.highlight 562 | { 563 | font-weight: bold; 564 | } 565 | } 566 | 567 | /*============================================================================= 568 | Images 569 | =============================================================================*/ 570 | 571 | span.inlinemediaobject img 572 | { 573 | vertical-align: middle; 574 | } 575 | 576 | /*============================================================================== 577 | Super and Subscript: style so that line spacing isn't effected, see 578 | http://www.adobe.com/cfusion/communityengine/index.cfm?event=showdetails&productId=1&postId=5341 579 | ==============================================================================*/ 580 | 581 | sup, 582 | sub { 583 | height: 0; 584 | line-height: 1; 585 | vertical-align: baseline; 586 | _vertical-align: bottom; 587 | position: relative; 588 | 589 | } 590 | 591 | sup { 592 | bottom: 1ex; 593 | } 594 | 595 | sub { 596 | top: .5ex; 597 | } 598 | 599 | -------------------------------------------------------------------------------- /docs/samples/character.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /docs/samples/custom_memory_management.cpp: -------------------------------------------------------------------------------- 1 | #include "pugixml.hpp" 2 | 3 | #include 4 | 5 | //[code_custom_memory_management_decl 6 | void* custom_allocate(size_t size) 7 | { 8 | return new (std::nothrow) char[size]; 9 | } 10 | 11 | void custom_deallocate(void* ptr) 12 | { 13 | delete[] static_cast(ptr); 14 | } 15 | //] 16 | 17 | int main() 18 | { 19 | //[code_custom_memory_management_call 20 | pugi::set_memory_management_functions(custom_allocate, custom_deallocate); 21 | //] 22 | 23 | pugi::xml_document doc; 24 | doc.load(""); 25 | } 26 | 27 | // vim:et 28 | -------------------------------------------------------------------------------- /docs/samples/include.cpp: -------------------------------------------------------------------------------- 1 | #include "pugixml.hpp" 2 | 3 | #include 4 | #include 5 | 6 | //[code_include 7 | bool load_preprocess(pugi::xml_document& doc, const char* path); 8 | 9 | bool preprocess(pugi::xml_node node) 10 | { 11 | for (pugi::xml_node child = node.first_child(); child; ) 12 | { 13 | if (child.type() == pugi::node_pi && strcmp(child.name(), "include") == 0) 14 | { 15 | pugi::xml_node include = child; 16 | 17 | // load new preprocessed document (note: ideally this should handle relative paths) 18 | const char* path = include.value(); 19 | 20 | pugi::xml_document doc; 21 | if (!load_preprocess(doc, path)) return false; 22 | 23 | // insert the comment marker above include directive 24 | node.insert_child_before(pugi::node_comment, include).set_value(path); 25 | 26 | // copy the document above the include directive (this retains the original order!) 27 | for (pugi::xml_node ic = doc.first_child(); ic; ic = ic.next_sibling()) 28 | { 29 | node.insert_copy_before(ic, include); 30 | } 31 | 32 | // remove the include node and move to the next child 33 | child = child.next_sibling(); 34 | 35 | node.remove_child(include); 36 | } 37 | else 38 | { 39 | if (!preprocess(child)) return false; 40 | 41 | child = child.next_sibling(); 42 | } 43 | } 44 | 45 | return true; 46 | } 47 | 48 | bool load_preprocess(pugi::xml_document& doc, const char* path) 49 | { 50 | pugi::xml_parse_result result = doc.load_file(path, pugi::parse_default | pugi::parse_pi); // for 51 | 52 | return result ? preprocess(doc) : false; 53 | } 54 | //] 55 | 56 | int main() 57 | { 58 | pugi::xml_document doc; 59 | if (!load_preprocess(doc, "character.xml")) return -1; 60 | 61 | doc.print(std::cout); 62 | } 63 | 64 | // vim:et 65 | -------------------------------------------------------------------------------- /docs/samples/load_error_handling.cpp: -------------------------------------------------------------------------------- 1 | #include "pugixml.hpp" 2 | 3 | #include 4 | 5 | void check_xml(const char* source) 6 | { 7 | //[code_load_error_handling 8 | pugi::xml_document doc; 9 | pugi::xml_parse_result result = doc.load(source); 10 | 11 | if (result) 12 | std::cout << "XML [" << source << "] parsed without errors, attr value: [" << doc.child("node").attribute("attr").value() << "]\n\n"; 13 | else 14 | { 15 | std::cout << "XML [" << source << "] parsed with errors, attr value: [" << doc.child("node").attribute("attr").value() << "]\n"; 16 | std::cout << "Error description: " << result.description() << "\n"; 17 | std::cout << "Error offset: " << result.offset << " (error at [..." << (source + result.offset) << "]\n\n"; 18 | } 19 | //] 20 | } 21 | 22 | int main() 23 | { 24 | check_xml("text"); 25 | check_xml("text"); 26 | check_xml("text"); 27 | check_xml("<#tag />"); 29 | } 30 | 31 | // vim:et 32 | -------------------------------------------------------------------------------- /docs/samples/load_file.cpp: -------------------------------------------------------------------------------- 1 | #include "pugixml.hpp" 2 | 3 | #include 4 | 5 | int main() 6 | { 7 | //[code_load_file 8 | pugi::xml_document doc; 9 | 10 | pugi::xml_parse_result result = doc.load_file("tree.xml"); 11 | 12 | std::cout << "Load result: " << result.description() << ", mesh name: " << doc.child("mesh").attribute("name").value() << std::endl; 13 | //] 14 | } 15 | 16 | // vim:et 17 | -------------------------------------------------------------------------------- /docs/samples/load_memory.cpp: -------------------------------------------------------------------------------- 1 | #include "pugixml.hpp" 2 | 3 | #include 4 | 5 | int main() 6 | { 7 | //[code_load_memory_decl 8 | const char source[] = "0 0 1 1"; 9 | size_t size = sizeof(source); 10 | //] 11 | 12 | pugi::xml_document doc; 13 | 14 | { 15 | //[code_load_memory_buffer 16 | // You can use load_buffer to load document from immutable memory block: 17 | pugi::xml_parse_result result = doc.load_buffer(source, size); 18 | //] 19 | 20 | std::cout << "Load result: " << result.description() << ", mesh name: " << doc.child("mesh").attribute("name").value() << std::endl; 21 | } 22 | 23 | { 24 | //[code_load_memory_buffer_inplace 25 | // You can use load_buffer_inplace to load document from mutable memory block; the block's lifetime must exceed that of document 26 | char* buffer = new char[size]; 27 | memcpy(buffer, source, size); 28 | 29 | // The block can be allocated by any method; the block is modified during parsing 30 | pugi::xml_parse_result result = doc.load_buffer_inplace(buffer, size); 31 | 32 | //<- 33 | std::cout << "Load result: " << result.description() << ", mesh name: " << doc.child("mesh").attribute("name").value() << std::endl; 34 | //-> 35 | // You have to destroy the block yourself after the document is no longer used 36 | delete[] buffer; 37 | //] 38 | } 39 | 40 | { 41 | //[code_load_memory_buffer_inplace_own 42 | // You can use load_buffer_inplace_own to load document from mutable memory block and to pass the ownership of this block 43 | // The block has to be allocated via pugixml allocation function - using i.e. operator new here is incorrect 44 | char* buffer = static_cast(pugi::get_memory_allocation_function()(size)); 45 | memcpy(buffer, source, size); 46 | 47 | // The block will be deleted by the document 48 | pugi::xml_parse_result result = doc.load_buffer_inplace_own(buffer, size); 49 | //] 50 | 51 | std::cout << "Load result: " << result.description() << ", mesh name: " << doc.child("mesh").attribute("name").value() << std::endl; 52 | } 53 | 54 | { 55 | //[code_load_memory_string 56 | // You can use load to load document from null-terminated strings, for example literals: 57 | pugi::xml_parse_result result = doc.load("0 0 1 1"); 58 | //] 59 | 60 | std::cout << "Load result: " << result.description() << ", mesh name: " << doc.child("mesh").attribute("name").value() << std::endl; 61 | } 62 | } 63 | 64 | // vim:et 65 | -------------------------------------------------------------------------------- /docs/samples/load_options.cpp: -------------------------------------------------------------------------------- 1 | #include "pugixml.hpp" 2 | 3 | #include 4 | 5 | int main() 6 | { 7 | pugi::xml_document doc; 8 | 9 | //[code_load_options 10 | const char* source = "<"; 11 | 12 | // Parsing with default options; note that comment node is not added to the tree, and entity reference < is expanded 13 | doc.load(source); 14 | std::cout << "First node value: [" << doc.first_child().value() << "], node child value: [" << doc.child_value("node") << "]\n"; 15 | 16 | // Parsing with additional parse_comments option; comment node is now added to the tree 17 | doc.load(source, pugi::parse_default | pugi::parse_comments); 18 | std::cout << "First node value: [" << doc.first_child().value() << "], node child value: [" << doc.child_value("node") << "]\n"; 19 | 20 | // Parsing with additional parse_comments option and without the (default) parse_escapes option; < is not expanded 21 | doc.load(source, (pugi::parse_default | pugi::parse_comments) & ~pugi::parse_escapes); 22 | std::cout << "First node value: [" << doc.first_child().value() << "], node child value: [" << doc.child_value("node") << "]\n"; 23 | 24 | // Parsing with minimal option mask; comment node is not added to the tree, and < is not expanded 25 | doc.load(source, pugi::parse_minimal); 26 | std::cout << "First node value: [" << doc.first_child().value() << "], node child value: [" << doc.child_value("node") << "]\n"; 27 | //] 28 | } 29 | 30 | // vim:et 31 | -------------------------------------------------------------------------------- /docs/samples/load_stream.cpp: -------------------------------------------------------------------------------- 1 | #include "pugixml.hpp" 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | void print_doc(const char* message, const pugi::xml_document& doc, const pugi::xml_parse_result& result) 8 | { 9 | std::cout 10 | << message 11 | << "\t: load result '" << result.description() << "'" 12 | << ", first character of root name: U+" << std::hex << std::uppercase << std::setw(4) << std::setfill('0') << pugi::as_wide(doc.first_child().name())[0] 13 | << ", year: " << doc.first_child().first_child().first_child().child_value() 14 | << std::endl; 15 | } 16 | 17 | bool try_imbue(std::wistream& stream, const char* name) 18 | { 19 | try 20 | { 21 | stream.imbue(std::locale(name)); 22 | 23 | return true; 24 | } 25 | catch (const std::exception&) 26 | { 27 | return false; 28 | } 29 | } 30 | 31 | int main() 32 | { 33 | pugi::xml_document doc; 34 | 35 | { 36 | //[code_load_stream 37 | std::ifstream stream("weekly-utf-8.xml"); 38 | pugi::xml_parse_result result = doc.load(stream); 39 | //] 40 | 41 | // first character of root name: U+9031, year: 1997 42 | print_doc("UTF8 file from narrow stream", doc, result); 43 | } 44 | 45 | { 46 | std::ifstream stream("weekly-utf-16.xml"); 47 | pugi::xml_parse_result result = doc.load(stream); 48 | 49 | // first character of root name: U+9031, year: 1997 50 | print_doc("UTF16 file from narrow stream", doc, result); 51 | } 52 | 53 | { 54 | // Since wide streams are treated as UTF-16/32 ones, you can't load the UTF-8 file from a wide stream 55 | // directly if you have localized characters; you'll have to provide a UTF8 locale (there is no 56 | // standard one; you can use utf8_codecvt_facet from Boost or codecvt_utf8 from C++0x) 57 | std::wifstream stream("weekly-utf-8.xml"); 58 | 59 | if (try_imbue(stream, "en_US.UTF-8")) // try Linux encoding 60 | { 61 | pugi::xml_parse_result result = doc.load(stream); 62 | 63 | // first character of root name: U+00E9, year: 1997 64 | print_doc("UTF8 file from wide stream", doc, result); 65 | } 66 | else 67 | { 68 | std::cout << "UTF-8 locale is not available\n"; 69 | } 70 | } 71 | 72 | { 73 | // Since wide streams are treated as UTF-16/32 ones, you can't load the UTF-16 file from a wide stream without 74 | // using custom codecvt; you can use codecvt_utf16 from C++0x 75 | } 76 | 77 | { 78 | // Since encoding names are non-standard, you can't load the Shift-JIS (or any other non-ASCII) file 79 | // from a wide stream portably 80 | std::wifstream stream("weekly-shift_jis.xml"); 81 | 82 | if (try_imbue(stream, ".932") || // try Microsoft encoding 83 | try_imbue(stream, "ja_JP.SJIS")) // try Linux encoding; run "localedef -i ja_JP -c -f SHIFT_JIS /usr/lib/locale/ja_JP.SJIS" to get it 84 | { 85 | pugi::xml_parse_result result = doc.load(stream); 86 | 87 | // first character of root name: U+9031, year: 1997 88 | print_doc("Shift-JIS file from wide stream", doc, result); 89 | } 90 | else 91 | { 92 | std::cout << "Shift-JIS locale is not available\n"; 93 | } 94 | } 95 | } 96 | 97 | // vim:et 98 | -------------------------------------------------------------------------------- /docs/samples/modify_add.cpp: -------------------------------------------------------------------------------- 1 | #include "pugixml.hpp" 2 | 3 | #include 4 | 5 | int main() 6 | { 7 | pugi::xml_document doc; 8 | 9 | //[code_modify_add 10 | // add node with some name 11 | pugi::xml_node node = doc.append_child("node"); 12 | 13 | // add description node with text child 14 | pugi::xml_node descr = node.append_child("description"); 15 | descr.append_child(pugi::node_pcdata).set_value("Simple node"); 16 | 17 | // add param node before the description 18 | pugi::xml_node param = node.insert_child_before("param", descr); 19 | 20 | // add attributes to param node 21 | param.append_attribute("name") = "version"; 22 | param.append_attribute("value") = 1.1; 23 | param.insert_attribute_after("type", param.attribute("name")) = "float"; 24 | //] 25 | 26 | doc.print(std::cout); 27 | } 28 | 29 | // vim:et 30 | -------------------------------------------------------------------------------- /docs/samples/modify_base.cpp: -------------------------------------------------------------------------------- 1 | #include "pugixml.hpp" 2 | 3 | #include 4 | #include 5 | 6 | int main() 7 | { 8 | pugi::xml_document doc; 9 | if (!doc.load("text", pugi::parse_default | pugi::parse_comments)) return -1; 10 | 11 | //[code_modify_base_node 12 | pugi::xml_node node = doc.child("node"); 13 | 14 | // change node name 15 | std::cout << node.set_name("notnode"); 16 | std::cout << ", new node name: " << node.name() << std::endl; 17 | 18 | // change comment text 19 | std::cout << doc.last_child().set_value("useless comment"); 20 | std::cout << ", new comment text: " << doc.last_child().value() << std::endl; 21 | 22 | // we can't change value of the element or name of the comment 23 | std::cout << node.set_value("1") << ", " << doc.last_child().set_name("2") << std::endl; 24 | //] 25 | 26 | //[code_modify_base_attr 27 | pugi::xml_attribute attr = node.attribute("id"); 28 | 29 | // change attribute name/value 30 | std::cout << attr.set_name("key") << ", " << attr.set_value("345"); 31 | std::cout << ", new attribute: " << attr.name() << "=" << attr.value() << std::endl; 32 | 33 | // we can use numbers or booleans 34 | attr.set_value(1.234); 35 | std::cout << "new attribute value: " << attr.value() << std::endl; 36 | 37 | // we can also use assignment operators for more concise code 38 | attr = true; 39 | std::cout << "final attribute value: " << attr.value() << std::endl; 40 | //] 41 | } 42 | 43 | // vim:et 44 | -------------------------------------------------------------------------------- /docs/samples/modify_remove.cpp: -------------------------------------------------------------------------------- 1 | #include "pugixml.hpp" 2 | 3 | #include 4 | 5 | int main() 6 | { 7 | pugi::xml_document doc; 8 | if (!doc.load("Simple node")) return -1; 9 | 10 | //[code_modify_remove 11 | // remove description node with the whole subtree 12 | pugi::xml_node node = doc.child("node"); 13 | node.remove_child("description"); 14 | 15 | // remove id attribute 16 | pugi::xml_node param = node.child("param"); 17 | param.remove_attribute("value"); 18 | 19 | // we can also remove nodes/attributes by handles 20 | pugi::xml_attribute id = param.attribute("name"); 21 | param.remove_attribute(id); 22 | //] 23 | 24 | doc.print(std::cout); 25 | } 26 | 27 | // vim:et 28 | -------------------------------------------------------------------------------- /docs/samples/save_custom_writer.cpp: -------------------------------------------------------------------------------- 1 | #include "pugixml.hpp" 2 | 3 | #include 4 | 5 | #include 6 | 7 | //[code_save_custom_writer 8 | struct xml_string_writer: pugi::xml_writer 9 | { 10 | std::string result; 11 | 12 | virtual void write(const void* data, size_t size) 13 | { 14 | result += std::string(static_cast(data), size); 15 | } 16 | }; 17 | //] 18 | 19 | struct xml_memory_writer: pugi::xml_writer 20 | { 21 | char* buffer; 22 | size_t capacity; 23 | 24 | size_t result; 25 | 26 | xml_memory_writer(): buffer(0), capacity(0), result(0) 27 | { 28 | } 29 | 30 | xml_memory_writer(char* buffer, size_t capacity): buffer(buffer), capacity(capacity), result(0) 31 | { 32 | } 33 | 34 | size_t written_size() const 35 | { 36 | return result < capacity ? result : capacity; 37 | } 38 | 39 | virtual void write(const void* data, size_t size) 40 | { 41 | if (result < capacity) 42 | { 43 | size_t chunk = (capacity - result < size) ? capacity - result : size; 44 | 45 | memcpy(buffer + result, data, chunk); 46 | } 47 | 48 | result += size; 49 | } 50 | }; 51 | 52 | std::string node_to_string(pugi::xml_node node) 53 | { 54 | xml_string_writer writer; 55 | node.print(writer); 56 | 57 | return writer.result; 58 | } 59 | 60 | char* node_to_buffer(pugi::xml_node node, char* buffer, size_t size) 61 | { 62 | if (size == 0) return buffer; 63 | 64 | // leave one character for null terminator 65 | xml_memory_writer writer(buffer, size - 1); 66 | node.print(writer); 67 | 68 | // null terminate 69 | buffer[writer.written_size()] = 0; 70 | 71 | return buffer; 72 | } 73 | 74 | char* node_to_buffer_heap(pugi::xml_node node) 75 | { 76 | // first pass: get required memory size 77 | xml_memory_writer counter; 78 | node.print(counter); 79 | 80 | // allocate necessary size (+1 for null termination) 81 | char* buffer = new char[counter.result + 1]; 82 | 83 | // second pass: actual printing 84 | xml_memory_writer writer(buffer, counter.result); 85 | node.print(writer); 86 | 87 | // null terminate 88 | buffer[writer.written_size()] = 0; 89 | 90 | return buffer; 91 | } 92 | 93 | int main() 94 | { 95 | // get a test document 96 | pugi::xml_document doc; 97 | doc.load("hey"); 98 | 99 | // get contents as std::string (single pass) 100 | printf("contents: [%s]\n", node_to_string(doc).c_str()); 101 | 102 | // get contents into fixed-size buffer (single pass) 103 | char large_buf[128]; 104 | printf("contents: [%s]\n", node_to_buffer(doc, large_buf, sizeof(large_buf))); 105 | 106 | // get contents into fixed-size buffer (single pass, shows truncating behavior) 107 | char small_buf[22]; 108 | printf("contents: [%s]\n", node_to_buffer(doc, small_buf, sizeof(small_buf))); 109 | 110 | // get contents into heap-allocated buffer (two passes) 111 | char* heap_buf = node_to_buffer_heap(doc); 112 | printf("contents: [%s]\n", heap_buf); 113 | delete[] heap_buf; 114 | } 115 | 116 | // vim:et 117 | -------------------------------------------------------------------------------- /docs/samples/save_file.cpp: -------------------------------------------------------------------------------- 1 | #include "pugixml.hpp" 2 | 3 | #include 4 | 5 | int main() 6 | { 7 | // get a test document 8 | pugi::xml_document doc; 9 | doc.load("hey"); 10 | 11 | //[code_save_file 12 | // save document to file 13 | std::cout << "Saving result: " << doc.save_file("save_file_output.xml") << std::endl; 14 | //] 15 | } 16 | 17 | // vim:et 18 | -------------------------------------------------------------------------------- /docs/samples/save_file_output.xml: -------------------------------------------------------------------------------- 1 | 2 | hey 3 | -------------------------------------------------------------------------------- /docs/samples/save_options.cpp: -------------------------------------------------------------------------------- 1 | #include "pugixml.hpp" 2 | 3 | #include 4 | 5 | int main() 6 | { 7 | //[code_save_options 8 | // get a test document 9 | pugi::xml_document doc; 10 | doc.load("hey"); 11 | 12 | // default options; prints 13 | // 14 | // 15 | // hey 16 | // 17 | doc.save(std::cout); 18 | std::cout << std::endl; 19 | 20 | // default options with custom indentation string; prints 21 | // 22 | // 23 | // --hey 24 | // 25 | doc.save(std::cout, "--"); 26 | std::cout << std::endl; 27 | 28 | // default options without indentation; prints 29 | // 30 | // 31 | // hey 32 | // 33 | doc.save(std::cout, "\t", pugi::format_default & ~pugi::format_indent); // can also pass "" instead of indentation string for the same effect 34 | std::cout << std::endl; 35 | 36 | // raw output; prints 37 | // hey 38 | doc.save(std::cout, "\t", pugi::format_raw); 39 | std::cout << std::endl << std::endl; 40 | 41 | // raw output without declaration; prints 42 | // hey 43 | doc.save(std::cout, "\t", pugi::format_raw | pugi::format_no_declaration); 44 | std::cout << std::endl; 45 | //] 46 | } 47 | 48 | // vim:et 49 | -------------------------------------------------------------------------------- /docs/samples/save_stream.cpp: -------------------------------------------------------------------------------- 1 | #include "pugixml.hpp" 2 | 3 | #include 4 | 5 | int main() 6 | { 7 | // get a test document 8 | pugi::xml_document doc; 9 | doc.load("hey"); 10 | 11 | //[code_save_stream 12 | // save document to standard output 13 | std::cout << "Document:\n"; 14 | doc.save(std::cout); 15 | //] 16 | } 17 | 18 | // vim:et 19 | -------------------------------------------------------------------------------- /docs/samples/save_subtree.cpp: -------------------------------------------------------------------------------- 1 | #include "pugixml.hpp" 2 | 3 | #include 4 | 5 | int main() 6 | { 7 | //[code_save_subtree 8 | // get a test document 9 | pugi::xml_document doc; 10 | doc.load("hey"); 11 | 12 | // print document to standard output (prints hey) 13 | doc.save(std::cout, "", pugi::format_raw); 14 | std::cout << std::endl; 15 | 16 | // print document to standard output as a regular node (prints hey) 17 | doc.print(std::cout, "", pugi::format_raw); 18 | std::cout << std::endl; 19 | 20 | // print a subtree to standard output (prints hey) 21 | doc.child("foo").child("call").print(std::cout, "", pugi::format_raw); 22 | std::cout << std::endl; 23 | //] 24 | } 25 | 26 | // vim:et 27 | -------------------------------------------------------------------------------- /docs/samples/transitions.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /docs/samples/traverse_base.cpp: -------------------------------------------------------------------------------- 1 | #include "pugixml.hpp" 2 | 3 | #include 4 | #include 5 | 6 | int main() 7 | { 8 | pugi::xml_document doc; 9 | if (!doc.load_file("xgconsole.xml")) return -1; 10 | 11 | pugi::xml_node tools = doc.child("Profile").child("Tools"); 12 | 13 | //[code_traverse_base_basic 14 | for (pugi::xml_node tool = tools.first_child(); tool; tool = tool.next_sibling()) 15 | { 16 | std::cout << "Tool:"; 17 | 18 | for (pugi::xml_attribute attr = tool.first_attribute(); attr; attr = attr.next_attribute()) 19 | { 20 | std::cout << " " << attr.name() << "=" << attr.value(); 21 | } 22 | 23 | std::cout << std::endl; 24 | } 25 | //] 26 | 27 | std::cout << std::endl; 28 | 29 | //[code_traverse_base_data 30 | for (pugi::xml_node tool = tools.child("Tool"); tool; tool = tool.next_sibling("Tool")) 31 | { 32 | std::cout << "Tool " << tool.attribute("Filename").value(); 33 | std::cout << ": AllowRemote " << tool.attribute("AllowRemote").as_bool(); 34 | std::cout << ", Timeout " << tool.attribute("Timeout").as_int(); 35 | std::cout << ", Description '" << tool.child_value("Description") << "'\n"; 36 | } 37 | //] 38 | 39 | std::cout << std::endl; 40 | 41 | //[code_traverse_base_contents 42 | std::cout << "Tool for *.dae generation: " << tools.find_child_by_attribute("Tool", "OutputFileMasks", "*.dae").attribute("Filename").value() << "\n"; 43 | 44 | for (pugi::xml_node tool = tools.child("Tool"); tool; tool = tool.next_sibling("Tool")) 45 | { 46 | std::cout << "Tool " << tool.attribute("Filename").value() << "\n"; 47 | } 48 | //] 49 | } 50 | 51 | // vim:et 52 | -------------------------------------------------------------------------------- /docs/samples/traverse_iter.cpp: -------------------------------------------------------------------------------- 1 | #include "pugixml.hpp" 2 | 3 | #include 4 | 5 | int main() 6 | { 7 | pugi::xml_document doc; 8 | if (!doc.load_file("xgconsole.xml")) return -1; 9 | 10 | pugi::xml_node tools = doc.child("Profile").child("Tools"); 11 | 12 | //[code_traverse_iter 13 | for (pugi::xml_node_iterator it = tools.begin(); it != tools.end(); ++it) 14 | { 15 | std::cout << "Tool:"; 16 | 17 | for (pugi::xml_attribute_iterator ait = it->attributes_begin(); ait != it->attributes_end(); ++ait) 18 | { 19 | std::cout << " " << ait->name() << "=" << ait->value(); 20 | } 21 | 22 | std::cout << std::endl; 23 | } 24 | //] 25 | } 26 | 27 | // vim:et 28 | -------------------------------------------------------------------------------- /docs/samples/traverse_predicate.cpp: -------------------------------------------------------------------------------- 1 | #include "pugixml.hpp" 2 | 3 | #include 4 | #include 5 | 6 | //[code_traverse_predicate_decl 7 | bool small_timeout(pugi::xml_node node) 8 | { 9 | return node.attribute("Timeout").as_int() < 20; 10 | } 11 | 12 | struct allow_remote_predicate 13 | { 14 | bool operator()(pugi::xml_attribute attr) const 15 | { 16 | return strcmp(attr.name(), "AllowRemote") == 0; 17 | } 18 | 19 | bool operator()(pugi::xml_node node) const 20 | { 21 | return node.attribute("AllowRemote").as_bool(); 22 | } 23 | }; 24 | //] 25 | 26 | int main() 27 | { 28 | pugi::xml_document doc; 29 | if (!doc.load_file("xgconsole.xml")) return -1; 30 | 31 | pugi::xml_node tools = doc.child("Profile").child("Tools"); 32 | 33 | //[code_traverse_predicate_find 34 | // Find child via predicate (looks for direct children only) 35 | std::cout << tools.find_child(allow_remote_predicate()).attribute("Filename").value() << std::endl; 36 | 37 | // Find node via predicate (looks for all descendants in depth-first order) 38 | std::cout << doc.find_node(allow_remote_predicate()).attribute("Filename").value() << std::endl; 39 | 40 | // Find attribute via predicate 41 | std::cout << tools.last_child().find_attribute(allow_remote_predicate()).value() << std::endl; 42 | 43 | // We can use simple functions instead of function objects 44 | std::cout << tools.find_child(small_timeout).attribute("Filename").value() << std::endl; 45 | //] 46 | } 47 | 48 | // vim:et 49 | -------------------------------------------------------------------------------- /docs/samples/traverse_walker.cpp: -------------------------------------------------------------------------------- 1 | #include "pugixml.hpp" 2 | 3 | #include 4 | 5 | const char* node_types[] = 6 | { 7 | "null", "document", "element", "pcdata", "cdata", "comment", "pi", "declaration" 8 | }; 9 | 10 | //[code_traverse_walker_impl 11 | struct simple_walker: pugi::xml_tree_walker 12 | { 13 | virtual bool for_each(pugi::xml_node& node) 14 | { 15 | for (int i = 0; i < depth(); ++i) std::cout << " "; // indentation 16 | 17 | std::cout << node_types[node.type()] << ": name='" << node.name() << "', value='" << node.value() << "'\n"; 18 | 19 | return true; // continue traversal 20 | } 21 | }; 22 | //] 23 | 24 | int main() 25 | { 26 | pugi::xml_document doc; 27 | if (!doc.load_file("tree.xml")) return -1; 28 | 29 | //[code_traverse_walker_traverse 30 | simple_walker walker; 31 | doc.traverse(walker); 32 | //] 33 | } 34 | 35 | // vim:et 36 | -------------------------------------------------------------------------------- /docs/samples/tree.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | some text 5 | 6 | some more text 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/samples/weekly-shift_jis.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rofldev/pugihtml/a7e4c33c8b59d6e92d5f1f4b849b5b8a1ec0bc06/docs/samples/weekly-shift_jis.xml -------------------------------------------------------------------------------- /docs/samples/weekly-utf-16.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rofldev/pugihtml/a7e4c33c8b59d6e92d5f1f4b849b5b8a1ec0bc06/docs/samples/weekly-utf-16.xml -------------------------------------------------------------------------------- /docs/samples/weekly-utf-8.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <週報> 5 | <年月週> 6 | <年度>1997 7 | <月度>1 8 | <週>1 9 | 10 | 11 | <氏名> 12 | <氏>山田 13 | <名>太郎 14 | 15 | 16 | <業務報告リスト> 17 | <業務報告> 18 | <業務名>XMLエディターの作成 19 | <業務コード>X3355-23 20 | <工数管理> 21 | <見積もり工数>1600 22 | <実績工数>320 23 | <当月見積もり工数>160 24 | <当月実績工数>24 25 | 26 | <予定項目リスト> 27 | <予定項目> 28 |

XMLエディターの基本仕様の作成

29 | 30 | 31 | <実施事項リスト> 32 | <実施事項> 33 |

XMLエディターの基本仕様の作成

34 | 35 | <実施事項> 36 |

競合他社製品の機能調査

37 | 38 | 39 | <上長への要請事項リスト> 40 | <上長への要請事項> 41 |

特になし

42 | 43 | 44 | <問題点対策> 45 |

XMLとは何かわからない。

46 | 47 | 48 | 49 | <業務報告> 50 | <業務名>検索エンジンの開発 51 | <業務コード>S8821-76 52 | <工数管理> 53 | <見積もり工数>120 54 | <実績工数>6 55 | <当月見積もり工数>32 56 | <当月実績工数>2 57 | 58 | <予定項目リスト> 59 | <予定項目> 60 |

gooの機能を調べてみる

61 | 62 | 63 | <実施事項リスト> 64 | <実施事項> 65 |

更に、どういう検索エンジンがあるか調査する

66 | 67 | 68 | <上長への要請事項リスト> 69 | <上長への要請事項> 70 |

開発をするのはめんどうなので、Yahoo!を買収して下さい。

71 | 72 | 73 | <問題点対策> 74 |

検索エンジンで車を走らせることができない。(要調査)

75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /docs/samples/xgconsole.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Jamplus build system 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/samples/xpath_error.cpp: -------------------------------------------------------------------------------- 1 | #include "pugixml.hpp" 2 | 3 | #include 4 | 5 | int main() 6 | { 7 | pugi::xml_document doc; 8 | if (!doc.load_file("xgconsole.xml")) return -1; 9 | 10 | //[code_xpath_error 11 | // Exception is thrown for incorrect query syntax 12 | try 13 | { 14 | doc.select_nodes("//nodes[#true()]"); 15 | } 16 | catch (const pugi::xpath_exception& e) 17 | { 18 | std::cout << "Select failed: " << e.what() << std::endl; 19 | } 20 | 21 | // Exception is thrown for incorrect query semantics 22 | try 23 | { 24 | doc.select_nodes("(123)/next"); 25 | } 26 | catch (const pugi::xpath_exception& e) 27 | { 28 | std::cout << "Select failed: " << e.what() << std::endl; 29 | } 30 | 31 | // Exception is thrown for query with incorrect return type 32 | try 33 | { 34 | doc.select_nodes("123"); 35 | } 36 | catch (const pugi::xpath_exception& e) 37 | { 38 | std::cout << "Select failed: " << e.what() << std::endl; 39 | } 40 | //] 41 | } 42 | 43 | // vim:et 44 | -------------------------------------------------------------------------------- /docs/samples/xpath_query.cpp: -------------------------------------------------------------------------------- 1 | #include "pugixml.hpp" 2 | 3 | #include 4 | #include 5 | 6 | int main() 7 | { 8 | pugi::xml_document doc; 9 | if (!doc.load_file("xgconsole.xml")) return -1; 10 | 11 | //[code_xpath_query 12 | // Select nodes via compiled query 13 | pugi::xpath_query query_remote_tools("/Profile/Tools/Tool[@AllowRemote='true']"); 14 | 15 | pugi::xpath_node_set tools = query_remote_tools.evaluate_node_set(doc); 16 | std::cout << "Remote tool: "; 17 | tools[2].node().print(std::cout); 18 | 19 | // Evaluate numbers via compiled query 20 | pugi::xpath_query query_timeouts("sum(//Tool/@Timeout)"); 21 | std::cout << query_timeouts.evaluate_number(doc) << std::endl; 22 | 23 | // Evaluate strings via compiled query for different context nodes 24 | pugi::xpath_query query_name_valid("string-length(substring-before(@Filename, '_')) > 0 and @OutputFileMasks"); 25 | pugi::xpath_query query_name("concat(substring-before(@Filename, '_'), ' produces ', @OutputFileMasks)"); 26 | 27 | for (pugi::xml_node tool = doc.first_element_by_path("Profile/Tools/Tool"); tool; tool = tool.next_sibling()) 28 | { 29 | std::string s = query_name.evaluate_string(tool); 30 | 31 | if (query_name_valid.evaluate_boolean(tool)) std::cout << s << std::endl; 32 | } 33 | //] 34 | } 35 | 36 | // vim:et 37 | -------------------------------------------------------------------------------- /docs/samples/xpath_select.cpp: -------------------------------------------------------------------------------- 1 | #include "pugixml.hpp" 2 | 3 | #include 4 | 5 | int main() 6 | { 7 | pugi::xml_document doc; 8 | if (!doc.load_file("xgconsole.xml")) return -1; 9 | 10 | //[code_xpath_select 11 | pugi::xpath_node_set tools = doc.select_nodes("/Profile/Tools/Tool[@AllowRemote='true' and @DeriveCaptionFrom='lastparam']"); 12 | 13 | std::cout << "Tools:"; 14 | 15 | for (pugi::xpath_node_set::const_iterator it = tools.begin(); it != tools.end(); ++it) 16 | { 17 | pugi::xpath_node node = *it; 18 | std::cout << " " << node.node().attribute("Filename").value(); 19 | } 20 | 21 | pugi::xpath_node build_tool = doc.select_single_node("//Tool[contains(Description, 'build system')]"); 22 | 23 | std::cout << "\nBuild tool: " << build_tool.node().attribute("Filename").value() << "\n"; 24 | //] 25 | } 26 | 27 | // vim:et 28 | -------------------------------------------------------------------------------- /docs/samples/xpath_variables.cpp: -------------------------------------------------------------------------------- 1 | #include "pugixml.hpp" 2 | 3 | #include 4 | #include 5 | 6 | int main() 7 | { 8 | pugi::xml_document doc; 9 | if (!doc.load_file("xgconsole.xml")) return -1; 10 | 11 | //[code_xpath_variables 12 | // Select nodes via compiled query 13 | pugi::xpath_variable_set vars; 14 | vars.add("remote", pugi::xpath_type_boolean); 15 | 16 | pugi::xpath_query query_remote_tools("/Profile/Tools/Tool[@AllowRemote = string($remote)]", &vars); 17 | 18 | vars.set("remote", true); 19 | pugi::xpath_node_set tools_remote = query_remote_tools.evaluate_node_set(doc); 20 | 21 | vars.set("remote", false); 22 | pugi::xpath_node_set tools_local = query_remote_tools.evaluate_node_set(doc); 23 | 24 | std::cout << "Remote tool: "; 25 | tools_remote[2].node().print(std::cout); 26 | 27 | std::cout << "Local tool: "; 28 | tools_local[0].node().print(std::cout); 29 | 30 | // You can pass the context directly to select_nodes/select_single_node 31 | pugi::xpath_node_set tools_local_imm = doc.select_nodes("/Profile/Tools/Tool[@AllowRemote = string($remote)]", &vars); 32 | 33 | std::cout << "Local tool imm: "; 34 | tools_local_imm[0].node().print(std::cout); 35 | //] 36 | } 37 | 38 | // vim:et 39 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | This library is distributed under the MIT License: 2 | 3 | Copyright (c) 2012 Adgooroo, LLC (kgantchev@adgooroo.com) 4 | Permission is hereby granted, free of charge, to any person 5 | obtaining a copy of this software and associated documentation 6 | files (the "Software"), to deal in the Software without 7 | restriction, including without limitation the rights to use, 8 | copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the 10 | Software is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 18 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 20 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 21 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 23 | OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | pugihtml 1.0 - an HTML processing library based on pugixml 2 | 3 | Copyright (c) 2012 Adgooroo, LLC (kgantchev [AT] adgooroo [DOT] com) 4 | 5 | This is the distribution of pugihtml, which is a C++ HTML processing library, 6 | consisting of a DOM-like interface with rich traversal/modification 7 | capabilities, an extremely fast HTML parser which constructs the DOM tree from 8 | an HTML file/buffer, and an XPath 1.0 implementation for complex data-driven 9 | tree queries. Full Unicode support is also available, with Unicode interface 10 | variants and conversions between different Unicode encodings (which happen 11 | automatically during parsing/saving). 12 | 13 | The distribution contains the following folders: 14 | 15 | contrib/ - various contributions to pugihtml 16 | 17 | docs/ - documentation 18 | docs/samples - pugixml usage examples 19 | docs/quickstart.html - quick start guide 20 | docs/manual.html - complete manual 21 | 22 | scripts/ - project files for IDE/build systems 23 | 24 | src/ - header and source files 25 | 26 | readme.txt - this file. 27 | 28 | This work is based on pugixml parser, which is: 29 | Copyright (C) 2006-2010, by Arseny Kapoulkine (arseny [DOT] kapoulkine [AT] gmail [DOT] com) 30 | 31 | This library is distributed under the MIT License: 32 | 33 | Copyright (c) 2012 Adgooroo, LLC 34 | Permission is hereby granted, free of charge, to any person 35 | obtaining a copy of this software and associated documentation 36 | files (the "Software"), to deal in the Software without 37 | restriction, including without limitation the rights to use, 38 | copy, modify, merge, publish, distribute, sublicense, and/or sell 39 | copies of the Software, and to permit persons to whom the 40 | Software is furnished to do so, subject to the following 41 | conditions: 42 | 43 | The above copyright notice and this permission notice shall be 44 | included in all copies or substantial portions of the Software. 45 | 46 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 47 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 48 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 49 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 50 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 51 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 52 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 53 | OTHER DEALINGS IN THE SOFTWARE. 54 | -------------------------------------------------------------------------------- /scripts/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(pugihtml) 2 | 3 | set(SOURCES ../src/pugihtml.cpp ../src/memory.cpp) 4 | 5 | add_library(pugihtml STATIC ${SOURCES}) 6 | -------------------------------------------------------------------------------- /scripts/premake4.lua: -------------------------------------------------------------------------------- 1 | -- Reset RNG seed to get consistent results across runs (i.e. XCode) 2 | math.randomseed(12345) 3 | 4 | local static = _ARGS[1] == 'static' 5 | local action = premake.action.current() 6 | 7 | if string.startswith(_ACTION, "vs") then 8 | -- We need debugging symbols for all configurations, but runtime library depends on official Symbols flag, so hack it 9 | function premake.vs200x_vcproj_symbols(cfg) 10 | return 3 11 | end 12 | 13 | if action then 14 | -- Disable solution generation 15 | function action.onsolution(sln) 16 | sln.vstudio_configs = premake.vstudio_buildconfigs(sln) 17 | end 18 | 19 | -- Rename output file 20 | function action.onproject(prj) 21 | premake.generate(prj, "%%_" .. _ACTION .. (static and "_static" or "") .. ".vcproj", premake.vs200x_vcproj) 22 | end 23 | end 24 | elseif _ACTION == "codeblocks" then 25 | action.onsolution = nil 26 | 27 | function action.onproject(prj) 28 | premake.generate(prj, "%%_" .. _ACTION .. ".cbp", premake.codeblocks_cbp) 29 | end 30 | elseif _ACTION == "codelite" then 31 | action.onsolution = nil 32 | 33 | function action.onproject(prj) 34 | premake.generate(prj, "%%_" .. _ACTION .. ".project", premake.codelite_project) 35 | end 36 | end 37 | 38 | solution "pugixml" 39 | objdir(_ACTION) 40 | targetdir(_ACTION) 41 | 42 | if string.startswith(_ACTION, "vs") then 43 | if _ACTION ~= "vs2002" and _ACTION ~= "vs2003" then 44 | platforms { "x32", "x64" } 45 | 46 | configuration "x32" targetdir(_ACTION .. "/x32") 47 | configuration "x64" targetdir(_ACTION .. "/x64") 48 | end 49 | 50 | configurations { "Debug", "Release" } 51 | 52 | if static then 53 | configuration "Debug" targetsuffix "_sd" 54 | configuration "Release" targetsuffix "_s" 55 | else 56 | configuration "Debug" targetsuffix "_d" 57 | end 58 | else 59 | if _ACTION == "xcode3" then 60 | platforms "universal" 61 | end 62 | 63 | configurations { "Debug", "Release" } 64 | 65 | configuration "Debug" targetsuffix "_d" 66 | end 67 | 68 | project "pugixml" 69 | kind "StaticLib" 70 | language "C++" 71 | files { "../src/pugixml.hpp", "../src/pugiconfig.hpp", "../src/pugixml.cpp" } 72 | flags { "NoPCH", "NoMinimalRebuild" } 73 | uuid "89A1E353-E2DC-495C-B403-742BE206ACED" 74 | 75 | configuration "Debug" 76 | defines { "_DEBUG" } 77 | flags { "Symbols" } 78 | 79 | configuration "Release" 80 | defines { "NDEBUG" } 81 | flags { "Optimize" } 82 | 83 | if static then 84 | configuration "*" 85 | flags { "StaticRuntime" } 86 | end 87 | -------------------------------------------------------------------------------- /scripts/pugihtml_codeblocks.cbp: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /scripts/pugihtml_codelite.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | None 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | None 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /scripts/pugihtml_vs2010.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | pugihtml 23 | {D0E1A412-6B78-4F08-A813-254486C54268} 24 | pugihtml 25 | Win32Proj 26 | 27 | 28 | 29 | StaticLibrary 30 | MultiByte 31 | 32 | 33 | StaticLibrary 34 | MultiByte 35 | 36 | 37 | StaticLibrary 38 | MultiByte 39 | 40 | 41 | StaticLibrary 42 | MultiByte 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | <_ProjectFileVersion>10.0.30319.1 62 | vs2010\x32\ 63 | vs2010\x32\Debug\ 64 | vs2010\x64\ 65 | vs2010\x64\Debug\ 66 | vs2010\x32\ 67 | vs2010\x32\Release\ 68 | vs2010\x64\ 69 | vs2010\x64\Release\ 70 | $(ProjectName)_d 71 | $(ProjectName)_d 72 | 73 | 74 | 75 | Disabled 76 | _DEBUG;%(PreprocessorDefinitions) 77 | EnableFastChecks 78 | MultiThreadedDebugDLL 79 | 80 | 81 | Level3 82 | $(OutDir)pugihtml_d.pdb 83 | ProgramDatabase 84 | true 85 | true 86 | 87 | 88 | _DEBUG;%(PreprocessorDefinitions) 89 | 90 | 91 | 92 | 93 | 94 | X64 95 | 96 | 97 | Disabled 98 | _DEBUG;%(PreprocessorDefinitions) 99 | EnableFastChecks 100 | MultiThreadedDebugDLL 101 | true 102 | 103 | 104 | Level3 105 | $(OutDir)pugihtml_d.pdb 106 | ProgramDatabase 107 | 108 | 109 | _DEBUG;%(PreprocessorDefinitions) 110 | 111 | 112 | 113 | 114 | 115 | Full 116 | NDEBUG;%(PreprocessorDefinitions) 117 | true 118 | MultiThreadedDLL 119 | true 120 | 121 | 122 | Level3 123 | $(OutDir)pugihtml.pdb 124 | ProgramDatabase 125 | 126 | 127 | NDEBUG;%(PreprocessorDefinitions) 128 | 129 | 130 | 131 | 132 | 133 | X64 134 | 135 | 136 | Full 137 | NDEBUG;%(PreprocessorDefinitions) 138 | true 139 | MultiThreadedDLL 140 | true 141 | 142 | 143 | Level3 144 | $(OutDir)pugihtml.pdb 145 | ProgramDatabase 146 | 147 | 148 | NDEBUG;%(PreprocessorDefinitions) 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | -------------------------------------------------------------------------------- /scripts/pugihtml_vs2010.vcxproj.user: -------------------------------------------------------------------------------- 1 |  2 | 3 | -------------------------------------------------------------------------------- /scripts/pugihtml_vs2010_static.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | pugixml 23 | {89A1E353-E2DC-495C-B403-742BE206ACED} 24 | pugixml 25 | Win32Proj 26 | 27 | 28 | 29 | StaticLibrary 30 | MultiByte 31 | 32 | 33 | StaticLibrary 34 | MultiByte 35 | 36 | 37 | StaticLibrary 38 | MultiByte 39 | 40 | 41 | StaticLibrary 42 | MultiByte 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | <_ProjectFileVersion>10.0.30319.1 62 | vs2010\x32\ 63 | vs2010\x32\Debug\ 64 | vs2010\x64\ 65 | vs2010\x64\Debug\ 66 | vs2010\x32\ 67 | vs2010\x32\Release\ 68 | vs2010\x64\ 69 | vs2010\x64\Release\ 70 | $(ProjectName)_sd 71 | $(ProjectName)_sd 72 | $(ProjectName)_s 73 | $(ProjectName)_s 74 | 75 | 76 | 77 | Disabled 78 | _DEBUG;%(PreprocessorDefinitions) 79 | EnableFastChecks 80 | MultiThreadedDebug 81 | true 82 | 83 | 84 | Level3 85 | $(OutDir)pugixml_sd.pdb 86 | ProgramDatabase 87 | 88 | 89 | _DEBUG;%(PreprocessorDefinitions) 90 | 91 | 92 | 93 | 94 | 95 | X64 96 | 97 | 98 | Disabled 99 | _DEBUG;%(PreprocessorDefinitions) 100 | EnableFastChecks 101 | MultiThreadedDebug 102 | true 103 | 104 | 105 | Level3 106 | $(OutDir)pugixml_sd.pdb 107 | ProgramDatabase 108 | 109 | 110 | _DEBUG;%(PreprocessorDefinitions) 111 | 112 | 113 | 114 | 115 | 116 | Full 117 | NDEBUG;%(PreprocessorDefinitions) 118 | true 119 | MultiThreaded 120 | true 121 | 122 | 123 | Level3 124 | $(OutDir)pugixml_s.pdb 125 | ProgramDatabase 126 | 127 | 128 | NDEBUG;%(PreprocessorDefinitions) 129 | 130 | 131 | 132 | 133 | 134 | X64 135 | 136 | 137 | Full 138 | NDEBUG;%(PreprocessorDefinitions) 139 | true 140 | MultiThreaded 141 | true 142 | 143 | 144 | Level3 145 | $(OutDir)pugixml_s.pdb 146 | ProgramDatabase 147 | 148 | 149 | NDEBUG;%(PreprocessorDefinitions) 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | -------------------------------------------------------------------------------- /src/common.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * pugihtml parser - version 1.0 3 | * -------------------------------------------------------- 4 | * Copyright (c) 2012 Adgooroo, LLC (kgantchev [AT] adgooroo [DOT] com) 5 | * 6 | * This library is distributed under the MIT License. See notice in license.txt 7 | * 8 | * This work is based on the pugxml parser, which is: 9 | * Copyright (C) 2006-2010, by Arseny Kapoulkine (arseny [DOT] kapoulkine [AT] gmail [DOT] com) 10 | */ 11 | 12 | #ifndef COMMON_HPP 13 | #define COMMON_HPP 14 | #include "pugiconfig.hpp" 15 | 16 | #ifndef PUGIHTML_NO_STL 17 | namespace std 18 | { 19 | struct bidirectional_iterator_tag; 20 | 21 | #ifdef __SUNPRO_CC 22 | // Sun C++ compiler has a bug which forces template argument names in forward declarations to be the same as in actual definitions 23 | template class allocator; 24 | template struct char_traits; 25 | template class basic_istream; 26 | template class basic_ostream; 27 | template class basic_string; 28 | #else 29 | // Borland C++ compiler has a bug which forces template argument names in forward declarations to be the same as in actual definitions 30 | template class allocator; 31 | template struct char_traits; 32 | template class basic_istream; 33 | template class basic_ostream; 34 | template class basic_string; 35 | #endif 36 | 37 | // Digital Mars compiler has a bug which requires a forward declaration for explicit instantiation (otherwise type selection is messed up later, producing link errors) 38 | // Also note that we have to declare char_traits as a class here, since it's defined that way 39 | #ifdef __DMC__ 40 | template <> class char_traits; 41 | #endif 42 | } 43 | #endif 44 | 45 | // Macro for deprecated features 46 | #ifndef PUGIHTML_DEPRECATED 47 | # if defined(__GNUC__) 48 | # define PUGIHTML_DEPRECATED __attribute__((deprecated)) 49 | # elif defined(_MSC_VER) && _MSC_VER >= 1300 50 | # define PUGIHTML_DEPRECATED __declspec(deprecated) 51 | # else 52 | # define PUGIHTML_DEPRECATED 53 | # endif 54 | #endif 55 | 56 | // Include exception header for XPath 57 | #if !defined(PUGIHTML_NO_XPATH) && !defined(PUGIHTML_NO_EXCEPTIONS) 58 | # include 59 | #endif 60 | 61 | // If no API is defined, assume default 62 | #ifndef PUGIHTML_API 63 | # define PUGIHTML_API 64 | #endif 65 | 66 | // If no API for classes is defined, assume default 67 | #ifndef PUGIHTML_CLASS 68 | # define PUGIHTML_CLASS PUGIHTML_API 69 | #endif 70 | 71 | // If no API for functions is defined, assume default 72 | #ifndef PUGIHTML_FUNCTION 73 | # define PUGIHTML_FUNCTION PUGIHTML_API 74 | #endif 75 | 76 | // uintptr_t 77 | #if !defined(_MSC_VER) || _MSC_VER >= 1600 78 | # include 79 | #else 80 | # if _MSC_VER < 1300 81 | // No native uintptr_t in MSVC6 82 | typedef size_t uintptr_t; 83 | # endif 84 | typedef unsigned __int8 uint8_t; 85 | typedef unsigned __int16 uint16_t; 86 | typedef unsigned __int32 uint32_t; 87 | typedef __int32 int32_t; 88 | #endif 89 | 90 | // Inlining controls 91 | #if defined(_MSC_VER) && _MSC_VER >= 1300 92 | # define PUGIHTML_NO_INLINE __declspec(noinline) 93 | #elif defined(__GNUC__) 94 | # define PUGIHTML_NO_INLINE __attribute__((noinline)) 95 | #else 96 | # define PUGIHTML_NO_INLINE 97 | #endif 98 | 99 | // Character interface macros 100 | #ifdef PUGIHTML_WCHAR_MODE 101 | # define PUGIHTML_TEXT(t) L ## t 102 | # define PUGIHTML_CHAR wchar_t 103 | #else 104 | # define PUGIHTML_TEXT(t) t 105 | # define PUGIHTML_CHAR char 106 | #endif 107 | 108 | namespace pugihtml 109 | { 110 | // Character type used for all internal storage and operations; depends on PUGIHTML_WCHAR_MODE 111 | typedef PUGIHTML_CHAR char_t; 112 | 113 | #ifndef PUGIHTML_NO_STL 114 | // String type used for operations that work with STL string; depends on PUGIHTML_WCHAR_MODE 115 | typedef std::basic_string, std::allocator > string_t; 116 | #endif 117 | } 118 | 119 | #endif 120 | -------------------------------------------------------------------------------- /src/memory.cpp: -------------------------------------------------------------------------------- 1 | #include "memory.hpp" 2 | #include 3 | #include 4 | 5 | namespace pugihtml 6 | { 7 | 8 | html_memory_page* html_memory_page::construct(void* memory) 9 | { 10 | if (!memory) return 0; //$ redundant, left for performance 11 | 12 | html_memory_page* result = static_cast(memory); 13 | 14 | result->allocator = 0; 15 | result->memory = 0; 16 | result->prev = 0; 17 | result->next = 0; 18 | result->busy_size = 0; 19 | result->freed_size = 0; 20 | 21 | return result; 22 | } 23 | 24 | html_allocator::html_allocator(html_memory_page* root): _root(root), _busy_size(root->busy_size) 25 | { 26 | } 27 | 28 | void html_allocator::deallocate_page(html_memory_page* page) 29 | { 30 | global_deallocate(page->memory); 31 | } 32 | 33 | 34 | html_memory_page* html_allocator::allocate_page(size_t data_size) 35 | { 36 | size_t size = offsetof(html_memory_page, data) + data_size; 37 | 38 | // allocate block with some alignment, leaving memory for worst-case padding 39 | void* memory = global_allocate(size + html_memory_page_alignment); 40 | if (!memory) return 0; 41 | 42 | // align upwards to page boundary 43 | void* page_memory = reinterpret_cast((reinterpret_cast(memory) + (html_memory_page_alignment - 1)) & ~(html_memory_page_alignment - 1)); 44 | 45 | // prepare page structure 46 | html_memory_page* page = html_memory_page::construct(page_memory); 47 | 48 | page->memory = memory; 49 | page->allocator = _root->allocator; 50 | 51 | return page; 52 | } 53 | 54 | void* html_allocator::allocate_memory(size_t size, html_memory_page*& out_page) 55 | { 56 | if (_busy_size + size > html_memory_page_size) return allocate_memory_oob(size, out_page); 57 | 58 | void* buf = _root->data + _busy_size; 59 | 60 | _busy_size += size; 61 | 62 | out_page = _root; 63 | 64 | return buf; 65 | } 66 | 67 | void html_allocator::deallocate_memory(void* ptr, size_t size, html_memory_page* page) 68 | { 69 | if (page == _root) page->busy_size = _busy_size; 70 | 71 | assert(ptr >= page->data && ptr < page->data + page->busy_size); 72 | (void)!ptr; 73 | 74 | page->freed_size += size; 75 | assert(page->freed_size <= page->busy_size); 76 | 77 | if (page->freed_size == page->busy_size) 78 | { 79 | if (page->next == 0) 80 | { 81 | assert(_root == page); 82 | 83 | // top page freed, just reset sizes 84 | page->busy_size = page->freed_size = 0; 85 | _busy_size = 0; 86 | } 87 | else 88 | { 89 | assert(_root != page); 90 | assert(page->prev); 91 | 92 | // remove from the list 93 | page->prev->next = page->next; 94 | page->next->prev = page->prev; 95 | 96 | // deallocate 97 | deallocate_page(page); 98 | } 99 | } 100 | } 101 | 102 | char_t* html_allocator::allocate_string(size_t length) 103 | { 104 | // allocate memory for string and header block 105 | size_t size = sizeof(html_memory_string_header) + length * sizeof(char_t); 106 | 107 | // round size up to pointer alignment boundary 108 | size_t full_size = (size + (sizeof(void*) - 1)) & ~(sizeof(void*) - 1); 109 | 110 | html_memory_page* page; 111 | html_memory_string_header* header = static_cast(allocate_memory(full_size, page)); 112 | 113 | if (!header) return 0; 114 | 115 | // setup header 116 | ptrdiff_t page_offset = reinterpret_cast(header) - page->data; 117 | 118 | assert(page_offset >= 0 && page_offset < (1 << 16)); 119 | header->page_offset = static_cast(page_offset); 120 | 121 | // full_size == 0 for large strings that occupy the whole page 122 | assert(full_size < (1 << 16) || (page->busy_size == full_size && page_offset == 0)); 123 | header->full_size = static_cast(full_size < (1 << 16) ? full_size : 0); 124 | 125 | return reinterpret_cast(header + 1); 126 | } 127 | 128 | void html_allocator::deallocate_string(char_t* string) 129 | { 130 | // get header 131 | html_memory_string_header* header = reinterpret_cast(string) - 1; 132 | 133 | // deallocate 134 | size_t page_offset = offsetof(html_memory_page, data) + header->page_offset; 135 | html_memory_page* page = reinterpret_cast(reinterpret_cast(header) - page_offset); 136 | 137 | // if full_size == 0 then this string occupies the whole page 138 | size_t full_size = header->full_size == 0 ? page->busy_size : header->full_size; 139 | 140 | deallocate_memory(header, full_size, page); 141 | } 142 | 143 | 144 | PUGIHTML_NO_INLINE void* html_allocator::allocate_memory_oob(size_t size, html_memory_page*& out_page) 145 | { 146 | const size_t large_allocation_threshold = html_memory_page_size / 4; 147 | 148 | html_memory_page* page = allocate_page(size <= large_allocation_threshold ? html_memory_page_size : size); 149 | if (!page) return 0; 150 | 151 | if (size <= large_allocation_threshold) 152 | { 153 | _root->busy_size = _busy_size; 154 | 155 | // insert page at the end of linked list 156 | page->prev = _root; 157 | _root->next = page; 158 | _root = page; 159 | 160 | _busy_size = size; 161 | } 162 | else 163 | { 164 | // insert page before the end of linked list, so that it is deleted as soon as possible 165 | // the last page is not deleted even if it's empty (see deallocate_memory) 166 | assert(_root->prev); 167 | 168 | page->prev = _root->prev; 169 | page->next = _root; 170 | 171 | _root->prev->next = page; 172 | _root->prev = page; 173 | } 174 | 175 | // allocate inside page 176 | page->busy_size = size; 177 | 178 | out_page = page; 179 | return page->data; 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /src/memory.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * pugihtml parser - version 1.0 3 | * -------------------------------------------------------- 4 | * Copyright (c) 2012 Adgooroo, LLC (kgantchev [AT] adgooroo [DOT] com) 5 | * 6 | * This library is distributed under the MIT License. See notice in license.txt 7 | * 8 | * This work is based on the pugxml parser, which is: 9 | * Copyright (C) 2006-2010, by Arseny Kapoulkine (arseny [DOT] kapoulkine [AT] gmail [DOT] com) 10 | */ 11 | 12 | #ifndef MEMORY_HPP 13 | #define MEMORY_HPP 14 | #include "common.hpp" 15 | #include 16 | 17 | namespace pugihtml 18 | { 19 | static const size_t html_memory_page_size = 32768; 20 | static const uintptr_t html_memory_page_alignment = 32; 21 | static const uintptr_t html_memory_page_pointer_mask = ~(html_memory_page_alignment - 1); 22 | static const uintptr_t html_memory_page_name_allocated_mask = 16; 23 | static const uintptr_t html_memory_page_value_allocated_mask = 8; 24 | static const uintptr_t html_memory_page_type_mask = 7; 25 | 26 | // Memory allocation function interface; returns pointer to allocated memory or NULL on failure 27 | typedef void* (*allocation_function)(size_t size); 28 | 29 | // Memory deallocation function interface 30 | typedef void (*deallocation_function)(void* ptr); 31 | 32 | // Memory allocation 33 | inline void* default_allocate(size_t size) 34 | { 35 | return malloc(size); 36 | } 37 | // Memory deallocation 38 | inline void default_deallocate(void* ptr) 39 | { 40 | free(ptr); 41 | } 42 | 43 | static allocation_function global_allocate = default_allocate; 44 | static deallocation_function global_deallocate = default_deallocate; 45 | 46 | // Override default memory management functions. All subsequent allocations/deallocations will be performed via supplied functions. 47 | void PUGIHTML_FUNCTION set_memory_management_functions(allocation_function allocate, deallocation_function deallocate); 48 | 49 | // Get current memory management functions 50 | allocation_function PUGIHTML_FUNCTION get_memory_allocation_function(); 51 | deallocation_function PUGIHTML_FUNCTION get_memory_deallocation_function(); 52 | 53 | struct html_allocator; 54 | 55 | struct html_memory_page 56 | { 57 | static html_memory_page* construct(void* memory); 58 | 59 | html_allocator* allocator; 60 | 61 | void* memory; 62 | 63 | html_memory_page* prev; 64 | html_memory_page* next; 65 | 66 | size_t busy_size; 67 | size_t freed_size; 68 | 69 | char data[1]; 70 | }; 71 | 72 | struct html_memory_string_header 73 | { 74 | uint16_t page_offset; // offset from page->data 75 | uint16_t full_size; // 0 if string occupies whole page 76 | }; 77 | 78 | struct html_allocator 79 | { 80 | html_allocator(html_memory_page* root); 81 | 82 | html_memory_page* allocate_page(size_t data_size); 83 | 84 | static void deallocate_page(html_memory_page* page); 85 | 86 | void* allocate_memory_oob(size_t size, html_memory_page*& out_page); 87 | 88 | void* allocate_memory(size_t size, html_memory_page*& out_page); 89 | 90 | void deallocate_memory(void* ptr, size_t size, html_memory_page* page); 91 | 92 | pugihtml::char_t* allocate_string(size_t length); 93 | 94 | void deallocate_string(pugihtml::char_t* string); 95 | 96 | html_memory_page* _root; 97 | size_t _busy_size; 98 | }; 99 | 100 | } 101 | #endif 102 | -------------------------------------------------------------------------------- /src/pugiconfig.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * pugihtml parser - version 0.1 3 | * -------------------------------------------------------- 4 | * Copyright (c) 2012 Adgooroo, LLC (kgantchev [AT] adgooroo [DOT] com) 5 | * 6 | * This library is distributed under the MIT License. See notice in license.txt 7 | * 8 | * This work is based on the pugxml parser, which is: 9 | * Copyright (C) 2006-2010, by Arseny Kapoulkine (arseny [DOT] kapoulkine [AT] gmail [DOT] com) 10 | */ 11 | 12 | 13 | #ifndef HEADER_PUGICONFIG_HPP 14 | #define HEADER_PUGICONFIG_HPP 15 | 16 | // Uncomment this to enable wchar_t mode 17 | // #define PUGIHTML_WCHAR_MODE 18 | 19 | // Uncomment this to disable XPath 20 | // #define PUGIHTML_NO_XPATH 21 | 22 | // Uncomment this to disable STL 23 | // Note: you can't use XPath with PUGIHTML_NO_STL 24 | // #define PUGIHTML_NO_STL 25 | 26 | // Uncomment this to disable exceptions 27 | // Note: you can't use XPath with PUGIHTML_NO_EXCEPTIONS 28 | // #define PUGIHTML_NO_EXCEPTIONS 29 | 30 | // Set this to control attributes for public classes/functions, i.e.: 31 | // #define PUGIHTML_API __declspec(dllexport) // to export all public symbols from DLL 32 | // #define PUGIHTML_CLASS __declspec(dllimport) // to import all classes from DLL 33 | // #define PUGIHTML_FUNCTION __fastcall // to set calling conventions to all public functions to fastcall 34 | // In absence of PUGIHTML_CLASS/PUGIHTML_FUNCTION definitions PUGIHTML_API is used instead 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /src/pugiutil.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * pugihtml parser - version 0.1 3 | * -------------------------------------------------------- 4 | * Copyright (c) 2012 Adgooroo, LLC (kgantchev [AT] adgooroo [DOT] com) 5 | * 6 | * This library is distributed under the MIT License. See notice in license.txt 7 | * 8 | * This work is based on the pugxml parser, which is: 9 | * Copyright (C) 2006-2010, by Arseny Kapoulkine (arseny [DOT] kapoulkine [AT] gmail [DOT] com) 10 | */ 11 | 12 | #ifndef PUGI_UTIL_H 13 | #define PUGI_UTIL_H 14 | #include 15 | #include "common.hpp" 16 | 17 | namespace pugihtml 18 | { 19 | //#define ARRAYSIZE(ar) (sizeof(ar) / sizeof(ar[0])) 20 | #define TOUPPER(X){ if((X) >= 'a' && (X) <= 'z') {(X) -= ('a' - 'A');} } 21 | 22 | static inline void to_upper(char_t* str) 23 | { 24 | while(*str!=0) 25 | { 26 | TOUPPER(*str); 27 | str++; 28 | } 29 | } 30 | 31 | //static char_t* attributes[] = {"ABBR", "ACCEPT", "ACCEPT-CHARSET", 32 | // "ACCESSKEY", "ACTION", "ALIGN", "ALINK", "ALT", "ARCHIVE", 33 | // "AXIS", "BACKGROUND", "BGCOLOR", "BORDER", "CELLPADDING", 34 | // "CELLSPACING", "CHAR", "CHAROFF", "CHARSET", "CHECKED", "CITE", 35 | // "CLASS", "CLASSID", "CLEAR", "CODE", "CODEBASE", "CODETYPE", 36 | // "COLOR", "COLS", "COLSPAN", "COMPACT", "CONTENT", "COORDS", 37 | // "DATA", "DATETIME", "DECLARE", "DEFER", "DIR", "DISABLED", 38 | // "ENCTYPE", "FACE", "FOR", "FRAME", "FRAMEBORDER", "HEADERS", 39 | // "HEIGHT", "HREF", "HREFLANG", "HSPACE", "HTTP-EQUIV", "ID", 40 | // "ISMAP", "LABEL", "LANG", "LANGUAGE", "LINK", "LONGDESC", 41 | // "MARGINHEIGHT", "MARGINWIDTH", "MAXLENGTH", "MEDIA", "METHOD", 42 | // "MULTIPLE", "NAME", "NOHREF", "NORESIZE", "NOSHADE", "NOWRAP", 43 | // "OBJECT", "ONBLUR", "ONCHANGE", "ONCLICK", "ONDBLCLICK", 44 | // "ONFOCUS", "ONKEYDOWN", "ONKEYPRESS", "ONKEYUP", "ONLOAD", 45 | // "ONMOUSEDOWN", "ONMOUSEMOVE", "ONMOUSEOUT", "ONMOUSEOVER", 46 | // "ONMOUSEUP", "ONRESET", "ONSELECT", "ONSUBMIT", "ONUNLOAD", 47 | // "PROFILE", "PROMPT", "READONLY", "REL", "REV", "ROWS", "ROWSPAN", 48 | // "RULES", "SCHEME", "SCOPE", "SCROLLING", "SELECTED", "SHAPE", 49 | // "SIZE", "SPAN", "SRC", "STANDBY", "START", "STYLE", "SUMMARY", 50 | // "TABINDEX", "TARGET", "TEXT", "TITLE", "TYPE", "USEMAP", "VALIGN", 51 | // "VALUE", "VALUETYPE", "VERSION", "VLINK", "VSPACE", "WIDTH"}; 52 | 53 | //static char_t* elements[] = {"!DOCTYPE", "A", "ABBR", "ACRONYM", "ADDRESS", 54 | // "APPLET", "AREA", "ARTICLE", "ASIDE", "AUDIO", "B", "BASE", 55 | // "BASEFONT", "BDI", "BDO", "BIG", "BLOCKQUOTE", "BODY", "BR", 56 | // "BUTTON", "CANVAS", "CAPTION", "CENTER", "CITE", "CODE", "COL", 57 | // "COLGROUP", "COMMAND", "DATALIST", "DD", "DEL", "DETAILS", 58 | // "DFN", "DIR", "DIV", "DL", "DT", "EM", "EMBED", "FIELDSET", 59 | // "FIGCAPTION", "FIGURE", "FONT", "FOOTER", "FORM", "FRAME", 60 | // "FRAMESET", "H1> TO html_attributes(attributes, attributes+ARRAYSIZE(attributes)); 98 | // 99 | ///// HTML5 elements 100 | //static const std::set html_elements(elements, elements+ARRAYSIZE(elements)); 101 | 102 | ///// Tag normalization involves the capitalization of the tag if it 103 | ///// was found in the given tag set. 104 | ///// 105 | ///// tag is the tag which should be normalized 106 | ///// 107 | ///// tmp is a the temporary character array has to be large enough 108 | ///// to store valid tags and the number of characters in the tag 109 | ///// should not surpass the size of the temporary character array. 110 | ///// 111 | ///// tagSet is the set of tags which the given tag should be 112 | ///// checked against. 113 | //static inline void normalize(char_t* tag, char_t* tmp, const std::set& tagSet ) 114 | //{ 115 | // strcpy(tmp, tag); 116 | // to_upper(tmp); 117 | // if(tagSet.find(tmp) != tagSet.end()) 118 | // { 119 | // strcpy(tag, tmp); 120 | // } 121 | // memset(tmp, 0, strlen(tmp)); 122 | //} 123 | } 124 | #endif 125 | --------------------------------------------------------------------------------