diff --git a/.codecov.yml b/.codecov.yml index 230b4ed..31eef09 100644 --- a/.codecov.yml +++ b/.codecov.yml @@ -1,2 +1,7 @@ comment: false - +coverage: + status: + project: + default: + informational: true + patch: off diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..bf6948b --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,52 @@ +name: build + +on: + push: + branches: + - 'master' + pull_request: + +jobs: + unix: + strategy: + matrix: + os: [ubuntu, macos] + compiler: [g++, clang++] + defines: [standard, PUGIXML_WCHAR_MODE, PUGIXML_COMPACT, PUGIXML_NO_EXCEPTIONS] + exclude: + - os: macos + compiler: g++ + name: ${{matrix.os}} (${{matrix.compiler}}, ${{matrix.defines}}) + runs-on: ${{matrix.os}}-latest + steps: + - uses: actions/checkout@v1 + - name: make test + run: | + export CXX=${{matrix.compiler}} + make test cxxstd=c++11 defines=${{matrix.defines}} config=release -j2 + make test cxxstd=c++98 defines=${{matrix.defines}} config=debug -j2 + make test defines=${{matrix.defines}} config=sanitize -j2 + - name: make coverage + if: ${{!(matrix.os == 'ubuntu' && matrix.compiler == 'clang++')}} # linux/clang produces coverage info gcov can't parse + run: | + export CXX=${{matrix.compiler}} + make test defines=${{matrix.defines}} config=coverage -j2 + bash <(curl -s https://codecov.io/bash) -f pugixml.cpp.gcov -X search -t ${{secrets.CODECOV_TOKEN}} -B ${{github.ref}} + + windows: + runs-on: windows-latest + strategy: + matrix: + arch: [Win32, x64] + defines: [standard, PUGIXML_WCHAR_MODE, PUGIXML_COMPACT, PUGIXML_NO_EXCEPTIONS] + steps: + - uses: actions/checkout@v1 + - name: cmake configure + run: cmake . -DPUGIXML_BUILD_TESTS=ON -D${{matrix.defines}}=ON -A ${{matrix.arch}} + - name: cmake test + shell: bash # necessary for fail-fast + run: | + cmake --build . -- -property:Configuration=Debug -verbosity:minimal + Debug/pugixml-check.exe + cmake --build . -- -property:Configuration=Release -verbosity:minimal + Release/pugixml-check.exe diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 01bd59f..0000000 --- a/.travis.yml +++ /dev/null @@ -1,27 +0,0 @@ -language: cpp -os: - - linux - - osx -compiler: - - clang - - gcc - -matrix: - exclude: - - os: osx - compiler: gcc - -env: - - DEFINES=standard - - DEFINES=PUGIXML_WCHAR_MODE - - DEFINES=PUGIXML_COMPACT - - DEFINES=PUGIXML_NO_EXCEPTIONS - -script: - - if [[ ! ( "$CXX" == "clang++" && "$TRAVIS_OS_NAME" == "linux" ) ]]; then make test cxxstd=c++11 defines=$DEFINES config=coverage -j2; fi - - if [[ "$CXX" == "clang++" ]]; then make test cxxstd=c++11 defines=$DEFINES config=sanitize -j2; fi - - make test cxxstd=c++11 defines=$DEFINES config=release -j2 - - make test cxxstd=c++98 defines=$DEFINES config=debug -j2 - -after_success: - - bash <(curl -s https://codecov.io/bash) -f pugixml.cpp.gcov diff --git a/CMakeLists.txt b/CMakeLists.txt index fda789c..cdb8c21 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,38 +1,65 @@ cmake_minimum_required(VERSION 3.4) -project(pugixml VERSION 1.10 LANGUAGES CXX) +project(pugixml VERSION 1.11 LANGUAGES CXX) include(CMakePackageConfigHelpers) include(CMakeDependentOption) include(GNUInstallDirs) include(CTest) - -cmake_dependent_option(USE_VERSIONED_LIBDIR +cmake_dependent_option(PUGIXML_USE_VERSIONED_LIBDIR "Use a private subdirectory to install the headers and libraries" OFF "CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF) -cmake_dependent_option(USE_POSTFIX +cmake_dependent_option(PUGIXML_USE_POSTFIX "Use separate postfix for each configuration to make sure you can install multiple build outputs" OFF "CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF) -cmake_dependent_option(STATIC_CRT +cmake_dependent_option(PUGIXML_STATIC_CRT "Use static MSVC RT libraries" OFF "MSVC" OFF) -cmake_dependent_option(BUILD_TESTS +cmake_dependent_option(PUGIXML_BUILD_TESTS "Build pugixml tests" OFF "BUILD_TESTING;CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF) -option(BUILD_SHARED_AND_STATIC_LIBS "Build both shared and static libraries" OFF) - # Technically not needed for this file. This is builtin. +# Custom build defines +set(PUGIXML_BUILD_DEFINES CACHE STRING "Build defines for custom options") +separate_arguments(PUGIXML_BUILD_DEFINES) + +# Technically not needed for this file. This is builtin CMAKE global variable. option(BUILD_SHARED_LIBS "Build shared instead of static library" OFF) -set(BUILD_DEFINES CACHE STRING "Build defines") +# Expose option to build PUGIXML as static as well when the global BUILD_SHARED_LIBS variable is set +cmake_dependent_option(PUGIXML_BUILD_SHARED_AND_STATIC_LIBS + "Build both shared and static libraries" OFF + "BUILD_SHARED_LIBS" OFF) + +# Expose options from the pugiconfig.hpp +option(PUGIXML_WCHAR_MODE "Enable wchar_t mode" OFF) +option(PUGIXML_COMPACT "Enable compact mode" OFF) + +# Advanced options from pugiconfig.hpp +option(PUGIXML_NO_XPATH "Disable XPath" OFF) +option(PUGIXML_NO_STL "Disable STL" OFF) +option(PUGIXML_NO_EXCEPTIONS "Disable Exceptions" OFF) +mark_as_advanced(PUGIXML_NO_XPATH PUGIXML_NO_STL PUGIXML_NO_EXCEPTIONS) + +# Policy configuration +if(POLICY CMP0091) + cmake_policy(SET CMP0091 NEW) # Enables use of MSVC_RUNTIME_LIBRARY +endif() + +set(PUGIXML_PUBLIC_DEFINITIONS + $<$:PUGIXML_WCHAR_MODE> + $<$:PUGIXML_COMPACT> + $<$:PUGIXML_NO_XPATH> + $<$:PUGIXML_NO_STL> + $<$:PUGIXML_NO_EXCEPTIONS>) # This is used to backport a CMake 3.15 feature, but is also forwards compatible if (NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY) set(CMAKE_MSVC_RUNTIME_LIBRARY - MultiThreaded$<$:Debug>$<$>:DLL>) + MultiThreaded$<$:Debug>$<$>:DLL>) endif() if (NOT DEFINED CMAKE_CXX_STANDARD_REQUIRED) @@ -43,7 +70,7 @@ if (NOT DEFINED CMAKE_CXX_STANDARD) set(CMAKE_CXX_STANDARD 11) endif() -if (USE_POSTFIX) +if (PUGIXML_USE_POSTFIX) set(CMAKE_RELWITHDEBINFO_POSTFIX _r) set(CMAKE_MINSIZEREL_POSTFIX _m) set(CMAKE_DEBUG_POSTFIX _d) @@ -64,11 +91,11 @@ if (CMAKE_VERSION VERSION_LESS 3.15) set(msvc-rt-mt-static $<${msvc-rt-mt-static}:-MT>) endif() -set(versioned-dir $<$:/pugixml-${PROJECT_VERSION}>) +set(versioned-dir $<$:/pugixml-${PROJECT_VERSION}>) set(libs) -if (BUILD_SHARED_LIBS OR BUILD_SHARED_AND_STATIC_LIBS) +if (BUILD_SHARED_LIBS) add_library(pugixml-shared SHARED ${PROJECT_SOURCE_DIR}/scripts/pugixml_dll.rc ${PROJECT_SOURCE_DIR}/src/pugixml.cpp) @@ -80,6 +107,9 @@ if (BUILD_SHARED_LIBS OR BUILD_SHARED_AND_STATIC_LIBS) PUBLIC $) target_compile_definitions(pugixml-shared + PUBLIC + ${PUGIXML_BUILD_DEFINES} + ${PUGIXML_PUBLIC_DEFINITIONS} PRIVATE $<$:PUGIXML_API=__declspec\(dllexport\)>) target_compile_options(pugixml-shared @@ -90,7 +120,7 @@ if (BUILD_SHARED_LIBS OR BUILD_SHARED_AND_STATIC_LIBS) ${msvc-rt-mt-static}) endif() -if (NOT BUILD_SHARED_LIBS OR BUILD_SHARED_AND_STATIC_LIBS) +if (NOT BUILD_SHARED_LIBS OR PUGIXML_BUILD_SHARED_AND_STATIC_LIBS) add_library(pugixml-static STATIC ${PROJECT_SOURCE_DIR}/src/pugixml.cpp) add_library(pugixml::static ALIAS pugixml-static) @@ -100,6 +130,10 @@ if (NOT BUILD_SHARED_LIBS OR BUILD_SHARED_AND_STATIC_LIBS) target_include_directories(pugixml-static PUBLIC $) + target_compile_definitions(pugixml-static + PUBLIC + ${PUGIXML_BUILD_DEFINES} + ${PUGIXML_PUBLIC_DEFINITIONS}) target_compile_options(pugixml-static PRIVATE ${msvc-rt-mtd-shared} @@ -142,7 +176,7 @@ write_basic_package_version_file( "${PROJECT_BINARY_DIR}/pugixml-config-version.cmake" COMPATIBILITY SameMajorVersion) -if (USE_POSTFIX) +if (PUGIXML_USE_POSTFIX) if(CMAKE_BUILD_TYPE MATCHES RelWithDebInfo) set(LIB_POSTFIX ${CMAKE_RELWITHDEBINFO_POSTFIX}) elseif(CMAKE_BUILD_TYPE MATCHES MinSizeRel) @@ -199,7 +233,7 @@ install( DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}${versioned-dir} COMPONENT ${PUGIXML_DEVELOPMENT_COMPONENT}) -if (BUILD_TESTS) +if (PUGIXML_BUILD_TESTS) set(fuzz-pattern "tests/fuzz_*.cpp") set(test-pattern "tests/*.cpp") if (CMAKE_VERSION VERSION_GREATER 3.11) diff --git a/LICENSE.md b/LICENSE.md index 7cd2f3d..2503b81 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2006-2019 Arseny Kapoulkine +Copyright (c) 2006-2020 Arseny Kapoulkine Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation diff --git a/Makefile b/Makefile index bb740d5..028641b 100644 --- a/Makefile +++ b/Makefile @@ -77,7 +77,7 @@ docs: docs/quickstart.html docs/manual.html build/pugixml-%: .FORCE | $(RELEASE) @mkdir -p $(BUILD) - TIMESTAMP=`git show v$(VERSION) -s --format=%ct` && python scripts/archive.py $@ pugixml-$(VERSION) $$TIMESTAMP $| + TIMESTAMP=`git show v$(VERSION) -s --format=%ct` && python3 scripts/archive.py $@ pugixml-$(VERSION) $$TIMESTAMP $| $(EXECUTABLE): $(OBJECTS) $(CXX) $(OBJECTS) $(LDFLAGS) -o $@ diff --git a/README.md b/README.md index 2982ec2..1d49def 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -pugixml [![Build Status](https://travis-ci.org/zeux/pugixml.svg?branch=master)](https://travis-ci.org/zeux/pugixml) [![Build status](https://ci.appveyor.com/api/projects/status/9hdks1doqvq8pwe7/branch/master?svg=true)](https://ci.appveyor.com/project/zeux/pugixml) [![codecov.io](https://codecov.io/github/zeux/pugixml/coverage.svg?branch=master)](https://codecov.io/github/zeux/pugixml?branch=master) ![MIT](https://img.shields.io/badge/license-MIT-blue.svg) +pugixml [![Actions Status](https://github.com/zeux/pugixml/workflows/build/badge.svg)](https://github.com/zeux/pugixml/actions) [![Build status](https://ci.appveyor.com/api/projects/status/9hdks1doqvq8pwe7/branch/master?svg=true)](https://ci.appveyor.com/project/zeux/pugixml) [![codecov.io](https://codecov.io/github/zeux/pugixml/coverage.svg?branch=master)](https://codecov.io/github/zeux/pugixml?branch=master) ![MIT](https://img.shields.io/badge/license-MIT-blue.svg) ======= pugixml is a C++ XML processing library, which consists of a DOM-like interface with rich traversal/modification diff --git a/docs/manual.adoc b/docs/manual.adoc index bb73aea..80264aa 100644 --- a/docs/manual.adoc +++ b/docs/manual.adoc @@ -46,7 +46,7 @@ Thanks to *Vyacheslav Egorov* for documentation proofreading and fuzz testing. The pugixml library is distributed under the MIT license: .... -Copyright (c) 2006-2019 Arseny Kapoulkine +Copyright (c) 2006-2020 Arseny Kapoulkine Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation @@ -74,7 +74,7 @@ This means that you can freely use pugixml in your applications, both open-sourc .... This software is based on pugixml library (https://pugixml.org). -pugixml is Copyright (C) 2006-2019 Arseny Kapoulkine. +pugixml is Copyright (C) 2006-2020 Arseny Kapoulkine. .... [[install]] @@ -1683,12 +1683,12 @@ bool xml_document::save_file(const char* path, const char_t* indent = "\t", unsi bool xml_document::save_file(const wchar_t* path, const char_t* indent = "\t", unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const; ---- -These functions accept file path as its first argument, and also three optional arguments, which specify indentation and other output options (see <>) and output data encoding (see <>). The path has the target operating system format, so it can be a relative or absolute one, it should have the delimiters of the target system, it should have the exact case if the target file system is case-sensitive, etc. +These functions accept file path as its first argument, and also three optional arguments, which specify indentation and other output options (see <>) and output data encoding (see <>). The path has the target operating system format, so it can be a relative or absolute one, it should have the delimiters of the target system, it should have the exact case if the target file system is case-sensitive, etc. The functions return `true` on success and `false` if the file could not be opened or written to. File path is passed to the system file opening function as is in case of the first function (which accepts `const char* path`); the second function either uses a special file opening function if it is provided by the runtime library or converts the path to UTF-8 and uses the system file opening function. [[xml_writer_file]] -`save_file` opens the target file for writing, outputs the requested header (by default a document declaration is output, unless the document already has one), and then saves the document contents. If the file could not be opened, the function returns `false`. Calling `save_file` is equivalent to creating an `xml_writer_file` object with `FILE*` handle as the only constructor argument and then calling `save`; see <> for writer interface details. +`save_file` opens the target file for writing, outputs the requested header (by default a document declaration is output, unless the document already has one), and then saves the document contents. Calling `save_file` is equivalent to creating an `xml_writer_file` object with `FILE*` handle as the only constructor argument and then calling `save`; see <> for writer interface details. This is a simple example of saving XML document to file (link:samples/save_file.cpp[]): @@ -2217,6 +2217,27 @@ Because of the differences in document object models, performance considerations :!numbered: +[[v1.11]] +=== v1.11 ^2020-11-26^ + +Maintenance release. Changes: + +* New features: + . Add xml_node::remove_attributes and xml_node::remove_children + . Add a way to customize floating point precision via xml_attribute::set and xml_text::set overloads + +* XPath improvements: + . XPath parser now limits recursion depth which prevents stack overflow on malicious queries + +* Compatibility improvements: + . Fix Visual Studio warnings when built using clang-cl compiler + . Fix Wconversion warnings in gcc + . Fix Wzero-as-null-pointer-constant warnings in pugixml.hpp + . Work around several static analysis false positives + +* Build system changes + . The CMake package for pugixml now provides a `pugixml::pugixml` target rather than a `pugixml` target. A compatibility `pugixml` target is provided if at least version 1.11 is not requested. + [[v1.10]] === v1.10 ^2019-09-15^ diff --git a/docs/manual.html b/docs/manual.html index 4a1d501..0cec877 100644 --- a/docs/manual.html +++ b/docs/manual.html @@ -2,22 +2,21 @@ - + - + -pugixml 1.10 manual +pugixml 1.11 manual - @@ -750,9 +686,9 @@ pugixml is Copyright (C) 2006-2019 Arseny Kapoulkine.

You can download the latest source distribution as an archive:

-

pugixml-1.10.zip (Windows line endings) +

pugixml-1.11.zip (Windows line endings) / -pugixml-1.10.tar.gz (Unix line endings)

+pugixml-1.11.tar.gz (Unix line endings)

The distribution contains library source, documentation (the manual you’re reading now and the quick start guide) and some code examples. After downloading the distribution, install pugixml by extracting all files from the compressed archive.

@@ -773,7 +709,7 @@ pugixml is Copyright (C) 2006-2019 Arseny Kapoulkine.
git clone https://github.com/zeux/pugixml
 cd pugixml
-git checkout v1.10
+git checkout v1.11
@@ -790,7 +726,7 @@ git checkout v1.10
-
svn checkout https://github.com/zeux/pugixml/tags/v1.10 pugixml
+
svn checkout https://github.com/zeux/pugixml/tags/v1.11 pugixml
@@ -838,7 +774,7 @@ git checkout v1.10
-
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?
+
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?
@@ -1057,13 +993,13 @@ In that example PUGIXML_API is inconsistent between several source
  • -

    Document node (node_document) - this is the root of the tree, which consists of several child nodes. This node corresponds to xml_document class; note that xml_document is a sub-class of xml_node, so the entire node interface is also available. However, document node is special in several ways, which are covered below. There can be only one document node in the tree; document node does not have any XML representation.

    +

    Document node (node_document) - this is the root of the tree, which consists of several child nodes. This node corresponds to xml_document class; note that xml_document is a sub-class of xml_node, so the entire node interface is also available. However, document node is special in several ways, which are covered below. There can be only one document node in the tree; document node does not have any XML representation. Document generally has one child element node (see document_element()), although documents parsed from XML fragments (see parse_fragment) can have more than one.

  • Element/tag node (node_element) - this is the most common type of node, which represents XML elements. Element nodes have a name, a collection of attributes and a collection of child nodes (both of which may be empty). The attribute is a simple name/value pair. The example XML representation of element nodes is as follows:

    -
    <node attr="value"><child/></node>
    +
    <node attr="value"><child/></node>
    @@ -1074,7 +1010,7 @@ In that example PUGIXML_API is inconsistent between several source

    Plain character data nodes (node_pcdata) represent plain text in XML. PCDATA nodes have a value, but do not have a name or children/attributes. Note that plain character data is not a part of the element node but instead has its own node; an element node can have several child PCDATA nodes. The example XML representation of text nodes is as follows:

    -
    <node> text1 <child/> text2 </node>
    +
    <node> text1 <child/> text2 </node>
    @@ -1085,7 +1021,7 @@ In that example PUGIXML_API is inconsistent between several source

    Character data nodes (node_cdata) represent text in XML that is quoted in a special way. CDATA nodes do not differ from PCDATA nodes except in XML representation - the above text example looks like this with CDATA:

    -
    <node> <![CDATA[text1]]> <child/> <![CDATA[text2]]> </node>
    +
    <node> <![CDATA[text1]]> <child/> <![CDATA[text2]]> </node>
    @@ -1096,7 +1032,7 @@ In that example PUGIXML_API is inconsistent between several source

    Comment nodes (node_comment) represent comments in XML. Comment nodes have a value, but do not have a name or children/attributes. The example XML representation of a comment node is as follows:

    -
    <!-- comment text -->
    +
    <!-- comment text -->
    @@ -1107,7 +1043,7 @@ In that example PUGIXML_API is inconsistent between several source

    Processing instruction node (node_pi) represent processing instructions (PI) in XML. PI nodes have a name and an optional value, but do not have children/attributes. The example XML representation of a PI node is as follows:

    -
    <?name value?>
    +
    <?name value?>
    @@ -1118,7 +1054,7 @@ In that example PUGIXML_API is inconsistent between several source

    Declaration node (node_declaration) represents document declarations in XML. Declaration nodes have a name ("xml") and an optional collection of attributes, but do not have value or children. There can be only one declaration node in a document; moreover, it should be the topmost node (its parent should be the document). The example XML representation of a declaration node is as follows:

    -
    <?xml version="1.0"?>
    +
    <?xml version="1.0"?>
    @@ -1129,7 +1065,7 @@ In that example PUGIXML_API is inconsistent between several source

    Document type declaration node (node_doctype) represents document type declarations in XML. Document type declaration nodes have a value, which corresponds to the entire document type contents; no additional nodes are created for inner elements like <!ENTITY>. There can be only one document type declaration node in a document; moreover, it should be the topmost node (its parent should be the document). The example XML representation of a document type declaration node is as follows:

    -
    <!DOCTYPE greeting [ <!ELEMENT greeting (#PCDATA)> ]>
    +
    <!DOCTYPE greeting [ <!ELEMENT greeting (#PCDATA)> ]>
    @@ -1635,14 +1571,14 @@ Sometimes XML data should be loaded from some other source than a file, i.e. HTT
    -
    struct xml_parse_result
    +
    struct xml_parse_result
     {
         xml_parse_status status;
         ptrdiff_t offset;
         xml_encoding encoding;
     
         operator bool() const;
    -    const char* description() const;
    +    const char* description() const;
     };
    @@ -1792,7 +1728,7 @@ You should use the usual bitwise arithmetics to manipulate the bitmask: to enabl Since this flag significantly changes the DOM structure it is only recommended for parsing documents with many PCDATA nodes in memory-constrained environments. This flag is off by default.

  • -

    parse_fragment determines if document should be treated as a fragment of a valid XML. Parsing document as a fragment leads to top-level PCDATA content (i.e. text that is not located inside a node) to be added to a tree, and additionally treats documents without element nodes as valid. This flag is off by default.

    +

    parse_fragment determines if document should be treated as a fragment of a valid XML. Parsing document as a fragment leads to top-level PCDATA content (i.e. text that is not located inside a node) to be added to a tree, and additionally treats documents without element nodes as valid and permits multiple top-level element nodes. This flag is off by default.

@@ -1972,6 +1908,9 @@ The current behavior for Unicode conversion is to skip all invalid UTF sequences
  • Unicode validation is not performed so invalid UTF sequences are not rejected.

  • +
  • +

    Document can contain multiple top-level element nodes.

    +
  • @@ -2337,8 +2276,8 @@ Node and attribute iterators are somewhere in the middle between const and non-c { public: virtual bool begin(xml_node& node); - virtual bool for_each(xml_node& node) = 0; - virtual bool end(xml_node& node); + virtual bool for_each(xml_node& node) = 0; + virtual bool end(xml_node& node); int depth() const; }; @@ -2374,7 +2313,7 @@ The traversal is launched by calling traverse function on traversal
    -
    struct simple_walker: pugi::xml_tree_walker
    +
    struct simple_walker: pugi::xml_tree_walker
     {
         virtual bool for_each(pugi::xml_node& node)
         {
    @@ -2402,9 +2341,9 @@ While there are existing functions for getting a node/attribute with known conte
     
    -
    template <typename Predicate> xml_attribute xml_node::find_attribute(Predicate pred) const;
    -template <typename Predicate> xml_node xml_node::find_child(Predicate pred) const;
    -template <typename Predicate> xml_node xml_node::find_node(Predicate pred) const;
    +
    template <typename Predicate> xml_attribute xml_node::find_attribute(Predicate pred) const;
    +template <typename Predicate> xml_node xml_node::find_child(Predicate pred) const;
    +template <typename Predicate> xml_node xml_node::find_node(Predicate pred) const;
    @@ -2429,14 +2368,14 @@ While there are existing functions for getting a node/attribute with known conte return node.attribute("Timeout").as_int() < 20; } -struct allow_remote_predicate +struct allow_remote_predicate { - bool operator()(pugi::xml_attribute attr) const + bool operator()(pugi::xml_attribute attr) const { return strcmp(attr.name(), "AllowRemote") == 0; } - bool operator()(pugi::xml_node node) const + bool operator()(pugi::xml_node node) const { return node.attribute("AllowRemote").as_bool(); } @@ -2661,7 +2600,9 @@ All attributes have name and value, both of which are strings (value may be empt bool xml_attribute::set_value(long rhs); bool xml_attribute::set_value(unsigned long rhs); bool xml_attribute::set_value(double rhs); +bool xml_attribute::set_value(double rhs, int precision); bool xml_attribute::set_value(float rhs); +bool xml_attribute::set_value(float rhs, int precision); bool xml_attribute::set_value(bool rhs); bool xml_attribute::set_value(long long rhs); bool xml_attribute::set_value(unsigned long long rhs); @@ -2833,17 +2774,19 @@ Nodes and attributes do not exist without a document tree, so you can’t cr

    6.3. Removing nodes/attributes

    -

    +

    If you do not want your document to contain some node or attribute, you can remove it with one of the following functions:

    bool xml_node::remove_attribute(const xml_attribute& a);
    -bool xml_node::remove_child(const xml_node& n);
    +bool xml_node::remove_attributes(); +bool xml_node::remove_child(const xml_node& n); +bool xml_node::remove_children();
    -

    remove_attribute removes the attribute from the attribute list of the node, and returns the operation result. remove_child removes the child node with the entire subtree (including all descendant nodes and attributes) from the document, and returns the operation result. Removing fails if one of the following is true:

    +

    remove_attribute removes the attribute from the attribute list of the node, and returns the operation result. remove_child removes the child node with the entire subtree (including all descendant nodes and attributes) from the document, and returns the operation result. remove_attributes removes all the attributes of the node, and returns the operation result. remove_children removes all the child nodes of the node, and returns the operation result. Removing fails if one of the following is true:

      @@ -2918,7 +2861,9 @@ If you do not want your document to contain some node or attribute, you can remo bool xml_text::set(long rhs); bool xml_text::set(unsigned long rhs); bool xml_text::set(double rhs); +bool xml_text::set(double rhs, int precision); bool xml_text::set(float rhs); +bool xml_text::set(float rhs, int precision); bool xml_text::set(bool rhs); bool xml_text::set(long long rhs); bool xml_text::set(unsigned long long rhs); @@ -3175,13 +3120,13 @@ If you want to save the whole document to a file, you can use one of the followi
    -

    These functions accept file path as its first argument, and also three optional arguments, which specify indentation and other output options (see Output options) and output data encoding (see Encodings). The path has the target operating system format, so it can be a relative or absolute one, it should have the delimiters of the target system, it should have the exact case if the target file system is case-sensitive, etc.

    +

    These functions accept file path as its first argument, and also three optional arguments, which specify indentation and other output options (see Output options) and output data encoding (see Encodings). The path has the target operating system format, so it can be a relative or absolute one, it should have the delimiters of the target system, it should have the exact case if the target file system is case-sensitive, etc. The functions return true on success and false if the file could not be opened or written to.

    File path is passed to the system file opening function as is in case of the first function (which accepts const char* path); the second function either uses a special file opening function if it is provided by the runtime library or converts the path to UTF-8 and uses the system file opening function.

    -

    save_file opens the target file for writing, outputs the requested header (by default a document declaration is output, unless the document already has one), and then saves the document contents. If the file could not be opened, the function returns false. Calling save_file is equivalent to creating an xml_writer_file object with FILE* handle as the only constructor argument and then calling save; see Saving document via writer interface for writer interface details.

    +

    save_file opens the target file for writing, outputs the requested header (by default a document declaration is output, unless the document already has one), and then saves the document contents. Calling save_file is equivalent to creating an xml_writer_file object with FILE* handle as the only constructor argument and then calling save; see Saving document via writer interface for writer interface details.

    This is a simple example of saving XML document to file (samples/save_file.cpp):

    @@ -3249,11 +3194,11 @@ All of the above saving functions are implemented in terms of writer interface.
    -
    struct xml_string_writer: pugi::xml_writer
    +
    struct xml_string_writer: pugi::xml_writer
     {
         std::string result;
     
    -    virtual void write(const void* data, size_t size)
    +    virtual void write(const void* data, size_t size)
         {
             result.append(static_cast<const char*>(data), size);
         }
    @@ -3564,7 +3509,7 @@ The order of iteration depends on the order of nodes inside the set; the order c
     
    -
    enum xpath_node_set::type_t {type_unsorted, type_sorted, type_sorted_reverse};
    +
    enum xpath_node_set::type_t {type_unsorted, type_sorted, type_sorted_reverse};
     type_t xpath_node_set::type() const;
    @@ -3951,13 +3896,13 @@ If exceptions are disabled, then in the event of parsing failure the query is in
    -
    struct xpath_parse_result
    +
    struct xpath_parse_result
     {
         const char* error;
         ptrdiff_t offset;
     
         operator bool() const;
    -    const char* description() const;
    +    const char* description() const;
     };
    @@ -4041,6 +3986,68 @@ If exceptions are disabled, then in the event of parsing failure the query is in

    9. Changelog

    +

    v1.11 2020-11-26

    +
    +

    Maintenance release. Changes:

    +
    +
    +
      +
    • +

      New features:

      +
      +
        +
      1. +

        Add xml_node::remove_attributes and xml_node::remove_children

        +
      2. +
      3. +

        Add a way to customize floating point precision via xml_attribute::set and xml_text::set overloads

        +
      4. +
      +
      +
    • +
    • +

      XPath improvements:

      +
      +
        +
      1. +

        XPath parser now limits recursion depth which prevents stack overflow on malicious queries

        +
      2. +
      +
      +
    • +
    • +

      Compatibility improvements:

      +
      +
        +
      1. +

        Fix Visual Studio warnings when built using clang-cl compiler

        +
      2. +
      3. +

        Fix Wconversion warnings in gcc

        +
      4. +
      5. +

        Fix Wzero-as-null-pointer-constant warnings in pugixml.hpp

        +
      6. +
      7. +

        Work around several static analysis false positives

        +
      8. +
      +
      +
    • +
    • +

      Build system changes

      +
      +
        +
      1. +

        The CMake package for pugixml now provides a pugixml::pugixml target rather than a pugixml target. A compatibility pugixml target is provided if at least version 1.11 is not requested.

        +
      2. +
      +
      +
    • +
    +
    +
    +

    v1.10 2019-09-15

    Maintenance release. Changes:

    @@ -5597,9 +5604,9 @@ If exceptions are disabled, then in the event of parsing failure the query is in bool traverse(xml_tree_walker& walker); - template <typename Predicate> xml_attribute find_attribute(Predicate pred) const; - template <typename Predicate> xml_node find_child(Predicate pred) const; - template <typename Predicate> xml_node find_node(Predicate pred) const; + template <typename Predicate> xml_attribute find_attribute(Predicate pred) const; + template <typename Predicate> xml_node find_child(Predicate pred) const; + template <typename Predicate> xml_node find_node(Predicate pred) const; string_t path(char_t delimiter = '/') const; xml_node xml_node::first_element_by_path(const char_t* path, char_t delimiter = '/') const; @@ -5641,8 +5648,10 @@ If exceptions are disabled, then in the event of parsing failure the query is in bool remove_attribute(const xml_attribute& a); bool remove_attribute(const char_t* name); + bool remove_attributes(); bool remove_child(const xml_node& n); bool remove_child(const char_t* name); + bool remove_children(); xml_parse_result append_buffer(const void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto); @@ -5806,7 +5815,7 @@ If exceptions are disabled, then in the event of parsing failure the query is in xpath_node first() const; - enum type_t {type_unsorted, type_sorted, type_sorted_reverse}; + enum type_t {type_unsorted, type_sorted, type_sorted_reverse}; type_t type() const; void sort(bool reverse = false); @@ -5862,8 +5871,84 @@ If exceptions are disabled, then in the event of parsing failure the query is in
    + \ No newline at end of file diff --git a/docs/quickstart.adoc b/docs/quickstart.adoc index b4d621d..ee15665 100644 --- a/docs/quickstart.adoc +++ b/docs/quickstart.adoc @@ -255,7 +255,7 @@ If filing an issue is not possible due to privacy or other concerns, you can con The pugixml library is distributed under the MIT license: .... -Copyright (c) 2006-2019 Arseny Kapoulkine +Copyright (c) 2006-2020 Arseny Kapoulkine Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation @@ -283,5 +283,5 @@ This means that you can freely use pugixml in your applications, both open-sourc .... This software is based on pugixml library (https://pugixml.org). -pugixml is Copyright (C) 2006-2019 Arseny Kapoulkine. +pugixml is Copyright (C) 2006-2020 Arseny Kapoulkine. .... diff --git a/docs/quickstart.html b/docs/quickstart.html index 26173aa..6eac2c7 100644 --- a/docs/quickstart.html +++ b/docs/quickstart.html @@ -2,22 +2,21 @@ - + - + -pugixml 1.10 quick start guide +pugixml 1.11 quick start guide -