Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
27b68329de | ||
|
|
c8033ce9d0 | ||
|
|
974e736f2d | ||
|
|
f5dbff784c | ||
|
|
77c1bb62e7 | ||
|
|
c971615200 | ||
|
|
09721beb80 | ||
|
|
7bdf94b22e | ||
|
|
c5d771df8b | ||
|
|
3a8e1dc59e | ||
|
|
504c90b2e9 | ||
|
|
71418cc5c9 | ||
|
|
29b39bed6f | ||
|
|
485f64d425 | ||
|
|
5a18bbcd11 | ||
|
|
088551d068 | ||
|
|
5a1c8f297a | ||
|
|
95ae857450 | ||
|
|
890fc20ea5 | ||
|
|
3ebcd3e680 | ||
|
|
00577a903a | ||
|
|
15a9ee72b5 | ||
|
|
bfe4bb6b7f | ||
|
|
b343fa9547 | ||
|
|
9426bd2ae3 | ||
|
|
4a0eda5395 | ||
|
|
6795caa34c | ||
|
|
02d1011bd4 | ||
|
|
de31023032 | ||
|
|
6ee0d9645b | ||
|
|
b6ee7a39be | ||
|
|
0632188425 | ||
|
|
eeedba928a | ||
|
|
d7096f53e8 | ||
|
|
532c028fb4 | ||
|
|
c1faf38e62 | ||
|
|
1960dbc881 | ||
|
|
3a9e532a9f | ||
|
|
aedf4dfed3 | ||
|
|
9de90bcb15 | ||
|
|
d69172513e | ||
|
|
86de7ff5a0 | ||
|
|
0595296e91 | ||
|
|
8b863f56ad | ||
|
|
05fc589176 | ||
|
|
6e1e723009 | ||
|
|
9c1b438fe1 | ||
|
|
e56134e6dd | ||
|
|
058733a4bd | ||
|
|
ec81c66a09 | ||
|
|
5c52ce0319 | ||
|
|
59ec7856c0 | ||
|
|
59f944c467 | ||
|
|
3070fb6320 | ||
|
|
aa50e2914a | ||
|
|
984551e432 | ||
|
|
710052066c | ||
|
|
61c944895e | ||
|
|
e86ffc5b47 | ||
|
|
706982acd6 | ||
|
|
5a1892b321 | ||
|
|
c4cca93ad1 | ||
|
|
b0801735cd | ||
|
|
390515a31b | ||
|
|
657c33ae34 | ||
|
|
3cdb7f4ae2 | ||
|
|
caade5a28a | ||
|
|
7144cc453d | ||
|
|
11090789b4 | ||
|
|
066b6583a4 | ||
|
|
709ba74b24 | ||
|
|
a340834408 | ||
|
|
8f17faf1ca | ||
|
|
762abf1c57 | ||
|
|
a305d01bc8 | ||
|
|
081e8a3227 | ||
|
|
9d7fcbf741 | ||
|
|
ee86beb30e | ||
|
|
e7ed748b02 | ||
|
|
b299231ff7 | ||
|
|
06318b084a | ||
|
|
4bc14418d1 | ||
|
|
752afbf4df | ||
|
|
8c3038f9c8 | ||
|
|
f1f532acfc | ||
|
|
3480faa837 | ||
|
|
0f22f71f60 | ||
|
|
781e2dbe5d | ||
|
|
f1f1b4e0dd | ||
|
|
25b508056c | ||
|
|
ae163d5f06 | ||
|
|
af6cbeb170 | ||
|
|
d5f14adb3c | ||
|
|
ca4f7cfecc | ||
|
|
4d0043fb6c | ||
|
|
2729d80c94 | ||
|
|
23e617b158 | ||
|
|
13beda24b8 | ||
|
|
7e702740ff | ||
|
|
d713fd2315 | ||
|
|
a0db6e2185 | ||
|
|
3b17184379 | ||
|
|
6247ece208 | ||
|
|
30cc354fe3 | ||
|
|
2039e448cf | ||
|
|
2d42114ed1 | ||
|
|
c691c6b401 | ||
|
|
ac0ef854e0 | ||
|
|
7c66cf7b06 | ||
|
|
f1d8c51ec8 | ||
|
|
08e38a4c14 | ||
|
|
6ab3fa418b | ||
|
|
b2b4664030 | ||
|
|
3cc2daf449 | ||
|
|
96aebcb8ae | ||
|
|
86591a97c3 | ||
|
|
8fef4591be | ||
|
|
cf466ce2a2 | ||
|
|
499750ad95 | ||
|
|
cd420ab193 | ||
|
|
d99aa003ba | ||
|
|
1e3d6f15f5 | ||
|
|
2e8a2a4e1c | ||
|
|
0bd2848f33 | ||
|
|
43d7d568a7 | ||
|
|
44236fef2c | ||
|
|
6909df2478 | ||
|
|
b15bc6bf1f | ||
|
|
33f709379a | ||
|
|
4d42ba7a60 | ||
|
|
d75a081aa3 | ||
|
|
1ade1d4bea | ||
|
|
94b19a3c45 | ||
|
|
76dec417a6 | ||
|
|
6699559320 | ||
|
|
dab3a2f858 | ||
|
|
60d9656cb7 | ||
|
|
08b966e24f | ||
|
|
2e357d19a3 | ||
|
|
b138778fd9 | ||
|
|
3cfe51b72d | ||
|
|
ef856bf975 | ||
|
|
efce4a8d7a | ||
|
|
a468d5c438 | ||
|
|
db78afc2b7 | ||
|
|
bd70bd7662 | ||
|
|
1a9a41b0f4 | ||
|
|
1118066f0b | ||
|
|
ff56985924 | ||
|
|
30adb1713b | ||
|
|
58616a29aa | ||
|
|
dfb2b7f7b4 | ||
|
|
efb76c1128 | ||
|
|
bf42c4c568 | ||
|
|
5a33d2b1d7 | ||
|
|
e9d17a045e | ||
|
|
08a5048f15 | ||
|
|
f4d4316eba | ||
|
|
6749789ec4 | ||
|
|
f31ad2c1ab | ||
|
|
37ba937e05 | ||
|
|
0189471a3a | ||
|
|
c72a210ff7 | ||
|
|
3ad133a2ad | ||
|
|
a28252205a | ||
|
|
068aa22b1a | ||
|
|
e15adbe704 | ||
|
|
980cf57ff4 | ||
|
|
187cf6b5a5 | ||
|
|
b047f46e2c | ||
|
|
f75dc6dd10 | ||
|
|
1e9636303e | ||
|
|
80a531ee1d | ||
|
|
8d18de8f46 | ||
|
|
058fc601a1 | ||
|
|
750e20323b | ||
|
|
f4b89469b3 | ||
|
|
a13b5cc08d | ||
|
|
d3199a0c39 | ||
|
|
e383ce5d82 | ||
|
|
02930331f8 | ||
|
|
a469fa2cfc | ||
|
|
544b0a49eb | ||
|
|
36aa487e9c | ||
|
|
8a679cfe78 | ||
|
|
ddd3cfa4bf | ||
|
|
9d8d193288 | ||
|
|
c2c61a5905 | ||
|
|
95683943bb | ||
|
|
7e8a42ee31 | ||
|
|
5cfa7f90f1 | ||
|
|
1dc3266fff | ||
|
|
cb217f5a85 | ||
|
|
e11e0c965f | ||
|
|
b6b747244e | ||
|
|
8be081fbbe | ||
|
|
a0e0643363 | ||
|
|
3bd1f452b5 | ||
|
|
c5b288d91a | ||
|
|
0ef3da1e6e | ||
|
|
76dcd89427 | ||
|
|
43ef7e25d9 | ||
|
|
ab8af53059 | ||
|
|
86c9105154 | ||
|
|
444963e269 | ||
|
|
0cb4f02579 | ||
|
|
c342266fae | ||
|
|
39e169285c | ||
|
|
1905284494 | ||
|
|
d359402311 | ||
|
|
09e7cc9b1c | ||
|
|
f327371219 | ||
|
|
bcf483c3b7 | ||
|
|
173a263490 | ||
|
|
521b2cd854 | ||
|
|
27bc68ab45 | ||
|
|
f7de324855 | ||
|
|
3b5c1fb022 | ||
|
|
ab8453c572 | ||
|
|
2639dfd053 | ||
|
|
0401559dde | ||
|
|
832a4f4914 | ||
|
|
33a75c734b | ||
|
|
ec851bb18d | ||
|
|
6fbf32140b | ||
|
|
effc46f0ed | ||
|
|
363ebdde91 | ||
|
|
c60ca94cdd | ||
|
|
dd50fa5b45 | ||
|
|
2fa9158b4f | ||
|
|
fad2d5e4ef | ||
|
|
f388c465dd |
@@ -0,0 +1,8 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report if you believe you've found a bug in this project; please use GitHub Discussions instead if you think the bug may be in your code.
|
||||
title: ''
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
@@ -0,0 +1,5 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Help and support
|
||||
url: https://github.com/zeux/pugixml/discussions
|
||||
about: Please use GitHub Discussions if you have questions or need help.
|
||||
@@ -0,0 +1,8 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
@@ -12,35 +12,60 @@ jobs:
|
||||
matrix:
|
||||
os: [ubuntu, macos]
|
||||
compiler: [g++, clang++]
|
||||
defines: [standard, PUGIXML_WCHAR_MODE, PUGIXML_COMPACT, PUGIXML_NO_EXCEPTIONS]
|
||||
defines: [standard, PUGIXML_WCHAR_MODE, PUGIXML_COMPACT, PUGIXML_NO_EXCEPTIONS, PUGIXML_CHARCONV_FLOAT]
|
||||
exclude:
|
||||
- os: macos
|
||||
compiler: g++
|
||||
- os: macos
|
||||
defines: PUGIXML_CHARCONV_FLOAT # std::charconv is not supported until Xcode 26
|
||||
name: ${{matrix.os}} (${{matrix.compiler}}, ${{matrix.defines}})
|
||||
runs-on: ${{matrix.os}}-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/checkout@v4
|
||||
- name: make test
|
||||
if: matrix.defines != 'PUGIXML_CHARCONV_FLOAT' # std::charconv requires C++17, tested below
|
||||
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 cxxstd=c++17 defines=${{matrix.defines}} config=debug -j2
|
||||
make test defines=${{matrix.defines}} config=sanitize -j2
|
||||
- name: make test charconv
|
||||
if: matrix.defines == 'PUGIXML_CHARCONV_FLOAT'
|
||||
run: |
|
||||
export CXX=${{matrix.compiler}}
|
||||
make test cxxstd=c++17 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
|
||||
make test cxxstd=c++17 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}}
|
||||
|
||||
unix-cmake:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu, macos]
|
||||
name: ${{matrix.os}} cmake
|
||||
runs-on: ${{matrix.os}}-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: cmake configure
|
||||
run: |
|
||||
mkdir cmake && cd cmake
|
||||
cmake .. -D PUGIXML_BUILD_TESTS=ON
|
||||
- name: cmake test
|
||||
run: |
|
||||
make -C cmake -j2
|
||||
|
||||
windows:
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
matrix:
|
||||
arch: [Win32, x64]
|
||||
defines: [standard, PUGIXML_WCHAR_MODE, PUGIXML_COMPACT, PUGIXML_NO_EXCEPTIONS]
|
||||
defines: [standard, PUGIXML_WCHAR_MODE, PUGIXML_COMPACT, PUGIXML_NO_EXCEPTIONS, PUGIXML_CHARCONV_FLOAT]
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/checkout@v4
|
||||
- name: cmake configure
|
||||
run: cmake . -DPUGIXML_BUILD_TESTS=ON -D${{matrix.defines}}=ON -A ${{matrix.arch}}
|
||||
- name: cmake test
|
||||
@@ -50,3 +75,10 @@ jobs:
|
||||
Debug/pugixml-check.exe
|
||||
cmake --build . -- -property:Configuration=Release -verbosity:minimal
|
||||
Release/pugixml-check.exe
|
||||
- name: cmake configure (c++17)
|
||||
run: cmake . -DPUGIXML_BUILD_TESTS=ON -DCMAKE_CXX_STANDARD=17 -D${{matrix.defines}}=ON -A ${{matrix.arch}}
|
||||
- name: cmake test (c++17)
|
||||
shell: bash # necessary for fail-fast
|
||||
run: |
|
||||
cmake --build . -- -property:Configuration=Debug -verbosity:minimal
|
||||
Debug/pugixml-check.exe
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
name: CIFuzz
|
||||
on: [pull_request]
|
||||
jobs:
|
||||
Fuzzing:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Build Fuzzers
|
||||
id: build
|
||||
uses: google/oss-fuzz/infra/cifuzz/actions/build_fuzzers@master
|
||||
with:
|
||||
oss-fuzz-project-name: 'pugixml'
|
||||
dry-run: false
|
||||
- name: Run Fuzzers
|
||||
uses: google/oss-fuzz/infra/cifuzz/actions/run_fuzzers@master
|
||||
with:
|
||||
oss-fuzz-project-name: 'pugixml'
|
||||
fuzz-seconds: 30
|
||||
dry-run: false
|
||||
- name: Upload Crash
|
||||
uses: actions/upload-artifact@v4
|
||||
if: failure() && steps.build.outcome == 'success'
|
||||
with:
|
||||
name: artifacts
|
||||
path: ./out/artifacts
|
||||
+4
-1
@@ -1,2 +1,5 @@
|
||||
/build/
|
||||
/build*/
|
||||
|
||||
/.vscode/
|
||||
|
||||
.DS_Store
|
||||
+127
-55
@@ -1,10 +1,15 @@
|
||||
cmake_minimum_required(VERSION 3.4)
|
||||
project(pugixml VERSION 1.12 LANGUAGES CXX)
|
||||
cmake_minimum_required(VERSION 3.5...3.30)
|
||||
|
||||
# Policy configuration; this *MUST* be specified before project is defined
|
||||
if(POLICY CMP0091)
|
||||
cmake_policy(SET CMP0091 NEW) # Enables use of MSVC_RUNTIME_LIBRARY
|
||||
endif()
|
||||
|
||||
project(pugixml VERSION 1.16 LANGUAGES CXX)
|
||||
|
||||
include(CMakePackageConfigHelpers)
|
||||
include(CMakeDependentOption)
|
||||
include(GNUInstallDirs)
|
||||
include(CTest)
|
||||
|
||||
cmake_dependent_option(PUGIXML_USE_VERSIONED_LIBDIR
|
||||
"Use a private subdirectory to install the headers and libraries" OFF
|
||||
@@ -20,23 +25,37 @@ cmake_dependent_option(PUGIXML_STATIC_CRT
|
||||
|
||||
cmake_dependent_option(PUGIXML_BUILD_TESTS
|
||||
"Build pugixml tests" OFF
|
||||
"BUILD_TESTING;CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF)
|
||||
"CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR" OFF)
|
||||
|
||||
# Custom build defines
|
||||
set(PUGIXML_BUILD_DEFINES CACHE STRING "Build defines for custom options")
|
||||
separate_arguments(PUGIXML_BUILD_DEFINES)
|
||||
|
||||
# Public headers
|
||||
set(PUGIXML_HEADERS
|
||||
${PROJECT_SOURCE_DIR}/src/pugiconfig.hpp
|
||||
${PROJECT_SOURCE_DIR}/src/pugixml.hpp
|
||||
)
|
||||
|
||||
set(PUGIXML_SOURCE ${PROJECT_SOURCE_DIR}/src/pugixml.cpp)
|
||||
|
||||
# Technically not needed for this file. This is builtin CMAKE global variable.
|
||||
option(BUILD_SHARED_LIBS "Build shared instead of static library" OFF)
|
||||
option(BUILD_SHARED_LIBS "Build shared instead of static library" OFF)
|
||||
|
||||
# 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)
|
||||
|
||||
option(PUGIXML_INSTALL "Enable installation rules" ON)
|
||||
cmake_dependent_option(PUGIXML_INSTALL_SOURCE
|
||||
"Install pugixml.cpp alongside headers" OFF
|
||||
"PUGIXML_INSTALL" OFF)
|
||||
|
||||
# Expose options from the pugiconfig.hpp
|
||||
option(PUGIXML_WCHAR_MODE "Enable wchar_t mode" OFF)
|
||||
option(PUGIXML_COMPACT "Enable compact mode" OFF)
|
||||
option(PUGIXML_CHARCONV_FLOAT "Enable charconv number conversion" OFF)
|
||||
|
||||
# Advanced options from pugiconfig.hpp
|
||||
option(PUGIXML_NO_XPATH "Disable XPath" OFF)
|
||||
@@ -44,17 +63,18 @@ 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
|
||||
if (APPLE)
|
||||
option(PUGIXML_BUILD_APPLE_FRAMEWORK "Build as Apple Frameworks" OFF)
|
||||
endif()
|
||||
|
||||
set(PUGIXML_PUBLIC_DEFINITIONS
|
||||
$<$<BOOL:${PUGIXML_WCHAR_MODE}>:PUGIXML_WCHAR_MODE>
|
||||
$<$<BOOL:${PUGIXML_COMPACT}>:PUGIXML_COMPACT>
|
||||
$<$<BOOL:${PUGIXML_CHARCONV_FLOAT}>:PUGIXML_CHARCONV_FLOAT>
|
||||
$<$<BOOL:${PUGIXML_NO_XPATH}>:PUGIXML_NO_XPATH>
|
||||
$<$<BOOL:${PUGIXML_NO_STL}>:PUGIXML_NO_STL>
|
||||
$<$<BOOL:${PUGIXML_NO_EXCEPTIONS}>:PUGIXML_NO_EXCEPTIONS>)
|
||||
$<$<BOOL:${PUGIXML_NO_EXCEPTIONS}>: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)
|
||||
@@ -62,11 +82,13 @@ if (NOT DEFINED CMAKE_MSVC_RUNTIME_LIBRARY)
|
||||
MultiThreaded$<$<CONFIG:Debug>:Debug>$<$<NOT:$<BOOL:${PUGIXML_STATIC_CRT}>>:DLL>)
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED CMAKE_CXX_STANDARD_REQUIRED)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
endif()
|
||||
# Set the default C++ standard to C++17 if not set; CMake will automatically downgrade this if the compiler does not support it
|
||||
# When CMAKE_CXX_STANDARD_REQUIRED is set, we fall back to C++11 to avoid breaking older compilers
|
||||
if (NOT DEFINED CMAKE_CXX_STANDARD_REQUIRED AND NOT DEFINED CMAKE_CXX_STANDARD AND NOT CMAKE_VERSION VERSION_LESS 3.8)
|
||||
|
||||
if (NOT DEFINED CMAKE_CXX_STANDARD)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED OFF)
|
||||
elseif (NOT DEFINED CMAKE_CXX_STANDARD)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
endif()
|
||||
|
||||
@@ -98,9 +120,14 @@ set(libs)
|
||||
if (BUILD_SHARED_LIBS)
|
||||
add_library(pugixml-shared SHARED
|
||||
${PROJECT_SOURCE_DIR}/scripts/pugixml_dll.rc
|
||||
${PROJECT_SOURCE_DIR}/src/pugixml.cpp)
|
||||
${PUGIXML_SOURCE}
|
||||
${PUGIXML_HEADERS})
|
||||
add_library(pugixml::shared ALIAS pugixml-shared)
|
||||
list(APPEND libs pugixml-shared)
|
||||
string(CONCAT pugixml.msvc $<OR:
|
||||
$<STREQUAL:${CMAKE_CXX_COMPILER_FRONTEND_VARIANT},MSVC>,
|
||||
$<CXX_COMPILER_ID:MSVC>
|
||||
>)
|
||||
|
||||
set_property(TARGET pugixml-shared PROPERTY EXPORT_NAME shared)
|
||||
target_include_directories(pugixml-shared
|
||||
@@ -111,18 +138,24 @@ if (BUILD_SHARED_LIBS)
|
||||
${PUGIXML_BUILD_DEFINES}
|
||||
${PUGIXML_PUBLIC_DEFINITIONS}
|
||||
PRIVATE
|
||||
$<$<CXX_COMPILER_ID:MSVC>:PUGIXML_API=__declspec\(dllexport\)>)
|
||||
PUGIXML_API=$<IF:${pugixml.msvc},__declspec\(dllexport\),__attribute__\(\(visibility\("default"\)\)\)>
|
||||
)
|
||||
target_compile_options(pugixml-shared
|
||||
PRIVATE
|
||||
${msvc-rt-mtd-shared}
|
||||
${msvc-rt-mtd-static}
|
||||
${msvc-rt-mt-shared}
|
||||
${msvc-rt-mt-static})
|
||||
target_compile_features(pugixml-shared
|
||||
PRIVATE
|
||||
$<$<BOOL:${PUGIXML_CHARCONV_FLOAT}>:cxx_std_17>
|
||||
)
|
||||
endif()
|
||||
|
||||
if (NOT BUILD_SHARED_LIBS OR PUGIXML_BUILD_SHARED_AND_STATIC_LIBS)
|
||||
add_library(pugixml-static STATIC
|
||||
${PROJECT_SOURCE_DIR}/src/pugixml.cpp)
|
||||
${PUGIXML_SOURCE}
|
||||
${PUGIXML_HEADERS})
|
||||
add_library(pugixml::static ALIAS pugixml-static)
|
||||
list(APPEND libs pugixml-static)
|
||||
|
||||
@@ -140,6 +173,10 @@ if (NOT BUILD_SHARED_LIBS OR PUGIXML_BUILD_SHARED_AND_STATIC_LIBS)
|
||||
${msvc-rt-mtd-static}
|
||||
${msvc-rt-mt-shared}
|
||||
${msvc-rt-mt-static})
|
||||
target_compile_features(pugixml-static
|
||||
PRIVATE
|
||||
$<$<BOOL:${PUGIXML_CHARCONV_FLOAT}>:cxx_std_17>
|
||||
)
|
||||
endif()
|
||||
|
||||
if (BUILD_SHARED_LIBS)
|
||||
@@ -165,6 +202,23 @@ set_target_properties(${libs}
|
||||
EXCLUDE_FROM_ALL OFF)
|
||||
set(install-targets pugixml ${libs})
|
||||
|
||||
if (PUGIXML_BUILD_APPLE_FRAMEWORK)
|
||||
set_target_properties(${libs} PROPERTIES
|
||||
FRAMEWORK TRUE
|
||||
FRAMEWORK_VERSION ${PROJECT_VERSION}
|
||||
XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "com.github.zeux.pugixml"
|
||||
XCODE_ATTRIBUTE_INSTALL_PATH "@rpath"
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY ""
|
||||
XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO"
|
||||
XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO"
|
||||
PUBLIC_HEADER "${PUGIXML_HEADERS}"
|
||||
MACOSX_FRAMEWORK_IDENTIFIER "com.github.zeux.pugixml"
|
||||
MACOSX_FRAMEWORK_BUNDLE_VERSION ${PROJECT_VERSION}
|
||||
MACOSX_FRAMEWORK_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}
|
||||
MACOSX_RPATH TRUE
|
||||
)
|
||||
endif()
|
||||
|
||||
configure_package_config_file(
|
||||
"${PROJECT_SOURCE_DIR}/scripts/pugixml-config.cmake.in"
|
||||
"${PROJECT_BINARY_DIR}/pugixml-config.cmake"
|
||||
@@ -186,54 +240,72 @@ if (PUGIXML_USE_POSTFIX)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Handle both relative and absolute paths (e.g. NixOS) for a relocatable package
|
||||
if(IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}")
|
||||
set(PUGIXML_PC_INCLUDEDIR "${CMAKE_INSTALL_INCLUDEDIR}")
|
||||
else()
|
||||
set(PUGIXML_PC_INCLUDEDIR "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
|
||||
endif()
|
||||
if(IS_ABSOLUTE "${CMAKE_INSTALL_LIBDIR}")
|
||||
set(PUGIXML_PC_LIBDIR "${CMAKE_INSTALL_LIBDIR}")
|
||||
else()
|
||||
set(PUGIXML_PC_LIBDIR "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}")
|
||||
endif()
|
||||
configure_file(scripts/pugixml.pc.in pugixml.pc @ONLY)
|
||||
|
||||
if (NOT DEFINED PUGIXML_RUNTIME_COMPONENT)
|
||||
set(PUGIXML_RUNTIME_COMPONENT Runtime)
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED PUGIXML_LIBRARY_COMPONENT)
|
||||
set(PUGIXML_LIBRARY_COMPONENT Library)
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED PUGIXML_DEVELOPMENT_COMPONENT)
|
||||
set(PUGIXML_DEVELOPMENT_COMPONENT Development)
|
||||
endif()
|
||||
|
||||
set(namelink-component)
|
||||
if (NOT CMAKE_VERSION VERSION_LESS 3.12)
|
||||
set(namelink-component NAMELINK_COMPONENT ${PUGIXML_DEVELOPMENT_COMPONENT})
|
||||
endif()
|
||||
install(TARGETS ${install-targets}
|
||||
EXPORT pugixml-targets
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${PUGIXML_RUNTIME_COMPONENT}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${PUGIXML_LIBRARY_COMPONENT} ${namelink-component}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${PUGIXML_DEVELOPMENT_COMPONENT}
|
||||
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}${versioned-dir})
|
||||
|
||||
install(EXPORT pugixml-targets
|
||||
export(TARGETS ${install-targets}
|
||||
NAMESPACE pugixml::
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/pugixml COMPONENT ${PUGIXML_DEVELOPMENT_COMPONENT})
|
||||
FILE pugixml-targets.cmake)
|
||||
|
||||
export(EXPORT pugixml-targets
|
||||
NAMESPACE pugixml::)
|
||||
if(PUGIXML_INSTALL)
|
||||
if (NOT DEFINED PUGIXML_RUNTIME_COMPONENT)
|
||||
set(PUGIXML_RUNTIME_COMPONENT Runtime)
|
||||
endif()
|
||||
|
||||
install(FILES
|
||||
"${PROJECT_BINARY_DIR}/pugixml-config-version.cmake"
|
||||
"${PROJECT_BINARY_DIR}/pugixml-config.cmake"
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/pugixml COMPONENT ${PUGIXML_DEVELOPMENT_COMPONENT})
|
||||
if (NOT DEFINED PUGIXML_LIBRARY_COMPONENT)
|
||||
set(PUGIXML_LIBRARY_COMPONENT Library)
|
||||
endif()
|
||||
|
||||
install(FILES ${PROJECT_BINARY_DIR}/pugixml.pc
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig COMPONENT ${PUGIXML_DEVELOPMENT_COMPONENT})
|
||||
if (NOT DEFINED PUGIXML_DEVELOPMENT_COMPONENT)
|
||||
set(PUGIXML_DEVELOPMENT_COMPONENT Development)
|
||||
endif()
|
||||
|
||||
install(
|
||||
FILES
|
||||
"${PROJECT_SOURCE_DIR}/src/pugiconfig.hpp"
|
||||
"${PROJECT_SOURCE_DIR}/src/pugixml.hpp"
|
||||
DESTINATION
|
||||
${CMAKE_INSTALL_INCLUDEDIR}${versioned-dir} COMPONENT ${PUGIXML_DEVELOPMENT_COMPONENT})
|
||||
set(namelink-component)
|
||||
if (NOT CMAKE_VERSION VERSION_LESS 3.12)
|
||||
set(namelink-component NAMELINK_COMPONENT ${PUGIXML_DEVELOPMENT_COMPONENT})
|
||||
endif()
|
||||
install(TARGETS ${install-targets}
|
||||
EXPORT pugixml-targets
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${PUGIXML_RUNTIME_COMPONENT}
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${PUGIXML_LIBRARY_COMPONENT} ${namelink-component}
|
||||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT ${PUGIXML_DEVELOPMENT_COMPONENT}
|
||||
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}${versioned-dir}
|
||||
FRAMEWORK DESTINATION ${CMAKE_INSTALL_LIBDIR} COMPONENT runtime OPTIONAL
|
||||
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||
|
||||
install(EXPORT pugixml-targets
|
||||
NAMESPACE pugixml::
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/pugixml COMPONENT ${PUGIXML_DEVELOPMENT_COMPONENT})
|
||||
|
||||
install(FILES
|
||||
"${PROJECT_BINARY_DIR}/pugixml-config-version.cmake"
|
||||
"${PROJECT_BINARY_DIR}/pugixml-config.cmake"
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/pugixml COMPONENT ${PUGIXML_DEVELOPMENT_COMPONENT})
|
||||
|
||||
install(FILES ${PROJECT_BINARY_DIR}/pugixml.pc
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig COMPONENT ${PUGIXML_DEVELOPMENT_COMPONENT})
|
||||
|
||||
install(FILES ${PUGIXML_HEADERS}
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}${versioned-dir} COMPONENT ${PUGIXML_DEVELOPMENT_COMPONENT})
|
||||
|
||||
if (PUGIXML_INSTALL_SOURCE)
|
||||
install(FILES ${PUGIXML_SOURCE}
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}${versioned-dir} COMPONENT ${PUGIXML_DEVELOPMENT_COMPONENT})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (PUGIXML_BUILD_TESTS)
|
||||
include(CTest)
|
||||
set(fuzz-pattern "tests/fuzz_*.cpp")
|
||||
set(test-pattern "tests/*.cpp")
|
||||
if (CMAKE_VERSION VERSION_GREATER 3.11)
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2006-2022 Arseny Kapoulkine
|
||||
Copyright (c) 2006-2026 Arseny Kapoulkine
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
|
||||
@@ -3,15 +3,14 @@ MAKEFLAGS+=-r
|
||||
|
||||
config=debug
|
||||
defines=standard
|
||||
cxxstd=c++11
|
||||
# set cxxstd=any to disable use of -std=...
|
||||
cxxstd=any
|
||||
|
||||
BUILD=build/make-$(CXX)-$(config)-$(defines)-$(cxxstd)
|
||||
BUILD=build/make-$(firstword $(CXX))-$(config)-$(defines)-$(cxxstd)
|
||||
|
||||
SOURCES=src/pugixml.cpp $(filter-out tests/fuzz_%,$(wildcard tests/*.cpp))
|
||||
EXECUTABLE=$(BUILD)/test
|
||||
|
||||
VERSION=$(shell sed -n 's/.*version \(.*\).*/\1/p' src/pugiconfig.hpp)
|
||||
VERSION=$(shell sed -n 's/.*version \(.*\).*/\1/p; /version/q' src/pugiconfig.hpp)
|
||||
RELEASE=$(filter-out scripts/archive.py docs/%.adoc,$(shell git ls-files docs scripts src CMakeLists.txt LICENSE.md readme.txt))
|
||||
|
||||
CXXFLAGS=-g -Wall -Wextra -Werror -pedantic -Wundef -Wshadow -Wcast-align -Wcast-qual -Wold-style-cast -Wdouble-promotion
|
||||
@@ -27,7 +26,7 @@ ifeq ($(config),coverage)
|
||||
endif
|
||||
|
||||
ifeq ($(config),sanitize)
|
||||
CXXFLAGS+=-fsanitize=address,undefined -fno-sanitize=float-divide-by-zero,float-cast-overflow -fno-sanitize-recover=all
|
||||
CXXFLAGS+=-fsanitize=address,undefined -fno-sanitize-recover=all
|
||||
LDFLAGS+=-fsanitize=address,undefined
|
||||
endif
|
||||
|
||||
@@ -66,7 +65,7 @@ endif
|
||||
|
||||
fuzz_%: $(BUILD)/fuzz_%
|
||||
@mkdir -p build/$@
|
||||
$< build/$@ tests/data_fuzz_$* -max_len=1024 -dict=tests/fuzz_$*.dict
|
||||
$< build/$@ tests/data_fuzz_$* -max_len=1024 -dict=tests/fuzz_$*.dict -fork=16
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILD)
|
||||
|
||||
@@ -70,3 +70,12 @@ int main()
|
||||
## License
|
||||
|
||||
This library is available to anybody free of charge, under the terms of MIT License (see LICENSE.md).
|
||||
|
||||
This work is based on the pugxml parser, which carried the following Public Domain dedication:
|
||||
|
||||
// Pug XML Parser - Version 1.0002
|
||||
// --------------------------------------------------------
|
||||
// Copyright (C) 2003, by Kristen Wegner (kristen@tima.net)
|
||||
// Released into the Public Domain. Use at your own risk.
|
||||
// See pugxml.xml for further information, history, etc.
|
||||
// Contributions by Neville Franks (readonly@getsoft.com).
|
||||
|
||||
+33
-8
@@ -1,4 +1,9 @@
|
||||
branches:
|
||||
only:
|
||||
- master
|
||||
|
||||
image:
|
||||
- Visual Studio 2026
|
||||
- Visual Studio 2022
|
||||
- Visual Studio 2019
|
||||
- Visual Studio 2017
|
||||
@@ -6,20 +11,40 @@ image:
|
||||
|
||||
version: "{branch}-{build}"
|
||||
|
||||
for:
|
||||
- matrix:
|
||||
only:
|
||||
- image: Visual Studio 2026
|
||||
install:
|
||||
- pip install --upgrade cmake
|
||||
|
||||
build_script:
|
||||
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2013") { .\scripts\nuget_build.ps1 2013}
|
||||
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2015") { .\scripts\nuget_build.ps1 2015}
|
||||
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2017") { .\scripts\nuget_build.ps1 2017}
|
||||
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2019") { .\scripts\nuget_build.ps1 2019}
|
||||
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2022") { .\scripts\nuget_build.ps1 2022}
|
||||
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2026") { .\scripts\nuget_build.ps1 2026}
|
||||
|
||||
test_script:
|
||||
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2015") { .\tests\autotest-appveyor.ps1 9 10 11 12 14 }
|
||||
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2017") { .\tests\autotest-appveyor.ps1 15 }
|
||||
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2019") { .\tests\autotest-appveyor.ps1 19 }
|
||||
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2022") { .\tests\autotest-appveyor.ps1 22 }
|
||||
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2015") { & C:\cygwin\bin\bash.exe -c "PATH=/usr/bin:/usr/local/bin:$PATH; make config=coverage test && bash <(curl -s https://codecov.io/bash) -f pugixml.cpp.gcov 2>&1" }
|
||||
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2015") { & C:\cygwin\bin\bash.exe -c "PATH=/usr/bin:/usr/local/bin:$PATH; make config=coverage defines=PUGIXML_WCHAR_MODE test && bash <(curl -s https://codecov.io/bash) -f pugixml.cpp.gcov 2>&1" }
|
||||
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2015") { .\tests\cmake-appveyor.ps1 9 2008 }
|
||||
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2015") { .\tests\cmake-appveyor.ps1 12 2013 }
|
||||
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2015") { .\tests\cmake-appveyor.ps1 14 2015 }
|
||||
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2017") { .\tests\cmake-appveyor.ps1 15 2017 }
|
||||
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2019") { .\tests\cmake-appveyor.ps1 16 2019 }
|
||||
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2022") { .\tests\cmake-appveyor.ps1 17 2022 }
|
||||
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2026") { .\tests\cmake-appveyor.ps1 18 2026 }
|
||||
|
||||
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2015") { .\tests\autotest-appveyor.ps1 9 x86 standard }
|
||||
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2015") { .\tests\autotest-appveyor.ps1 10 x64 standard }
|
||||
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2015") { .\tests\autotest-appveyor.ps1 11 x86 PUGIXML_WCHAR_MODE }
|
||||
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2015") { .\tests\autotest-appveyor.ps1 12 x64 PUGIXML_COMPACT }
|
||||
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2015") { .\tests\autotest-appveyor.ps1 14 x64 standard }
|
||||
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2017") { .\tests\autotest-appveyor.ps1 15 x86 standard }
|
||||
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2019") { .\tests\autotest-appveyor.ps1 19 x86 PUGIXML_COMPACT }
|
||||
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2022") { .\tests\autotest-appveyor.ps1 22 x64 PUGIXML_WCHAR_MODE }
|
||||
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2026") { .\tests\autotest-appveyor.ps1 26 x64 standard }
|
||||
|
||||
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2015") { & C:\cygwin\bin\bash.exe -c "PATH=/usr/bin:/usr/local/bin:$PATH; make -j2 config=coverage test && bash <(curl -s https://codecov.io/bash) -f pugixml.cpp.gcov 2>&1" }
|
||||
- ps: if ($env:APPVEYOR_BUILD_WORKER_IMAGE -eq "Visual Studio 2015") { & C:\cygwin\bin\bash.exe -c "PATH=/usr/bin:/usr/local/bin:$PATH; make -j2 config=coverage defines=PUGIXML_WCHAR_MODE test && bash <(curl -s https://codecov.io/bash) -f pugixml.cpp.gcov 2>&1" }
|
||||
|
||||
artifacts:
|
||||
- path: .\scripts\*.nupkg
|
||||
|
||||
+266
-69
@@ -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-2022 Arseny Kapoulkine
|
||||
Copyright (c) 2006-2026 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-2022 Arseny Kapoulkine.
|
||||
pugixml is Copyright (C) 2006-2026 Arseny Kapoulkine.
|
||||
....
|
||||
|
||||
[[install]]
|
||||
@@ -116,16 +116,6 @@ The repository contains library source, documentation, code examples and full un
|
||||
|
||||
Use `latest` tag if you want to automatically get new versions. Use other tags if you want to switch to new versions only explicitly. Also please note that the master branch contains the work-in-progress version of the code; while this means that you can get new features and bug fixes from master without waiting for a new release, this also means that occasionally the code can be broken in some configurations.
|
||||
|
||||
[[install.getting.subversion]]
|
||||
==== Subversion repository
|
||||
|
||||
You can access the Git repository via Subversion using https://github.com/zeux/pugixml URL. For example, to checkout the current version, you can use this command:
|
||||
|
||||
[source,bash,subs="attributes"]
|
||||
----
|
||||
svn checkout https://github.com/zeux/pugixml/tags/v{version} pugixml
|
||||
----
|
||||
|
||||
[[install.getting.packages]]
|
||||
==== Packages
|
||||
|
||||
@@ -133,10 +123,11 @@ pugixml is available as a package via various package managers. Note that most p
|
||||
|
||||
Here's an incomplete list of pugixml packages in various systems:
|
||||
|
||||
* Linux (http://packages.ubuntu.com/search?keywords=pugixml[Ubuntu], https://tracker.debian.org/pkg/pugixml[Debian], https://apps.fedoraproject.org/packages/pugixml[Fedora], https://aur.archlinux.org/packages/pugixml/[Arch Linux], other http://pkgs.org/search/pugixml[distributions])
|
||||
* http://fbsdmon.org/ports/textproc/pugixml[FreeBSD]
|
||||
* OSX, via http://brewformulas.org/Pugixml[Homebrew]
|
||||
* Windows, via https://www.nuget.org/packages/pugixml/[NuGet]
|
||||
* Linux (http://packages.ubuntu.com/search?keywords=pugixml[Ubuntu], https://tracker.debian.org/pkg/pugixml[Debian], https://packages.fedoraproject.org/pkgs/pugixml/pugixml[Fedora], https://archlinux.org/packages/extra/x86_64/pugixml/[Arch Linux], other https://pkgs.org/download/pugixml[distributions])
|
||||
* https://www.freshports.org/textproc/pugixml[FreeBSD]
|
||||
* OSX, via https://formulae.brew.sh/formula/pugixml[Homebrew]
|
||||
* Windows, via https://www.nuget.org/packages/pugixml[NuGet]
|
||||
* C{plus}{plus} package managers (https://vcpkg.io/en/package/pugixml[vcpkg], https://conan.io/center/recipes/pugixml[Conan])
|
||||
|
||||
[[install.building]]
|
||||
=== Building pugixml
|
||||
@@ -228,6 +219,8 @@ pugixml uses several defines to control the compilation process. There are two w
|
||||
|
||||
[[PUGIXML_WCHAR_MODE]]`PUGIXML_WCHAR_MODE` define toggles between UTF-8 style interface (the in-memory text encoding is assumed to be UTF-8, most functions use `char` as character type) and UTF-16/32 style interface (the in-memory text encoding is assumed to be UTF-16/32, depending on `wchar_t` size, most functions use `wchar_t` as character type). See <<dom.unicode>> for more details.
|
||||
|
||||
[[PUGIXML_CHARCONV_FLOAT]]`PUGIXML_CHARCONV_FLOAT` will use https://en.cppreference.com/cpp/header/charconv[<charconv>] for floating-point number formatting instead of `<stdio.h>` functions, which requires C++17 and UTF-8 interface. Note that the conversion will then ignore the locale and always act as if the default `C` locale is used.
|
||||
|
||||
[[PUGIXML_COMPACT]]`PUGIXML_COMPACT` define activates a different internal representation of document storage that is much more memory efficient for documents with a lot of markup (i.e. nodes and attributes), but is slightly slower to parse and access. For details see <<dom.memory.compact>>.
|
||||
|
||||
[[PUGIXML_NO_XPATH]]`PUGIXML_NO_XPATH` define disables XPath. Both XPath interfaces and XPath implementation are excluded from compilation. This option is provided in case you do not need XPath functionality and need to save code space.
|
||||
@@ -244,16 +237,18 @@ NOTE: In that example `PUGIXML_API` is inconsistent between several source files
|
||||
|
||||
[[PUGIXML_HAS_LONG_LONG]]`PUGIXML_HAS_LONG_LONG` define enables support for `long long` type in pugixml. This define is automatically enabled if your platform is known to have `long long` support (i.e. has C{plus}{plus}11 support or uses a reasonably modern version of a known compiler); if pugixml does not recognize that your platform supports `long long` but in fact it does, you can enable the define manually.
|
||||
|
||||
[[PUGIXML_HAS_STRING_VIEW]]`PUGIXML_HAS_STRING_VIEW` define enables function overloads that accept `std::string_view` arguments. This define is automatically enabled if built targeting C{plus}{plus}17 or later; if pugixml does not recognize that your platform supports `std::string_view` but in fact it does, you can enable the define manually.
|
||||
|
||||
[[install.portability]]
|
||||
=== Portability
|
||||
|
||||
pugixml is written in standard-compliant C{plus}{plus} with some compiler-specific workarounds where appropriate. pugixml is compatible with the C{plus}{plus}11 standard, but does not require C{plus}{plus}11 support. Each version is tested with a unit test suite with code coverage exceeding 99%.
|
||||
pugixml is written in standard-compliant C{plus}{plus} with some compiler-specific workarounds where appropriate. pugixml can be compiled with any version of the C{plus}{plus} standard starting from C{plus}{plus}98; newer standards automatically enable additional functionality (move semantics and range-based for support in C{plus}{plus}11, `std::string_view` overloads in C{plus}{plus}17). Each version is tested with a unit test suite with code coverage exceeding 99%.
|
||||
|
||||
pugixml runs on a variety of desktop platforms (including Microsoft Windows, Linux, FreeBSD, Apple MacOSX and Sun Solaris), game consoles (inclusing Microsoft Xbox 360, Microsoft Xbox One, Nintendo Wii, Sony Playstation Portable and Sony Playstation 3) and mobile platforms (including Android, iOS, BlackBerry, Samsung bada and Microsoft Windows CE).
|
||||
pugixml runs on a variety of desktop platforms (including Microsoft Windows, Linux, FreeBSD, Apple MacOSX and Sun Solaris), game consoles (including Microsoft Xbox 360, Microsoft Xbox One, Nintendo Wii, Sony Playstation Portable and Sony Playstation 3) and mobile platforms (including Android, iOS, BlackBerry, Samsung bada and Microsoft Windows CE).
|
||||
|
||||
pugixml supports various architectures, such as x86/x86-64, PowerPC, ARM, MIPS and SPARC. In general it should run on any architecture since it does not use architecture-specific code and does not rely on features such as unaligned memory access.
|
||||
|
||||
pugixml can be compiled using any C++ compiler; it was tested with all versions of Microsoft Visual C{plus}{plus} from 6.0 up to 2015, GCC from 3.4 up to 5.2, Clang from 3.2 up to 3.7, as well as a variety of other compilers (e.g. Borland C{plus}{plus}, Digital Mars C{plus}{plus}, Intel C{plus}{plus}, Metrowerks CodeWarrior and PathScale). The code is written to avoid compilation warnings even on reasonably high warning levels.
|
||||
pugixml can be compiled using any C++ compiler; it was tested with all versions of Microsoft Visual C{plus}{plus} from 6.0 up to 2026, GCC from 3.4 up to 16, Clang from 3.2 up to 21, as well as a variety of other compilers (e.g. Borland C{plus}{plus}, Digital Mars C{plus}{plus}, Intel C{plus}{plus}, Metrowerks CodeWarrior and PathScale). The code is written to avoid compilation warnings even on reasonably high warning levels.
|
||||
|
||||
Note that some platforms may have very bare-bones support of C++; in some cases you'll have to use `PUGIXML_NO_STL` and/or `PUGIXML_NO_EXCEPTIONS` to compile without issues. This mostly applies to old game consoles and embedded systems.
|
||||
|
||||
@@ -270,7 +265,7 @@ The XML document is represented with a tree data structure. The root of the tree
|
||||
[[xml_node_type]]
|
||||
The tree nodes can be of one of the following types (which together form the enumeration `xml_node_type`):
|
||||
|
||||
* Document node ([[node_document]]`node_document`) - this is the root of the tree, which consists of several child nodes. This node corresponds to <<xml_document,xml_document>> class; note that <<xml_document,xml_document>> is a sub-class of <<xml_node,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 [[xml_document::document_element]]`document_element()`), although documents parsed from XML fragments (see [[parse_fragment]]`parse_fragment`) can have more than one.
|
||||
* Document node ([[node_document]]`node_document`) - this is the root of the tree, which consists of several child nodes. This node corresponds to <<xml_document,xml_document>> class; note that <<xml_document,xml_document>> is a sub-class of <<xml_node,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 <<xml_document::document_element,document_element()>>), although documents parsed from XML fragments (see <<parse_fragment,parse_fragment>>) can have more than one.
|
||||
|
||||
* Element/tag node ([[node_element]]`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:
|
||||
+
|
||||
@@ -419,8 +414,8 @@ const wchar_t* xml_node::name() const;
|
||||
bool xml_node::set_name(const wchar_t* value);
|
||||
----
|
||||
|
||||
[[char_t]][[string_t]]
|
||||
There is a special type, `pugi::char_t`, that is defined as the character type and depends on the library configuration; it will be also used in the documentation hereafter. There is also a type `pugi::string_t`, which is defined as the STL string of the character type; it corresponds to `std::string` in char mode and to `std::wstring` in wchar_t mode.
|
||||
[[char_t]][[string_t]][[string_view_t]]
|
||||
There is a special type, `pugi::char_t`, that is defined as the character type and depends on the library configuration; it will be also used in the documentation hereafter. There is also a type `pugi::string_t`, which is defined as the STL string of the character type; it corresponds to `std::string` in char mode and to `std::wstring` in wchar_t mode. Similarly, `string_view_t` is defined to be `std::basic_string_view<char_t>`. Overloads for `string_view_t` are only available when building for C++17 or later (see `PUGIXML_HAS_STRING_VIEW`).
|
||||
|
||||
In addition to the interface, the internal implementation changes to store XML data as `pugi::char_t`; this means that these two modes have different memory usage characteristics - generally UTF-8 mode is more memory and performance efficient, especially if `sizeof(wchar_t)` is 4. The conversion to `pugi::char_t` upon document loading and from `pugi::char_t` upon document saving happen automatically, which also carries minor performance penalty. The general advice however is to select the character mode based on usage scenario, i.e. if UTF-8 is inconvenient to process and most of your XML data is non-ASCII, wchar_t mode is probably a better choice.
|
||||
|
||||
@@ -459,9 +454,9 @@ Almost all functions in pugixml have the following thread-safety guarantees:
|
||||
|
||||
* it is safe to call free (non-member) functions from multiple threads
|
||||
* it is safe to perform concurrent read-only accesses to the same tree (all constant member functions do not modify the tree)
|
||||
* it is safe to perform concurrent read/write accesses, if there is only one read or write access to the single tree at a time
|
||||
* it is safe to perform concurrent read/write accesses on multiple trees, as long as each tree is only accessed from a single thread at a time
|
||||
|
||||
Concurrent modification and traversing of a single tree requires synchronization, for example via reader-writer lock. Modification includes altering document structure and altering individual node/attribute data, i.e. changing names/values.
|
||||
Concurrent read/write access to a single tree requires synchronization, for example via a reader-writer lock. Modification includes altering document structure and altering individual node/attribute data, i.e. changing names/values.
|
||||
|
||||
The only exception is <<set_memory_management_functions,set_memory_management_functions>>; it modifies global variables and as such is not thread-safe. Its usage policy has more restrictions, see <<dom.memory.custom>>.
|
||||
|
||||
@@ -483,7 +478,7 @@ pugixml requests the memory needed for document storage in big chunks, and alloc
|
||||
==== Custom memory allocation/deallocation functions
|
||||
|
||||
[[allocation_function]][[deallocation_function]]
|
||||
All memory for tree structure, tree data and XPath objects is allocated via globally specified functions, which default to malloc/free. You can set your own allocation functions with set_memory_management function. The function interfaces are the same as that of malloc/free:
|
||||
All memory for tree structure, tree data and XPath objects is allocated via globally specified functions, which default to malloc/free. You can set your own allocation functions with `set_memory_management_functions` function. The function interfaces are the same as that of malloc/free:
|
||||
|
||||
[source]
|
||||
----
|
||||
@@ -538,7 +533,7 @@ Constructing a document object using the default constructor does not result in
|
||||
|
||||
When the document is loaded from file/buffer, unless an inplace loading function is used (see <<loading.memory>>), a complete copy of character stream is made; all names/values of nodes and attributes are allocated in this buffer. This buffer is allocated via a single large allocation and is only freed when document memory is reclaimed (i.e. if the <<xml_document,xml_document>> object is destroyed or if another document is loaded in the same object). Also when loading from file or stream, an additional large allocation may be performed if encoding conversion is required; a temporary buffer is allocated, and it is freed before load function returns.
|
||||
|
||||
All additional memory, such as memory for document structure (node/attribute objects) and memory for node/attribute names/values is allocated in pages on the order of 32 Kb; actual objects are allocated inside the pages using a memory management scheme optimized for fast allocation/deallocation of many small objects. Because of the scheme specifics, the pages are only destroyed if all objects inside them are destroyed; also, generally destroying an object does not mean that subsequent object creation will reuse the same memory. This means that it is possible to devise a usage scheme which will lead to higher memory usage than expected; one example is adding a lot of nodes, and them removing all even numbered ones; not a single page is reclaimed in the process. However this is an example specifically crafted to produce unsatisfying behavior; in all practical usage scenarios the memory consumption is less than that of a general-purpose allocator because allocation meta-data is very small in size.
|
||||
All additional memory, such as memory for document structure (node/attribute objects) and memory for node/attribute names/values is allocated in pages on the order of 32 Kb; actual objects are allocated inside the pages using a memory management scheme optimized for fast allocation/deallocation of many small objects. Because of the scheme specifics, the pages are only destroyed if all objects inside them are destroyed; also, generally destroying an object does not mean that subsequent object creation will reuse the same memory. This means that it is possible to devise a usage scheme which will lead to higher memory usage than expected; one example is adding a lot of nodes, and then removing all even numbered ones; not a single page is reclaimed in the process. However this is an example specifically crafted to produce unsatisfying behavior; in all practical usage scenarios the memory consumption is less than that of a general-purpose allocator because allocation meta-data is very small in size.
|
||||
|
||||
[[dom.memory.compact]]
|
||||
==== Compact mode
|
||||
@@ -651,7 +646,7 @@ xml_parse_result xml_document::load(std::wistream& stream, unsigned int options
|
||||
|
||||
`load` with `std::istream` argument loads the document from stream from the current read position to the end, treating the stream contents as a byte stream of the specified encoding (with encoding autodetection as necessary). Thus calling `xml_document::load` on an opened `std::ifstream` object is equivalent to calling `xml_document::load_file`.
|
||||
|
||||
`load` with `std::wstream` argument treats the stream contents as a wide character stream (encoding is always <<encoding_wchar,encoding_wchar>>). Because of this, using `load` with wide character streams requires careful (usually platform-specific) stream setup (i.e. using the `imbue` function). Generally use of wide streams is discouraged, however it provides you the ability to load documents from non-Unicode encodings, i.e. you can load Shift-JIS encoded data if you set the correct locale.
|
||||
`load` with `std::wistream` argument treats the stream contents as a wide character stream (encoding is always <<encoding_wchar,encoding_wchar>>). Because of this, using `load` with wide character streams requires careful (usually platform-specific) stream setup (i.e. using the `imbue` function). Generally use of wide streams is discouraged, however it provides you the ability to load documents from non-Unicode encodings, i.e. you can load Shift-JIS encoded data if you set the correct locale.
|
||||
|
||||
This is a simple example of loading XML document from file using streams (link:samples/load_stream.cpp[]); read the sample code for more complex examples involving wide streams and locales:
|
||||
|
||||
@@ -685,7 +680,7 @@ Parsing status is represented as the `xml_parse_status` enumeration and can be o
|
||||
* [[status_ok]]`status_ok` means that no error was encountered during parsing; the source stream represents the valid XML document which was fully parsed and converted to a tree.
|
||||
|
||||
* [[status_file_not_found]]`status_file_not_found` is only returned by `load_file` function and means that file could not be opened.
|
||||
* [[status_io_error]]`status_io_error` is returned by `load_file` function and by `load` functions with `std::istream`/`std::wstream` arguments; it means that some I/O error has occurred during reading the file/stream.
|
||||
* [[status_io_error]]`status_io_error` is returned by `load_file` function and by `load` functions with `std::istream`/`std::wistream` arguments; it means that some I/O error has occurred during reading the file/stream.
|
||||
* [[status_out_of_memory]]`status_out_of_memory` means that there was not enough memory during some allocation; any allocation failure during parsing results in this error.
|
||||
* [[status_internal_error]]`status_internal_error` means that something went horribly wrong; currently this error does not occur
|
||||
|
||||
@@ -746,10 +741,12 @@ These flags control the resulting tree contents:
|
||||
|
||||
* [[parse_ws_pcdata_single]]`parse_ws_pcdata_single` determines if whitespace-only PCDATA nodes that have no sibling nodes are to be put in DOM tree. In some cases application needs to parse the whitespace-only contents of nodes, i.e. `<node> </node>`, but is not interested in whitespace markup elsewhere. It is possible to use <<parse_ws_pcdata,parse_ws_pcdata>> flag in this case, but it results in excessive allocations and complicates document processing; this flag can be used to avoid that. As an example, after parsing XML string `<node> <a> </a> </node>` with `parse_ws_pcdata_single` flag set, `<node>` element will have one child `<a>`, and `<a>` element will have one child with type <<node_pcdata,node_pcdata>> and value `" "`. This flag has no effect if <<parse_ws_pcdata,parse_ws_pcdata>> is enabled. This flag is *off* by default.
|
||||
|
||||
* [[parse_embed_pcdata]]`parse_embed_pcdata` determines if PCDATA contents is to be saved as element values. Normally element nodes have names but not values; this flag forces the parser to store the contents as a value if PCDATA is the first child of the element node (otherwise PCDATA node is created as usual). This can significantly reduce the memory required for documents with many PCDATA nodes. To retrieve the data you can use `xml_node::value()` on the element nodes or any of the higher-level functions like `child_value` or `text`. This flag is *off* by default.
|
||||
* [[parse_embed_pcdata]]`parse_embed_pcdata` determines if PCDATA contents is to be saved as element values. Normally element nodes have names but not values; this flag forces the parser to store the contents as a value if PCDATA is the first child of the element node (otherwise PCDATA node is created as usual). This can significantly reduce the memory required for documents with many PCDATA nodes. To retrieve the data you can use `xml_node::value()` on the element nodes or any of the higher-level functions like `child_value` or `text`.
|
||||
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]]`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.
|
||||
* [[parse_merge_pcdata]]`parse_merge_pcdata` determines if PCDATA contents is to be merged with the previous PCDATA node when no intermediary nodes are present between them. If the PCDATA contains CDATA sections, PI nodes, or comments in between, and either of the flags <<parse_cdata,parse_cdata>>, <<parse_pi,parse_pi>>, <<parse_comments,parse_comments>> is not set, the contents of the PCDATA node will be merged with the previous one. This flag is *off* by default. Note that this flag is not compatible with `parse_embed_pcdata`.
|
||||
|
||||
* [[parse_fragment]]`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 (currently multiple top-level element nodes are also permitted when the flag is off, but that behavior should not be relied on). This flag is *off* by default.
|
||||
|
||||
CAUTION: Using in-place parsing (<<xml_document::load_buffer_inplace,load_buffer_inplace>>) with `parse_fragment` flag may result in the loss of the last character of the buffer if it is a part of PCDATA. Since PCDATA values are null-terminated strings, the only way to resolve this is to provide a null-terminated buffer as an input to `load_buffer_inplace` - i.e. `doc.load_buffer_inplace("test\0", 5, pugi::parse_default | pugi::parse_fragment)`.
|
||||
|
||||
@@ -823,10 +820,10 @@ As for rejecting invalid XML documents, there are a number of incompatibilities
|
||||
[[access]]
|
||||
== Accessing document data
|
||||
|
||||
pugixml features an extensive interface for getting various types of data from the document and for traversing the document. This section provides documentation for all such functions that do not modify the tree except for XPath-related functions; see <<xpath>> for XPath reference. As discussed in <<dom.cpp>>, there are two types of handles to tree data - <<xml_node,xml_node>> and <<xml_attribute,xml_attribute>>. The handles have special null (empty) values which propagate through various functions and thus are useful for writing more concise code; see <<node_null,this description>> for details. The documentation in this section will explicitly state the results of all function in case of null inputs.
|
||||
|
||||
[import samples/traverse_base.cpp]
|
||||
|
||||
pugixml features an extensive interface for getting various types of data from the document and for traversing the document. This section provides documentation for all such functions that do not modify the tree except for XPath-related functions; see <<xpath>> for XPath reference. As discussed in <<dom.cpp>>, there are two types of handles to tree data - <<xml_node,xml_node>> and <<xml_attribute,xml_attribute>>. The handles have special null (empty) values which propagate through various functions and thus are useful for writing more concise code; see <<node_null,this description>> for details. The documentation in this section will explicitly state the results of all function in case of null inputs.
|
||||
|
||||
[[access.basic]]
|
||||
=== Basic traversal functions
|
||||
|
||||
@@ -930,13 +927,13 @@ unsigned long long xml_attribute::as_ullong(unsigned long long def = 0) const;
|
||||
|
||||
`as_int`, `as_uint`, `as_llong`, `as_ullong`, `as_double` and `as_float` convert attribute values to numbers. If attribute handle is null `def` argument is returned (which is 0 by default). Otherwise, all leading whitespace characters are truncated, and the remaining string is parsed as an integer number in either decimal or hexadecimal form (applicable to `as_int`, `as_uint`, `as_llong` and `as_ullong`; hexadecimal format is used if the number has `0x` or `0X` prefix) or as a floating point number in either decimal or scientific form (`as_double` or `as_float`).
|
||||
|
||||
In case the input string contains a non-numeric character sequence or a number that is out of the target numeric range, the result is undefined.
|
||||
For integer conversions, non-numeric character sequences return 0 and out of range values are clamped to the closest representable value; for floating-point conversions, the result depends on implementation (CRT or STL depending on whether `PUGIXML_CHARCONV_FLOAT` is used).
|
||||
|
||||
CAUTION: Number conversion functions depend on current C locale as set with `setlocale`, so may return unexpected results if the locale is different from `"C"`.
|
||||
CAUTION: Floating-point conversion functions depend on the current C locale as set with `setlocale`, so may return unexpected results if the locale is different from `"C"`. This does not apply when pugixml is built with `PUGIXML_CHARCONV_FLOAT`.
|
||||
|
||||
`as_bool` converts attribute value to boolean as follows: if attribute handle is null, `def` argument is returned (which is `false` by default). If attribute value is empty, `false` is returned. Otherwise, `true` is returned if the first character is one of `'1', 't', 'T', 'y', 'Y'`. This means that strings like `"true"` and `"yes"` are recognized as `true`, while strings like `"false"` and `"no"` are recognized as `false`. For more complex matching you'll have to write your own function.
|
||||
|
||||
NOTE: `as_llong` and `as_ullong` are only available if your platform has reliable support for the `long long` type, including string conversions.
|
||||
NOTE: `as_llong` and `as_ullong` are only available if your platform has support for the `long long` type.
|
||||
|
||||
[[code_traverse_base_data]]
|
||||
This is an example of using these functions, along with node data retrieval ones (link:samples/traverse_base.cpp[]):
|
||||
@@ -955,9 +952,13 @@ Since a lot of document traversal consists of finding the node/attribute with th
|
||||
[source]
|
||||
----
|
||||
xml_node xml_node::child(const char_t* name) const;
|
||||
xml_node xml_node::child(string_view_t name) const;
|
||||
xml_attribute xml_node::attribute(const char_t* name) const;
|
||||
xml_attribute xml_node::attribute(string_view_t name) const;
|
||||
xml_node xml_node::next_sibling(const char_t* name) const;
|
||||
xml_node xml_node::next_sibling(string_view_t name) const;
|
||||
xml_node xml_node::previous_sibling(const char_t* name) const;
|
||||
xml_node xml_node::previous_sibling(string_view_t name) const;
|
||||
----
|
||||
|
||||
`child` and `attribute` return the first child/attribute with the specified name; `next_sibling` and `previous_sibling` return the first sibling in the corresponding direction with the specified name. All string comparisons are case-sensitive. In case the node handle is null or there is no node/attribute with the specified name, null handle is returned.
|
||||
@@ -969,6 +970,29 @@ xml_node xml_node::previous_sibling(const char_t* name) const;
|
||||
for (pugi::xml_node tool = tools.child("Tool"); tool; tool = tool.next_sibling("Tool"))
|
||||
----
|
||||
|
||||
[[xml_node::attribute_hinted]]
|
||||
`attribute` function needs to look for the target attribute by name. If a node has many attributes, finding each by name can be time consuming. If you have an idea of how attributes are ordered in the node, you can use a faster function:
|
||||
|
||||
[source]
|
||||
----
|
||||
xml_attribute xml_node::attribute(const char_t* name, xml_attribute& hint) const;
|
||||
xml_attribute xml_node::attribute(string_view_t name, xml_attribute& hint) const;
|
||||
----
|
||||
|
||||
The extra `hint` argument is used to guess where the attribute might be, and is updated to the location of the next attribute so that if you search for multiple attributes in the right order, the performance is maximized. Note that `hint` has to be either null or has to belong to the node, otherwise the behavior is undefined.
|
||||
|
||||
You can use this function as follows:
|
||||
|
||||
[source]
|
||||
----
|
||||
xml_attribute hint;
|
||||
xml_attribute id = node.attribute("id", hint);
|
||||
xml_attribute name = node.attribute("name", hint);
|
||||
xml_attribute version = node.attribute("version", hint);
|
||||
----
|
||||
|
||||
This code is correct regardless of the order of the attributes, but it's faster if `"id"`, `"name"` and `"version"` occur in that order.
|
||||
|
||||
[[xml_node::find_child_by_attribute]]
|
||||
Occasionally the needed node is specified not by the unique name but instead by the value of some attribute; for example, it is common to have node collections with each node having a unique id: `<group><item id="1"/> <item id="2"/></group>`. There are two functions for finding child nodes based on the attribute values:
|
||||
|
||||
@@ -993,7 +1017,7 @@ include::samples/traverse_base.cpp[tags=contents]
|
||||
=== Range-based for-loop support
|
||||
|
||||
[[xml_node::children]][[xml_node::attributes]]
|
||||
If your C{plus}{plus} compiler supports range-based for-loop (this is a C{plus}{plus}11 feature, at the time of writing it's supported by Microsoft Visual Studio 2012+, GCC 4.6+ and Clang 3.0+), you can use it to enumerate nodes/attributes. Additional helpers are provided to support this; note that they are also compatible with http://www.boost.org/libs/foreach/[Boost Foreach], and possibly other pre-C{plus}{plus}11 foreach facilities.
|
||||
If your C{plus}{plus} compiler supports range-based for-loop (this is a C{plus}{plus}11 feature, supported by Microsoft Visual Studio 2012+, GCC 4.6+ and Clang 3.0+), you can use it to enumerate nodes/attributes. Additional helpers are provided to support this; note that they are also compatible with http://www.boost.org/libs/foreach/[Boost Foreach], and possibly other pre-C{plus}{plus}11 foreach facilities.
|
||||
|
||||
[source,subs="+quotes"]
|
||||
----
|
||||
@@ -1015,7 +1039,19 @@ While using `children()` makes the intent of the code clear, note that each node
|
||||
|
||||
[source]
|
||||
----
|
||||
for (pugi::xml_node child: tool)
|
||||
for (pugi::xml_node child: tool) ...
|
||||
----
|
||||
|
||||
When using C{plus}{plus}20, you can also use nodes as well as objects returned by `children()` and `attributes()` functions as ranges:
|
||||
|
||||
[source]
|
||||
----
|
||||
auto tf =
|
||||
tools.children("Tool")
|
||||
| std::views::filter([](auto node) { return node.attribute("AllowRemote").as_bool(); })
|
||||
| std::views::reverse;
|
||||
|
||||
for (pugi::xml_node tool: tf) ...
|
||||
----
|
||||
|
||||
[[access.iterators]]
|
||||
@@ -1238,12 +1274,12 @@ If the offset is not available (this happens if the node is null, was not origin
|
||||
[[modify]]
|
||||
== Modifying document data
|
||||
|
||||
[import samples/modify_base.cpp]
|
||||
|
||||
The document in pugixml is fully mutable: you can completely change the document structure and modify the data of nodes/attributes. This section provides documentation for the relevant functions. All functions take care of memory management and structural integrity themselves, so they always result in structurally valid tree - however, it is possible to create an invalid XML tree (for example, by adding two attributes with the same name or by setting attribute/node name to empty/invalid string). Tree modification is optimized for performance and for memory consumption, so if you have enough memory you can create documents from scratch with pugixml and later save them to file/stream instead of relying on error-prone manual text writing and without too much overhead.
|
||||
|
||||
All member functions that change node/attribute data or structure are non-constant and thus can not be called on constant handles. However, you can easily convert constant handle to non-constant one by simple assignment: `void foo(const pugi::xml_node& n) { pugi::xml_node nc = n; }`, so const-correctness here mainly provides additional documentation.
|
||||
|
||||
[import samples/modify_base.cpp]
|
||||
|
||||
[[modify.nodedata]]
|
||||
=== Setting node data
|
||||
|
||||
@@ -1253,7 +1289,11 @@ As discussed before, nodes can have name and value, both of which are strings. D
|
||||
[source]
|
||||
----
|
||||
bool xml_node::set_name(const char_t* rhs);
|
||||
bool xml_node::set_name(const char_t* rhs, size_t sz);
|
||||
bool xml_node::set_name(string_view_t rhs);
|
||||
bool xml_node::set_value(const char_t* rhs);
|
||||
bool xml_node::set_value(const char_t* rhs, size_t size);
|
||||
bool xml_node::set_value(string_view_t rhs);
|
||||
----
|
||||
|
||||
Both functions try to set the name/value to the specified string, and return the operation result. The operation fails if the node can not have name or value (for instance, when trying to call `set_name` on a <<node_pcdata,node_pcdata>> node), if the node handle is null, or if there is insufficient memory to handle the request. The provided string is copied into document managed memory and can be destroyed after the function returns (for example, you can safely pass stack-allocated buffers to these functions). The name/value content is not verified, so take care to use only valid XML names, or the document may become malformed.
|
||||
@@ -1274,7 +1314,11 @@ All attributes have name and value, both of which are strings (value may be empt
|
||||
[source]
|
||||
----
|
||||
bool xml_attribute::set_name(const char_t* rhs);
|
||||
bool xml_attribute::set_name(const char_t* rhs, size_t sz);
|
||||
bool xml_attribute::set_name(string_view_t rhs);
|
||||
bool xml_attribute::set_value(const char_t* rhs);
|
||||
bool xml_attribute::set_value(const char_t* rhs, size_t size);
|
||||
bool xml_attribute::set_value(string_view_t rhs);
|
||||
----
|
||||
|
||||
Both functions try to set the name/value to the specified string, and return the operation result. The operation fails if the attribute handle is null, or if there is insufficient memory to handle the request. The provided string is copied into document managed memory and can be destroyed after the function returns (for example, you can safely pass stack-allocated buffers to these functions). The name/value content is not verified, so take care to use only valid XML names, or the document may become malformed.
|
||||
@@ -1298,9 +1342,9 @@ bool xml_attribute::set_value(unsigned long long rhs);
|
||||
|
||||
The above functions convert the argument to string and then call the base `set_value` function. Integers are converted to a decimal form, floating-point numbers are converted to either decimal or scientific form, depending on the number magnitude, boolean values are converted to either `"true"` or `"false"`.
|
||||
|
||||
CAUTION: Number conversion functions depend on current C locale as set with `setlocale`, so may generate unexpected results if the locale is different from `"C"`.
|
||||
CAUTION: Floating-point conversion functions depend on the current C locale as set with `setlocale`, so may generate unexpected results if the locale is different from `"C"`. This does not apply when pugixml is built with `PUGIXML_CHARCONV_FLOAT`.
|
||||
|
||||
NOTE: `set_value` overloads with `long long` type are only available if your platform has reliable support for the type, including string conversions.
|
||||
NOTE: `set_value` overloads with `long long` type are only available if your platform has support for the type.
|
||||
|
||||
[[xml_attribute::assign]]
|
||||
|
||||
@@ -1309,6 +1353,7 @@ For convenience, all `set_value` functions have the corresponding assignment ope
|
||||
[source]
|
||||
----
|
||||
xml_attribute& xml_attribute::operator=(const char_t* rhs);
|
||||
xml_attribute& xml_attribute::operator=(string_view_t rhs);
|
||||
xml_attribute& xml_attribute::operator=(int rhs);
|
||||
xml_attribute& xml_attribute::operator=(unsigned int rhs);
|
||||
xml_attribute& xml_attribute::operator=(long rhs);
|
||||
@@ -1332,15 +1377,19 @@ include::samples/modify_base.cpp[tags=attr]
|
||||
[[modify.add]]
|
||||
=== Adding nodes/attributes
|
||||
|
||||
[[xml_node::prepend_attribute]][[xml_node::append_attribute]][[xml_node::insert_attribute_after]][[xml_node::insert_attribute_before]][[xml_node::prepend_child]][[xml_node::append_child]][[xml_node::insert_child_after]][[xml_node::insert_child_before]]
|
||||
[[xml_node::prepend_attribute]][[xml_node::append_attribute]][[xml_node::insert_attribute_after]][[xml_node::insert_attribute_before]][[xml_node::ensure_attribute]][[xml_node::prepend_child]][[xml_node::append_child]][[xml_node::insert_child_after]][[xml_node::insert_child_before]][[xml_node::ensure_child]]
|
||||
Nodes and attributes do not exist without a document tree, so you can't create them without adding them to some document. A node or attribute can be created at the end of node/attribute list or before/after some other node:
|
||||
|
||||
[source]
|
||||
----
|
||||
xml_attribute xml_node::append_attribute(const char_t* name);
|
||||
xml_attribute xml_node::append_attribute(string_view_t name);
|
||||
xml_attribute xml_node::prepend_attribute(const char_t* name);
|
||||
xml_attribute xml_node::prepend_attribute(string_view_t name);
|
||||
xml_attribute xml_node::insert_attribute_after(const char_t* name, const xml_attribute& attr);
|
||||
xml_attribute xml_node::insert_attribute_after(string_view_t name, const xml_attribute& attr);
|
||||
xml_attribute xml_node::insert_attribute_before(const char_t* name, const xml_attribute& attr);
|
||||
xml_attribute xml_node::insert_attribute_before(string_view_t name, const xml_attribute& attr);
|
||||
|
||||
xml_node xml_node::append_child(xml_node_type type = node_element);
|
||||
xml_node xml_node::prepend_child(xml_node_type type = node_element);
|
||||
@@ -1348,28 +1397,37 @@ xml_node xml_node::insert_child_after(xml_node_type type, const xml_node& node);
|
||||
xml_node xml_node::insert_child_before(xml_node_type type, const xml_node& node);
|
||||
|
||||
xml_node xml_node::append_child(const char_t* name);
|
||||
xml_node xml_node::append_child(string_view_t name);
|
||||
xml_node xml_node::prepend_child(const char_t* name);
|
||||
xml_node xml_node::prepend_child(string_view_t name);
|
||||
xml_node xml_node::insert_child_after(const char_t* name, const xml_node& node);
|
||||
xml_node xml_node::insert_child_after(string_view_t name, const xml_node& node);
|
||||
xml_node xml_node::insert_child_before(const char_t* name, const xml_node& node);
|
||||
xml_node xml_node::insert_child_before(string_view_t name, const xml_node& node);
|
||||
|
||||
xml_attribute xml_node::ensure_attribute(const char_t* name);
|
||||
xml_attribute xml_node::ensure_attribute(string_view_t name);
|
||||
xml_node xml_node::ensure_child(const char_t* name);
|
||||
xml_node xml_node::ensure_child(string_view_t name);
|
||||
----
|
||||
|
||||
`append_attribute` and `append_child` create a new node/attribute at the end of the corresponding list of the node the method is called on; `prepend_attribute` and `prepend_child` create a new node/attribute at the beginning of the list; `insert_attribute_after`, `insert_attribute_before`, `insert_child_after` and `insert_attribute_before` add the node/attribute before or after the specified node/attribute.
|
||||
`append_attribute` and `append_child` create a new node/attribute at the end of the corresponding list of the node the method is called on; `prepend_attribute` and `prepend_child` create a new node/attribute at the beginning of the list; `insert_attribute_after`, `insert_attribute_before`, `insert_child_after` and `insert_child_before` add the node/attribute before or after the specified node/attribute. `ensure_attribute` and `ensure_child` return the existing attribute/child with the specified name, appending a new one only if no such attribute/child exists; this makes it convenient to write code like `node.ensure_attribute("id") = 123;`.
|
||||
|
||||
Attribute functions create an attribute with the specified name; you can specify the empty name and change the name later if you want to. Node functions with the `type` argument create the node with the specified type; since node type can't be changed, you have to know the desired type beforehand. Also note that not all types can be added as children; see below for clarification. Node functions with the `name` argument create the element node (<<node_element,node_element>>) with the specified name.
|
||||
|
||||
All functions return the handle to the created object on success, and null handle on failure. There are several reasons for failure:
|
||||
|
||||
* Adding fails if the target node is null;
|
||||
* Only <<node_element,node_element>> nodes can contain attributes, so attribute adding fails if node is not an element;
|
||||
* Only <<node_element,node_element>> and <<node_declaration,node_declaration>> nodes can contain attributes, so attribute adding fails if node is not an element or a declaration;
|
||||
* Only <<node_document,node_document>> and <<node_element,node_element>> nodes can contain children, so child node adding fails if the target node is not an element or a document;
|
||||
* <<node_document,node_document>> and <<node_null,node_null>> nodes can not be inserted as children, so passing <<node_document,node_document>> or <<node_null,node_null>> value as `type` results in operation failure;
|
||||
* <<node_declaration,node_declaration>> nodes can only be added as children of the document node; attempt to insert declaration node as a child of an element node fails;
|
||||
* <<node_declaration,node_declaration>> and <<node_doctype,node_doctype>> nodes can only be added as children of the document node; attempt to insert them as children of an element node fails;
|
||||
* Adding node/attribute results in memory allocation, which may fail;
|
||||
* Insertion functions fail if the specified node or attribute is null or is not in the target node's children/attribute list.
|
||||
|
||||
Even if the operation fails, the document remains in consistent state, but the requested node/attribute is not added.
|
||||
|
||||
CAUTION: `attribute()` and `child()` functions do not add attributes or nodes to the tree, so code like `node.attribute("id") = 123;` will not do anything if `node` does not have an attribute with name `"id"`. Make sure you're operating with existing attributes/nodes by adding them if necessary.
|
||||
CAUTION: `attribute()` and `child()` functions do not add attributes or nodes to the tree, so code like `node.attribute("id") = 123;` will not do anything if `node` does not have an attribute with name `"id"`. Make sure you're operating with existing attributes/nodes by adding them if necessary, or use `ensure_attribute`/`ensure_child`.
|
||||
|
||||
This is an example of adding new attributes/nodes to the document (link:samples/modify_add.cpp[]):
|
||||
|
||||
@@ -1405,7 +1463,9 @@ If you want to remove the attribute or child node by its name, two additional he
|
||||
[source]
|
||||
----
|
||||
bool xml_node::remove_attribute(const char_t* name);
|
||||
bool xml_node::remove_attribute(string_view_t name);
|
||||
bool xml_node::remove_child(const char_t* name);
|
||||
bool xml_node::remove_child(string_view_t name);
|
||||
----
|
||||
|
||||
These functions look for the first attribute or child with the specified name, and then remove it, returning the result. If there is no attribute or child with such name, the function returns `false`; if there are two nodes with the given name, only the first node is deleted. If you want to delete all nodes with the specified name, you can use code like this: `while (node.remove_child("tool")) ;`.
|
||||
@@ -1428,9 +1488,11 @@ Once you have an `xml_text` object, you can set the text contents using the foll
|
||||
[source]
|
||||
----
|
||||
bool xml_text::set(const char_t* rhs);
|
||||
bool xml_text::set(const char_t* rhs, size_t size);
|
||||
bool xml_text::set(string_view_t rhs);
|
||||
----
|
||||
|
||||
This function tries to set the contents to the specified string, and returns the operation result. The operation fails if the text object was retrieved from a node that can not have a value and is not an element node (i.e. it is a <<node_declaration,node_declaration>> node), if the text object is empty, or if there is insufficient memory to handle the request. The provided string is copied into document managed memory and can be destroyed after the function returns (for example, you can safely pass stack-allocated buffers to this function). Note that if the text object was retrieved from an element node, this function creates the PCDATA child node if necessary (i.e. if the element node does not have a PCDATA/CDATA child already).
|
||||
This function tries to set the contents to the specified string, and returns the operation result. The operation fails if the text object was retrieved from a node that can not have a value and is not an element node (i.e. it is a <<node_declaration,node_declaration>> node), if the node handle is null, or if there is insufficient memory to handle the request. The provided string is copied into document managed memory and can be destroyed after the function returns (for example, you can safely pass stack-allocated buffers to this function). Note that if the text object was retrieved from an element node, this function creates the PCDATA child node if necessary (i.e. if the element node does not have a PCDATA/CDATA child already).
|
||||
|
||||
[[xml_text::set_value]]
|
||||
In addition to a string function, several functions are provided for handling text with numbers and booleans as contents:
|
||||
@@ -1459,6 +1521,7 @@ For convenience, all `set` functions have the corresponding assignment operators
|
||||
[source]
|
||||
----
|
||||
xml_text& xml_text::operator=(const char_t* rhs);
|
||||
xml_text& xml_text::operator=(string_view_t rhs);
|
||||
xml_text& xml_text::operator=(int rhs);
|
||||
xml_text& xml_text::operator=(unsigned int rhs);
|
||||
xml_text& xml_text::operator=(long rhs);
|
||||
@@ -1555,6 +1618,8 @@ bool append_fragment(pugi::xml_node target, const char* buffer, size_t size)
|
||||
|
||||
for (pugi::xml_node child = doc.first_child(); child; child = child.next_sibling())
|
||||
target.append_copy(child);
|
||||
|
||||
return true;
|
||||
}
|
||||
----
|
||||
|
||||
@@ -1562,7 +1627,7 @@ bool append_fragment(pugi::xml_node target, const char* buffer, size_t size)
|
||||
+
|
||||
[source]
|
||||
----
|
||||
bool append_fragment(pugi::xml_node target, const pugi::xml_document& cached_fragment)
|
||||
void append_fragment(pugi::xml_node target, const pugi::xml_document& cached_fragment)
|
||||
{
|
||||
for (pugi::xml_node child = cached_fragment.first_child(); child; child = child.next_sibling())
|
||||
target.append_copy(child);
|
||||
@@ -1630,10 +1695,10 @@ void xml_document::save(std::ostream& stream, const char_t* indent = "\t", unsig
|
||||
void xml_document::save(std::wostream& stream, const char_t* indent = "\t", unsigned int flags = format_default) const;
|
||||
----
|
||||
|
||||
`save` with `std::ostream` argument saves the document to the stream in the same way as `save_file` (i.e. with requested header and with encoding conversions). On the other hand, `save` with `std::wstream` argument saves the document to the wide stream with <<encoding_wchar,encoding_wchar>> encoding. Because of this, using `save` with wide character streams requires careful (usually platform-specific) stream setup (i.e. using the `imbue` function). Generally use of wide streams is discouraged, however it provides you with the ability to save documents to non-Unicode encodings, i.e. you can save Shift-JIS encoded data if you set the correct locale.
|
||||
`save` with `std::ostream` argument saves the document to the stream in the same way as `save_file` (i.e. with requested header and with encoding conversions). On the other hand, `save` with `std::wostream` argument saves the document to the wide stream with <<encoding_wchar,encoding_wchar>> encoding. Because of this, using `save` with wide character streams requires careful (usually platform-specific) stream setup (i.e. using the `imbue` function). Generally use of wide streams is discouraged, however it provides you with the ability to save documents to non-Unicode encodings, i.e. you can save Shift-JIS encoded data if you set the correct locale.
|
||||
|
||||
[[xml_writer_stream]]
|
||||
Calling `save` with stream target is equivalent to creating an `xml_writer_stream` object with stream as the only constructor argument and then calling `save`; see <<saving.writer>> for writer interface details.
|
||||
Calling `save` with stream target is equivalent to creating an `xml_writer_stream` object with stream as the only constructor argument and then calling `save`; see <<saving.writer>> for writer interface details. When using `xml_writer_stream` with wide-character streams, you must pass `encoding_wchar` explicitly, as the wide writer expects wide-character data.
|
||||
|
||||
This is a simple example of saving XML document to standard output (link:samples/save_stream.cpp[]):
|
||||
|
||||
@@ -1722,7 +1787,7 @@ These flags control the additional output information:
|
||||
* [[format_write_bom]]`format_write_bom` enables Byte Order Mark (BOM) output. By default, no BOM is output, so in case of non UTF-8 encodings the resulting document's encoding may not be recognized by some parsers and text editors, if they do not implement sophisticated encoding detection. Enabling this flag adds an encoding-specific BOM to the output. This flag has no effect in `xml_node::print` functions: they never output the BOM. This flag is *off* by default.
|
||||
|
||||
* [[format_save_file_text]]`format_save_file_text` changes the file mode when using `save_file` function. By default, file is opened in binary mode, which means that the output file will
|
||||
contain platform-independent newline `\n` (ASCII 10). If this flag is on, file is opened in text mode, which on some systems changes the newline format (i.e. on Windows you can use this flag to output XML documents with `\r\n` (ASCII 13 10) newlines. This flag is *off* by default.
|
||||
contain platform-independent newline `\n` (ASCII 10). If this flag is on, file is opened in text mode, which on some systems changes the newline format (i.e. on Windows you can use this flag to output XML documents with `\r\n` (ASCII 13 10) newlines). This flag is *off* by default.
|
||||
|
||||
Additionally, there is one predefined option mask:
|
||||
|
||||
@@ -1765,7 +1830,7 @@ include::samples/save_declaration.cpp[tags=code]
|
||||
[[xpath]]
|
||||
== XPath
|
||||
|
||||
If the task at hand is to select a subset of document nodes that match some criteria, it is possible to code a function using the existing traversal functionality for any practical criteria. However, often either a data-driven approach is desirable, in case the criteria are not predefined and come from a file, or it is inconvenient to use traversal interfaces and a higher-level DSL is required. There is a standard language for XML processing, XPath, that can be useful for these cases. pugixml implements an almost complete subset of XPath 1.0. Because of differences in document object model and some performance implications, there are minor violations of the official specifications, which can be found in <<xpath.w3c>>. The rest of this section describes the interface for XPath functionality. Please note that if you wish to learn to use XPath language, you have to look for other tutorials or manuals; for example, you can read http://www.w3schools.com/xpath/[W3Schools XPath tutorial], http://www.tizag.com/xmlTutorial/xpathtutorial.php[XPath tutorial at tizag.com], and http://www.w3.org/TR/xpath/[the XPath 1.0 specification].
|
||||
If the task at hand is to select a subset of document nodes that match some criteria, it is possible to code a function using the existing traversal functionality for any practical criteria. However, often either a data-driven approach is desirable, in case the criteria are not predefined and come from a file, or it is inconvenient to use traversal interfaces and a higher-level DSL is required. There is a standard language for XML processing, XPath, that can be useful for these cases. pugixml implements an almost complete subset of XPath 1.0. Because of differences in document object model and some performance implications, there are minor violations of the official specifications, which can be found in <<xpath.w3c>>. The rest of this section describes the interface for XPath functionality. Please note that if you wish to learn to use XPath language, you have to look for other tutorials or manuals; for example, you can read https://www.w3schools.com/xml/xpath_intro.asp[W3Schools XPath tutorial] or https://www.w3.org/TR/xpath-10/[the XPath 1.0 specification].
|
||||
|
||||
[[xpath.types]]
|
||||
=== XPath types
|
||||
@@ -1976,7 +2041,7 @@ xpath_node_set xml_node::select_nodes(const char_t* query, xpath_variable_set* v
|
||||
|
||||
If you're using query objects, you can change the variable values before `evaluate`/`select` calls to change the query behavior.
|
||||
|
||||
NOTE: The variable set pointer is stored in the query object; you have to ensure that the lifetime of the set exceeds that of query object.
|
||||
NOTE: The variable set pointer is stored in the query object, along with pointers to the variables it references; you have to ensure that the lifetime of the set exceeds that of the query object, and that the set is not assigned to or moved into while the query is live.
|
||||
|
||||
[[xpath_variable_set]]
|
||||
Variable sets correspond to `xpath_variable_set` type, which is essentially a variable container.
|
||||
@@ -2070,11 +2135,11 @@ include::samples/xpath_variables.cpp[tags=code]
|
||||
There are two different mechanisms for error handling in XPath implementation; the mechanism used depends on whether exception support is disabled (this is controlled with <<PUGIXML_NO_EXCEPTIONS,PUGIXML_NO_EXCEPTIONS>> define).
|
||||
|
||||
[[xpath_exception]][[xpath_exception::result]][[xpath_exception::what]]
|
||||
By default, XPath functions throw `xpath_exception` object in case of errors; additionally, in the event any memory allocation fails, an `std::bad_alloc` exception is thrown. Also `xpath_exception` is thrown if the query is evaluated to a node set, but the return type is not node set. If the query constructor succeeds (i.e. no exception is thrown), the query object is valid. Otherwise you can get the error details via one of the following functions:
|
||||
By default, XPath functions throw `xpath_exception` object in case of errors; additionally, in the event any memory allocation fails, an `std::bad_alloc` exception is thrown. Also `xpath_exception` is thrown if the query is evaluated as a node set, but the return type is not node set. If the query constructor succeeds (i.e. no exception is thrown), the query object is valid. Otherwise you can get the error details via one of the following functions:
|
||||
|
||||
[source]
|
||||
----
|
||||
virtual const char* xpath_exception::what() const throw();
|
||||
virtual const char* xpath_exception::what() const noexcept;
|
||||
const xpath_parse_result& xpath_exception::result() const;
|
||||
----
|
||||
|
||||
@@ -2138,6 +2203,96 @@ Because of the differences in document object models, performance considerations
|
||||
|
||||
:!numbered:
|
||||
|
||||
[[v1.16]]
|
||||
=== v1.16 ^2026-06-16^
|
||||
|
||||
Anniversary release (pugixml turns 20 this year!). Changes:
|
||||
|
||||
* Behavior changes:
|
||||
. Elements that have a single empty PCDATA child are now printed as empty element tags (unless `format_no_empty_element_tags` is used)
|
||||
|
||||
* Improvements:
|
||||
. `PUGIXML_CHARCONV_FLOAT` option can be enabled to switch floating point conversions to `<charconv>`; this requires C{plus}{plus}17, makes the conversions locale-independent and can improve performance
|
||||
. Add `xml_node::ensure_child` and `xml_node::ensure_attribute` that return the child/attribute with the specified name, adding one if it does not exist
|
||||
. Improve performance of searching for nodes and attributes by name
|
||||
. Loading a document from an empty buffer no longer performs memory allocations
|
||||
|
||||
* XPath improvements:
|
||||
. Improve performance of queries that evaluate or compare attribute values, like `@attr > 5`
|
||||
. Improve performance of queries that select nodes and attributes by name
|
||||
|
||||
* Bug fixes:
|
||||
. Fix stack overflow when removing subtrees with extremely deep nesting
|
||||
. Fix integer overflows that could lead to crashes when loading very large (1+ GB) documents on 32-bit platforms in `PUGIXML_WCHAR_MODE`
|
||||
. Fix null pointer dereference when copying `xpath_variable_set` objects that contain string variables with unassigned values
|
||||
|
||||
* CMake improvements:
|
||||
. Apple frameworks built with `PUGIXML_BUILD_APPLE_FRAMEWORK` now include framework headers
|
||||
. `PUGIXML_INSTALL_SOURCE` option can be used to install `pugixml.cpp` (useful for header-only mode)
|
||||
|
||||
* Compatibility improvements:
|
||||
. Add project files and NuGet packages for Visual Studio 2026
|
||||
. Fix compatibility with C{plus}{plus}20 modules when including `pugixml.hpp` in the global module fragment
|
||||
. Fix clang/gcc warnings `-Wextra-semi-stmt`, `-Wsign-conversion`, `-Wuninitialized` (GCC16)
|
||||
. Fix compilation for Embarcadero C{plus}{plus} XE5
|
||||
. Work around several static analysis false positives
|
||||
|
||||
[[v1.15]]
|
||||
=== v1.15 ^2025-01-10^
|
||||
|
||||
Maintenance release. Changes:
|
||||
|
||||
* Improvements:
|
||||
. Many `xml_attribute::` and `xml_node::` functions now transparently support `std::string_view` and `std::string` when C++17 support is detected.
|
||||
|
||||
* CMake improvements:
|
||||
. Improve `pkg-config` file generation for NixOS
|
||||
. `PUGIXML_BUILD_APPLE_FRAMEWORK` CMake option can be used to build pugixml as `.xcframework`
|
||||
. `PUGIXML_INSTALL` CMake option can be used to disable installation targets
|
||||
|
||||
* Compatibility improvements:
|
||||
. Fix clang/gcc warnings `-Wzero-as-null-pointer-constant`, `-Wuseless-cast`, `-Wshorten-64-to-32`
|
||||
. Fix unreferenced function warnings in `PUGIXML_NO_STL` configuration
|
||||
. Fix CMake 3.31 deprecation warnings
|
||||
. Stop using deprecated `throw()` when `noexcept` is available
|
||||
|
||||
[[v1.14]]
|
||||
=== v1.14 ^2023-10-01^
|
||||
|
||||
Maintenance release. Changes:
|
||||
|
||||
* Improvements:
|
||||
. `xml_attribute::set_name` and `xml_node::set_name` now have overloads that accept pointer to non-null-terminated string and size
|
||||
. Implement `parse_merge_pcdata` parsing mode in which PCDATA contents is merged into a single node when original document had comments that were skipped during parsing
|
||||
. `xml_document::load_file` now returns a more consistent error status when given a path to a folder
|
||||
|
||||
* Bug fixes:
|
||||
. Fix assertion in XPath number->string conversion when using non-English locales
|
||||
. Fix PUGIXML_STATIC_CRT CMake option to correctly select static CRT when using MSVC and recent CMake
|
||||
|
||||
* Compatibility improvements:
|
||||
. Fix GCC 2.95/3.3 builds
|
||||
. Fix CMake 3.27 deprecation warnings
|
||||
. Fix XCode 14 sprintf deprecation warning when compiling in C++03 mode
|
||||
. Fix clang/gcc warnings `-Wweak-vtables`, `-Wreserved-macro-identifier`
|
||||
|
||||
[[v1.13]]
|
||||
=== v1.13 ^2022-11-01^
|
||||
|
||||
Maintenance release. Changes:
|
||||
|
||||
* Improvements:
|
||||
. `xml_attribute::set_value`, `xml_node::set_value` and `xml_text::set` now have overloads that accept pointer to non-null-terminated string and size
|
||||
. Improve performance of tree traversal when using compact mode (`PUGIXML_COMPACT`)
|
||||
|
||||
* Bug fixes:
|
||||
. Fix error handling in `xml_document::save_file` that could result in the function succeeding while running out of disk space
|
||||
. Fix memory leak during error handling of some out-of-memory conditions during `xml_document::load`
|
||||
|
||||
* Compatibility improvements:
|
||||
. Fix exported symbols in CMake DLL builds when using CMake
|
||||
. Fix exported symbols in CMake shared object builds when using -fvisibility=hidden
|
||||
|
||||
[[v1.12]]
|
||||
=== v1.12 ^2022-02-09^
|
||||
|
||||
@@ -2655,6 +2810,7 @@ This is the reference for all macros, types, enumerations, classes and functions
|
||||
#define +++<a href="#PUGIXML_MEMORY_XPATH_PAGE_SIZE">PUGIXML_MEMORY_XPATH_PAGE_SIZE</a>+++
|
||||
#define +++<a href="#PUGIXML_HEADER_ONLY">PUGIXML_HEADER_ONLY</a>+++
|
||||
#define +++<a href="#PUGIXML_HAS_LONG_LONG">PUGIXML_HAS_LONG_LONG</a>+++
|
||||
#define +++<a href="#PUGIXML_HAS_STRING_VIEW">PUGIXML_HAS_STRING_VIEW</a>+++
|
||||
----
|
||||
|
||||
[[apiref.types]]
|
||||
@@ -2664,6 +2820,7 @@ This is the reference for all macros, types, enumerations, classes and functions
|
||||
----
|
||||
typedef configuration-defined-type +++<a href="#char_t">char_t</a>+++;
|
||||
typedef configuration-defined-type +++<a href="#string_t">string_t</a>+++;
|
||||
typedef configuration-defined-type +++<a href="#string_view_t">string_view_t</a>+++;
|
||||
typedef void* (*+++<a href="#allocation_function">allocation_function</a>+++)(size_t size);
|
||||
typedef void (*+++<a href="#deallocation_function">deallocation_function</a>+++)(void* ptr);
|
||||
----
|
||||
@@ -2757,6 +2914,7 @@ const unsigned int +++<a href="#parse_trim_pcdata">parse_trim_pcdata</a>+++
|
||||
const unsigned int +++<a href="#parse_ws_pcdata">parse_ws_pcdata</a>+++
|
||||
const unsigned int +++<a href="#parse_ws_pcdata_single">parse_ws_pcdata_single</a>+++
|
||||
const unsigned int +++<a href="#parse_embed_pcdata">parse_embed_pcdata</a>+++
|
||||
const unsigned int +++<a href="#parse_merge_pcdata">parse_merge_pcdata</a>+++
|
||||
const unsigned int +++<a href="#parse_wconv_attribute">parse_wconv_attribute</a>+++
|
||||
const unsigned int +++<a href="#parse_wnorm_attribute">parse_wnorm_attribute</a>+++
|
||||
----
|
||||
@@ -2797,18 +2955,25 @@ const unsigned int +++<a href="#parse_wnorm_attribute">parse_wnorm_attribute</a>
|
||||
unsigned long long +++<a href="#xml_attribute::as_ullong">as_ullong</a>+++(unsigned long long def = 0) const;
|
||||
|
||||
bool +++<a href="#xml_attribute::set_name">set_name</a>+++(const char_t* rhs);
|
||||
bool +++<a href="#xml_attribute::set_name">set_name</a>+++(const char_t* rhs, size_t size);
|
||||
bool +++<a href="#xml_attribute::set_name">set_name</a>+++(string_view_t rhs);
|
||||
bool +++<a href="#xml_attribute::set_value">set_value</a>+++(const char_t* rhs);
|
||||
bool +++<a href="#xml_attribute::set_value">set_value</a>+++(const char_t* rhs, size_t size);
|
||||
bool +++<a href="#xml_attribute::set_value">set_value</a>+++(string_view_t rhs);
|
||||
bool +++<a href="#xml_attribute::set_value">set_value</a>+++(int rhs);
|
||||
bool +++<a href="#xml_attribute::set_value">set_value</a>+++(unsigned int rhs);
|
||||
bool +++<a href="#xml_attribute::set_value">set_value</a>+++(long rhs);
|
||||
bool +++<a href="#xml_attribute::set_value">set_value</a>+++(unsigned long rhs);
|
||||
bool +++<a href="#xml_attribute::set_value">set_value</a>+++(double rhs);
|
||||
bool +++<a href="#xml_attribute::set_value">set_value</a>+++(double rhs, int precision);
|
||||
bool +++<a href="#xml_attribute::set_value">set_value</a>+++(float rhs);
|
||||
bool +++<a href="#xml_attribute::set_value">set_value</a>+++(float rhs, int precision);
|
||||
bool +++<a href="#xml_attribute::set_value">set_value</a>+++(bool rhs);
|
||||
bool +++<a href="#xml_attribute::set_value">set_value</a>+++(long long rhs);
|
||||
bool +++<a href="#xml_attribute::set_value">set_value</a>+++(unsigned long long rhs);
|
||||
|
||||
xml_attribute& +++<a href="#xml_attribute::assign">operator=</a>+++(const char_t* rhs);
|
||||
xml_attribute& +++<a href="#xml_attribute::assign">operator=</a>+++(string_view_t rhs);
|
||||
xml_attribute& +++<a href="#xml_attribute::assign">operator=</a>+++(int rhs);
|
||||
xml_attribute& +++<a href="#xml_attribute::assign">operator=</a>+++(unsigned int rhs);
|
||||
xml_attribute& +++<a href="#xml_attribute::assign">operator=</a>+++(long rhs);
|
||||
@@ -2817,7 +2982,7 @@ const unsigned int +++<a href="#parse_wnorm_attribute">parse_wnorm_attribute</a>
|
||||
xml_attribute& +++<a href="#xml_attribute::assign">operator=</a>+++(float rhs);
|
||||
xml_attribute& +++<a href="#xml_attribute::assign">operator=</a>+++(bool rhs);
|
||||
xml_attribute& +++<a href="#xml_attribute::assign">operator=</a>+++(long long rhs);
|
||||
xml_attribute& +++<a href="#xml_attribute::assign">operator=</a>+++(unsnigned long long rhs);
|
||||
xml_attribute& +++<a href="#xml_attribute::assign">operator=</a>+++(unsigned long long rhs);
|
||||
|
||||
+++<span class="tok-k">class</span> <a href="#xml_node">xml_node</a>+++
|
||||
+++<a href="#xml_node::ctor">xml_node</a>+++();
|
||||
@@ -2853,9 +3018,17 @@ const unsigned int +++<a href="#parse_wnorm_attribute">parse_wnorm_attribute</a>
|
||||
implementation-defined-type +++<a href="#xml_node::attributes">attributes</a>+++() const;
|
||||
|
||||
xml_node +++<a href="#xml_node::child">child</a>+++(const char_t* name) const;
|
||||
xml_node +++<a href="#xml_node::child">child</a>+++(string_view_t name) const;
|
||||
xml_attribute +++<a href="#xml_node::attribute">attribute</a>+++(const char_t* name) const;
|
||||
xml_attribute +++<a href="#xml_node::attribute">attribute</a>+++(string_view_t name) const;
|
||||
xml_node +++<a href="#xml_node::next_sibling_name">next_sibling</a>+++(const char_t* name) const;
|
||||
xml_node +++<a href="#xml_node::next_sibling_name">next_sibling</a>+++(string_view_t name) const;
|
||||
xml_node +++<a href="#xml_node::previous_sibling_name">previous_sibling</a>+++(const char_t* name) const;
|
||||
xml_node +++<a href="#xml_node::previous_sibling_name">previous_sibling</a>+++(string_view_t name) const;
|
||||
|
||||
xml_attribute +++<a href="#xml_node::attribute_hinted">attribute</a>+++(const char_t* name, xml_attribute& hint) const;
|
||||
xml_attribute +++<a href="#xml_node::attribute_hinted">attribute</a>+++(string_view_t name, xml_attribute& hint) const;
|
||||
|
||||
xml_node +++<a href="#xml_node::find_child_by_attribute">find_child_by_attribute</a>+++(const char_t* name, const char_t* attr_name, const char_t* attr_value) const;
|
||||
xml_node +++<a href="#xml_node::find_child_by_attribute">find_child_by_attribute</a>+++(const char_t* attr_name, const char_t* attr_value) const;
|
||||
|
||||
@@ -2878,17 +3051,25 @@ const unsigned int +++<a href="#parse_wnorm_attribute">parse_wnorm_attribute</a>
|
||||
template <typename Predicate> xml_node +++<a href="#xml_node::find_node">find_node</a>+++(Predicate pred) const;
|
||||
|
||||
string_t +++<a href="#xml_node::path">path</a>+++(char_t delimiter = '/') const;
|
||||
xml_node +++<a href="#xml_node::first_element_by_path">xml_node::first_element_by_path</a>+++(const char_t* path, char_t delimiter = '/') const;
|
||||
xml_node +++<a href="#xml_node::first_element_by_path">first_element_by_path</a>+++(const char_t* path, char_t delimiter = '/') const;
|
||||
xml_node +++<a href="#xml_node::root">root</a>+++() const;
|
||||
ptrdiff_t +++<a href="#xml_node::offset_debug">offset_debug</a>+++() const;
|
||||
|
||||
bool +++<a href="#xml_node::set_name">set_name</a>+++(const char_t* rhs);
|
||||
bool +++<a href="#xml_node::set_name">set_name</a>+++(const char_t* rhs, size_t size);
|
||||
bool +++<a href="#xml_node::set_name">set_name</a>+++(string_view_t rhs);
|
||||
bool +++<a href="#xml_node::set_value">set_value</a>+++(const char_t* rhs);
|
||||
bool +++<a href="#xml_node::set_value">set_value</a>+++(const char_t* rhs, size_t size);
|
||||
bool +++<a href="#xml_node::set_value">set_value</a>+++(string_view_t rhs);
|
||||
|
||||
xml_attribute +++<a href="#xml_node::append_attribute">append_attribute</a>+++(const char_t* name);
|
||||
xml_attribute +++<a href="#xml_node::append_attribute">append_attribute</a>+++(string_view_t name);
|
||||
xml_attribute +++<a href="#xml_node::prepend_attribute">prepend_attribute</a>+++(const char_t* name);
|
||||
xml_attribute +++<a href="#xml_node::prepend_attribute">prepend_attribute</a>+++(string_view_t name);
|
||||
xml_attribute +++<a href="#xml_node::insert_attribute_after">insert_attribute_after</a>+++(const char_t* name, const xml_attribute& attr);
|
||||
xml_attribute +++<a href="#xml_node::insert_attribute_after">insert_attribute_after</a>+++(string_view_t name, const xml_attribute& attr);
|
||||
xml_attribute +++<a href="#xml_node::insert_attribute_before">insert_attribute_before</a>+++(const char_t* name, const xml_attribute& attr);
|
||||
xml_attribute +++<a href="#xml_node::insert_attribute_before">insert_attribute_before</a>+++(string_view_t name, const xml_attribute& attr);
|
||||
|
||||
xml_node +++<a href="#xml_node::append_child">append_child</a>+++(xml_node_type type = node_element);
|
||||
xml_node +++<a href="#xml_node::prepend_child">prepend_child</a>+++(xml_node_type type = node_element);
|
||||
@@ -2896,9 +3077,18 @@ const unsigned int +++<a href="#parse_wnorm_attribute">parse_wnorm_attribute</a>
|
||||
xml_node +++<a href="#xml_node::insert_child_before">insert_child_before</a>+++(xml_node_type type, const xml_node& node);
|
||||
|
||||
xml_node +++<a href="#xml_node::append_child">append_child</a>+++(const char_t* name);
|
||||
xml_node +++<a href="#xml_node::append_child">append_child</a>+++(string_view_t name);
|
||||
xml_node +++<a href="#xml_node::prepend_child">prepend_child</a>+++(const char_t* name);
|
||||
xml_node +++<a href="#xml_node::prepend_child">prepend_child</a>+++(string_view_t name);
|
||||
xml_node +++<a href="#xml_node::insert_child_after">insert_child_after</a>+++(const char_t* name, const xml_node& node);
|
||||
xml_node +++<a href="#xml_node::insert_child_after">insert_child_after</a>+++(string_view_t name, const xml_node& node);
|
||||
xml_node +++<a href="#xml_node::insert_child_before">insert_child_before</a>+++(const char_t* name, const xml_node& node);
|
||||
xml_node +++<a href="#xml_node::insert_child_before">insert_child_before</a>+++(string_view_t name, const xml_node& node);
|
||||
|
||||
xml_attribute +++<a href="#xml_node::ensure_attribute">ensure_attribute</a>+++(const char_t* name);
|
||||
xml_attribute +++<a href="#xml_node::ensure_attribute">ensure_attribute</a>+++(string_view_t name);
|
||||
xml_node +++<a href="#xml_node::ensure_child">ensure_child</a>+++(const char_t* name);
|
||||
xml_node +++<a href="#xml_node::ensure_child">ensure_child</a>+++(string_view_t name);
|
||||
|
||||
xml_attribute +++<a href="#xml_node::append_copy">append_copy</a>+++(const xml_attribute& proto);
|
||||
xml_attribute +++<a href="#xml_node::prepend_copy">prepend_copy</a>+++(const xml_attribute& proto);
|
||||
@@ -2917,9 +3107,11 @@ const unsigned int +++<a href="#parse_wnorm_attribute">parse_wnorm_attribute</a>
|
||||
|
||||
bool +++<a href="#xml_node::remove_attribute">remove_attribute</a>+++(const xml_attribute& a);
|
||||
bool +++<a href="#xml_node::remove_attribute">remove_attribute</a>+++(const char_t* name);
|
||||
bool +++<a href="#xml_node::remove_attribute">remove_attribute</a>+++(string_view_t name);
|
||||
bool +++<a href="#xml_node::remove_attributes">remove_attributes</a>+++();
|
||||
bool +++<a href="#xml_node::remove_child">remove_child</a>+++(const xml_node& n);
|
||||
bool +++<a href="#xml_node::remove_child">remove_child</a>+++(const char_t* name);
|
||||
bool +++<a href="#xml_node::remove_child">remove_child</a>+++(string_view_t name);
|
||||
bool +++<a href="#xml_node::remove_children">remove_children</a>+++();
|
||||
|
||||
xml_parse_result +++<a href="#xml_node::append_buffer">append_buffer</a>+++(const void* contents, size_t size, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
|
||||
@@ -2982,9 +3174,9 @@ const unsigned int +++<a href="#parse_wnorm_attribute">parse_wnorm_attribute</a>
|
||||
|
||||
+++<span class="tok-k">class</span> <a href="#xml_text">xml_text</a>+++
|
||||
bool +++<a href="#xml_text::empty">empty</a>+++() const;
|
||||
operator +++<a href="#xml_text::unspecified_bool_type">xml_text::unspecified_bool_type</a>+++() const;
|
||||
operator +++<a href="#xml_text::unspecified_bool_type">unspecified_bool_type</a>+++() const;
|
||||
|
||||
const char_t* +++<a href="#xml_text::get">xml_text::get</a>+++() const;
|
||||
const char_t* +++<a href="#xml_text::get">get</a>+++() const;
|
||||
|
||||
const char_t* +++<a href="#xml_text::as_string">as_string</a>+++(const char_t* def = "") const;
|
||||
int +++<a href="#xml_text::as_int">as_int</a>+++(int def = 0) const;
|
||||
@@ -2996,18 +3188,23 @@ const unsigned int +++<a href="#parse_wnorm_attribute">parse_wnorm_attribute</a>
|
||||
unsigned long long +++<a href="#xml_text::as_ullong">as_ullong</a>+++(unsigned long long def = 0) const;
|
||||
|
||||
bool +++<a href="#xml_text::set">set</a>+++(const char_t* rhs);
|
||||
bool +++<a href="#xml_text::set">set</a>+++(const char_t* rhs, size_t size);
|
||||
bool +++<a href="#xml_text::set">set</a>+++(string_view_t rhs);
|
||||
|
||||
bool +++<a href="#xml_text::set">set</a>+++(int rhs);
|
||||
bool +++<a href="#xml_text::set">set</a>+++(unsigned int rhs);
|
||||
bool +++<a href="#xml_text::set">set</a>+++(long rhs);
|
||||
bool +++<a href="#xml_text::set">set</a>+++(unsigned long rhs);
|
||||
bool +++<a href="#xml_text::set">set</a>+++(double rhs);
|
||||
bool +++<a href="#xml_text::set">set</a>+++(float rhs);
|
||||
bool +++<a href="#xml_text::set">set</a>+++(bool rhs);
|
||||
bool +++<a href="#xml_text::set">set</a>+++(long long rhs);
|
||||
bool +++<a href="#xml_text::set">set</a>+++(unsigned long long rhs);
|
||||
bool +++<a href="#xml_text::set_value">set</a>+++(int rhs);
|
||||
bool +++<a href="#xml_text::set_value">set</a>+++(unsigned int rhs);
|
||||
bool +++<a href="#xml_text::set_value">set</a>+++(long rhs);
|
||||
bool +++<a href="#xml_text::set_value">set</a>+++(unsigned long rhs);
|
||||
bool +++<a href="#xml_text::set_value">set</a>+++(double rhs);
|
||||
bool +++<a href="#xml_text::set_value">set</a>+++(double rhs, int precision);
|
||||
bool +++<a href="#xml_text::set_value">set</a>+++(float rhs);
|
||||
bool +++<a href="#xml_text::set_value">set</a>+++(float rhs, int precision);
|
||||
bool +++<a href="#xml_text::set_value">set</a>+++(bool rhs);
|
||||
bool +++<a href="#xml_text::set_value">set</a>+++(long long rhs);
|
||||
bool +++<a href="#xml_text::set_value">set</a>+++(unsigned long long rhs);
|
||||
|
||||
xml_text& +++<a href="#xml_text::assign">operator=</a>+++(const char_t* rhs);
|
||||
xml_text& +++<a href="#xml_text::assign">operator=</a>+++(string_view_t rhs);
|
||||
xml_text& +++<a href="#xml_text::assign">operator=</a>+++(int rhs);
|
||||
xml_text& +++<a href="#xml_text::assign">operator=</a>+++(unsigned int rhs);
|
||||
xml_text& +++<a href="#xml_text::assign">operator=</a>+++(long rhs);
|
||||
@@ -3053,7 +3250,7 @@ const unsigned int +++<a href="#parse_wnorm_attribute">parse_wnorm_attribute</a>
|
||||
operator +++<a href="#xpath_query::unspecified_bool_type">unspecified_bool_type</a>+++() const;
|
||||
|
||||
+++<span class="tok-k">class</span> <a href="#xpath_exception">xpath_exception</a>+++: public std::exception
|
||||
virtual const char* +++<a href="#xpath_exception::what">what</a>+++() const throw();
|
||||
virtual const char* +++<a href="#xpath_exception::what">what</a>+++() const noexcept;
|
||||
|
||||
const xpath_parse_result& +++<a href="#xpath_exception::result">result</a>+++() const;
|
||||
|
||||
|
||||
+1498
-1115
File diff suppressed because it is too large
Load Diff
@@ -83,7 +83,7 @@ include::samples/load_error_handling.cpp[tags=code]
|
||||
|
||||
Sometimes XML data should be loaded from some other source than file, i.e. HTTP URL; also you may want to load XML data from file using non-standard functions, i.e. to use your virtual file system facilities or to load XML from gzip-compressed files. These scenarios either require loading document from memory, in which case you should prepare a contiguous memory block with all XML data and to pass it to one of buffer loading functions, or loading document from C{plus}{plus} IOstream, in which case you should provide an object which implements `std::istream` or `std::wistream` interface.
|
||||
|
||||
There are different functions for loading document from memory; they treat the passed buffer as either an immutable one (`load_buffer`), a mutable buffer which is owned by the caller (`load_buffer_inplace`), or a mutable buffer which ownership belongs to pugixml (`load_buffer_inplace_own`). There is also a simple helper function, `xml_document::load`, for cases when you want to load the XML document from null-terminated character string.
|
||||
There are different functions for loading document from memory; they treat the passed buffer as either an immutable one (`load_buffer`), a mutable buffer which is owned by the caller (`load_buffer_inplace`), or a mutable buffer which ownership belongs to pugixml (`load_buffer_inplace_own`). There is also a simple helper function, `xml_document::load_string`, for cases when you want to load the XML document from null-terminated character string.
|
||||
|
||||
This is an example of loading XML document from memory using one of these functions (link:samples/load_memory.cpp[]); read the sample code for more examples:
|
||||
|
||||
@@ -139,7 +139,7 @@ Here is an example of using iterators for document traversal (link:samples/trave
|
||||
include::samples/traverse_iter.cpp[tags=code]
|
||||
----
|
||||
|
||||
If your C{plus}{plus} compiler supports range-based for-loop (this is a C{plus}{plus}11 feature, at the time of writing it's supported by Microsoft Visual Studio 11 Beta, GCC 4.6 and Clang 3.0), you can use it to enumerate nodes/attributes. Additional helpers are provided to support this; note that they are also compatible with http://www.boost.org/libs/foreach/[Boost Foreach], and possibly other pre-C{plus}{plus}11 foreach facilities.
|
||||
If your C{plus}{plus} compiler supports range-based for-loop (this is a C{plus}{plus}11 feature, supported by Microsoft Visual Studio 2012+, GCC 4.6+ and Clang 3.0+), you can use it to enumerate nodes/attributes. Additional helpers are provided to support this; note that they are also compatible with http://www.boost.org/libs/foreach/[Boost Foreach], and possibly other pre-C{plus}{plus}11 foreach facilities.
|
||||
|
||||
Here is an example of using C{plus}{plus}11 range-based for loop for document traversal (link:samples/traverse_rangefor.cpp[]):
|
||||
|
||||
@@ -231,7 +231,7 @@ This is a simple example of saving XML document to standard output (link:samples
|
||||
include::samples/save_stream.cpp[tags=code]
|
||||
----
|
||||
|
||||
All of the above saving functions are implemented in terms of writer interface. This is a simple interface with a single function, which is called several times during output process with chunks of document data as input. In order to output the document via some custom transport, for example sockets, you should create an object which implements `xml_writer_file` interface and pass it to `xml_document::save` function.
|
||||
All of the above saving functions are implemented in terms of writer interface. This is a simple interface with a single function, which is called several times during output process with chunks of document data as input. In order to output the document via some custom transport, for example sockets, you should create an object which implements `xml_writer` interface and pass it to `xml_document::save` function.
|
||||
|
||||
This is a simple example of custom writer for saving document data to STL string (link:samples/save_custom_writer.cpp[]); read the sample code for more complex examples:
|
||||
|
||||
@@ -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-2022 Arseny Kapoulkine
|
||||
Copyright (c) 2006-2026 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-2022 Arseny Kapoulkine.
|
||||
pugixml is Copyright (C) 2006-2026 Arseny Kapoulkine.
|
||||
....
|
||||
|
||||
+170
-171
@@ -4,9 +4,9 @@
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="generator" content="Asciidoctor 2.0.17">
|
||||
<meta name="generator" content="Asciidoctor 2.0.26">
|
||||
<meta name="author" content="website, repository">
|
||||
<title>pugixml 1.12 quick start guide</title>
|
||||
<title>pugixml 1.16 quick start guide</title>
|
||||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic%7CNoto+Serif:400,400italic,700,700italic%7CDroid+Sans+Mono:400,700">
|
||||
<style>
|
||||
/*! Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */
|
||||
@@ -85,10 +85,10 @@ code{font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;font-weight:400;
|
||||
ul,ol,dl{line-height:1.6;margin-bottom:1.25em;list-style-position:outside;font-family:inherit}
|
||||
ul,ol{margin-left:1.5em}
|
||||
ul li ul,ul li ol{margin-left:1.25em;margin-bottom:0}
|
||||
ul.square li ul,ul.circle li ul,ul.disc li ul{list-style:inherit}
|
||||
ul.square{list-style-type:square}
|
||||
ul.circle{list-style-type:circle}
|
||||
ul.disc{list-style-type:disc}
|
||||
ul.square{list-style-type:square}
|
||||
ul.circle ul:not([class]),ul.disc ul:not([class]),ul.square ul:not([class]){list-style:inherit}
|
||||
ol li ul,ol li ol{margin-left:1.25em;margin-bottom:0}
|
||||
dl dt{margin-bottom:.3125em;font-weight:bold}
|
||||
dl dd{margin-bottom:1.25em}
|
||||
@@ -117,7 +117,6 @@ h1 strong,h2 strong,h3 strong,#toctitle strong,.sidebarblock>.content>.title str
|
||||
:not(pre):not([class^=L])>code{font-size:.9375em;font-style:normal!important;letter-spacing:0;padding:.1em .5ex;word-spacing:-.15em;background:#f7f7f8;border-radius:4px;line-height:1.45;text-rendering:optimizeSpeed}
|
||||
pre{color:rgba(0,0,0,.9);font-family:"Droid Sans Mono","DejaVu Sans Mono",monospace;line-height:1.45;text-rendering:optimizeSpeed}
|
||||
pre code,pre pre{color:inherit;font-size:inherit;line-height:inherit}
|
||||
pre>code{display:block}
|
||||
pre.nowrap,pre.nowrap pre{white-space:pre;word-wrap:normal}
|
||||
em em{font-style:normal}
|
||||
strong strong{font-weight:400}
|
||||
@@ -141,7 +140,7 @@ p a>code:hover{color:rgba(0,0,0,.9)}
|
||||
#content::before{content:none}
|
||||
#header>h1:first-child{color:rgba(0,0,0,.85);margin-top:2.25rem;margin-bottom:0}
|
||||
#header>h1:first-child+#toc{margin-top:8px;border-top:1px solid #dddddf}
|
||||
#header>h1:only-child,body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
|
||||
#header>h1:only-child{border-bottom:1px solid #dddddf;padding-bottom:8px}
|
||||
#header .details{border-bottom:1px solid #dddddf;line-height:1.45;padding-top:.25em;padding-bottom:.25em;padding-left:.25em;color:rgba(0,0,0,.6);display:flex;flex-flow:row wrap}
|
||||
#header .details span:first-child{margin-left:-.125em}
|
||||
#header .details span.email a{color:rgba(0,0,0,.85)}
|
||||
@@ -163,6 +162,7 @@ p a>code:hover{color:rgba(0,0,0,.9)}
|
||||
#toctitle{color:#7a2518;font-size:1.2em}
|
||||
@media screen and (min-width:768px){#toctitle{font-size:1.375em}
|
||||
body.toc2{padding-left:15em;padding-right:0}
|
||||
body.toc2 #header>h1:nth-last-child(2){border-bottom:1px solid #dddddf;padding-bottom:8px}
|
||||
#toc.toc2{margin-top:0!important;background:#f8f8f7;position:fixed;width:15em;left:0;top:0;border-right:1px solid #e7e7e9;border-top-width:0!important;border-bottom-width:0!important;z-index:1000;padding:1.25em 1em;height:100%;overflow:auto}
|
||||
#toc.toc2 #toctitle{margin-top:0;margin-bottom:.8rem;font-size:1.2em}
|
||||
#toc.toc2>ul{font-size:.9em;margin-bottom:0}
|
||||
@@ -209,19 +209,17 @@ table.tableblock.fit-content>caption.title{white-space:nowrap;width:0}
|
||||
.admonitionblock>table td.content{padding-left:1.125em;padding-right:1.25em;border-left:1px solid #dddddf;color:rgba(0,0,0,.6);word-wrap:anywhere}
|
||||
.admonitionblock>table td.content>:last-child>:last-child{margin-bottom:0}
|
||||
.exampleblock>.content{border:1px solid #e6e6e6;margin-bottom:1.25em;padding:1.25em;background:#fff;border-radius:4px}
|
||||
.exampleblock>.content>:first-child{margin-top:0}
|
||||
.exampleblock>.content>:last-child{margin-bottom:0}
|
||||
.sidebarblock{border:1px solid #dbdbd6;margin-bottom:1.25em;padding:1.25em;background:#f3f3f2;border-radius:4px}
|
||||
.sidebarblock>:first-child{margin-top:0}
|
||||
.sidebarblock>:last-child{margin-bottom:0}
|
||||
.sidebarblock>.content>.title{color:#7a2518;margin-top:0;text-align:center}
|
||||
.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
|
||||
.exampleblock>.content>:first-child,.sidebarblock>.content>:first-child{margin-top:0}
|
||||
.exampleblock>.content>:last-child,.exampleblock>.content>:last-child>:last-child,.exampleblock>.content .olist>ol>li:last-child>:last-child,.exampleblock>.content .ulist>ul>li:last-child>:last-child,.exampleblock>.content .qlist>ol>li:last-child>:last-child,.sidebarblock>.content>:last-child,.sidebarblock>.content>:last-child>:last-child,.sidebarblock>.content .olist>ol>li:last-child>:last-child,.sidebarblock>.content .ulist>ul>li:last-child>:last-child,.sidebarblock>.content .qlist>ol>li:last-child>:last-child{margin-bottom:0}
|
||||
.literalblock pre,.listingblock>.content>pre{border-radius:4px;overflow-x:auto;padding:1em;font-size:.8125em}
|
||||
@media screen and (min-width:768px){.literalblock pre,.listingblock>.content>pre{font-size:.90625em}}
|
||||
@media screen and (min-width:1280px){.literalblock pre,.listingblock>.content>pre{font-size:1em}}
|
||||
.literalblock pre,.listingblock>.content>pre:not(.highlight),.listingblock>.content>pre[class=highlight],.listingblock>.content>pre[class^="highlight "]{background:#f7f7f8}
|
||||
.literalblock.output pre{color:#f7f7f8;background:rgba(0,0,0,.9)}
|
||||
.listingblock>.content{position:relative}
|
||||
.listingblock pre>code{display:block}
|
||||
.listingblock code[data-lang]::before{display:none;content:attr(data-lang);position:absolute;font-size:.75em;top:.425rem;right:.5rem;line-height:1;text-transform:uppercase;color:inherit;opacity:.5}
|
||||
.listingblock:hover code[data-lang]::before{display:block}
|
||||
.listingblock.terminal pre .command::before{content:attr(data-prompt);padding-right:.5em;color:inherit;opacity:.5}
|
||||
@@ -331,7 +329,7 @@ a.image{text-decoration:none;display:inline-block}
|
||||
a.image object{pointer-events:none}
|
||||
sup.footnote,sup.footnoteref{font-size:.875em;position:static;vertical-align:super}
|
||||
sup.footnote a,sup.footnoteref a{text-decoration:none}
|
||||
sup.footnote a:active,sup.footnoteref a:active{text-decoration:underline}
|
||||
sup.footnote a:active,sup.footnoteref a:active,#footnotes .footnote a:first-of-type:active{text-decoration:underline}
|
||||
#footnotes{padding-top:.75em;padding-bottom:.75em;margin-bottom:.625em}
|
||||
#footnotes hr{width:20%;min-width:6.25em;margin:-.25em 0 .75em;border-width:1px 0 0}
|
||||
#footnotes .footnote{padding:0 .375em 0 .225em;line-height:1.3334;font-size:.875em;margin-left:1.2em;margin-bottom:.2em}
|
||||
@@ -394,7 +392,7 @@ b.conum *{color:inherit!important}
|
||||
dt,th.tableblock,td.content,div.footnote{text-rendering:optimizeLegibility}
|
||||
h1,h2,p,td.content,span.alt,summary{letter-spacing:-.01em}
|
||||
p strong,td.content strong,div.footnote strong{letter-spacing:-.005em}
|
||||
p,blockquote,dt,td.content,span.alt,summary{font-size:1.0625rem}
|
||||
p,blockquote,dt,td.content,td.hdlist1,span.alt,summary{font-size:1.0625rem}
|
||||
p{margin-bottom:1.25rem}
|
||||
.sidebarblock p,.sidebarblock dt,.sidebarblock td.content,p.tableblock{font-size:1em}
|
||||
.exampleblock>.content{background:#fffef7;border-color:#e0e0dc;box-shadow:0 1px 4px #e0e0dc}
|
||||
@@ -439,78 +437,79 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
|
||||
<style>
|
||||
pre.pygments .hll { background-color: #ffffcc }
|
||||
pre.pygments { background: #f8f8f8; }
|
||||
pre.pygments .tok-c { color: #408080; font-style: italic } /* Comment */
|
||||
pre.pygments .tok-err { border: 1px solid #FF0000 } /* Error */
|
||||
pre.pygments .tok-c { color: #3D7B7B; font-style: italic } /* Comment */
|
||||
pre.pygments .tok-err { border: 1px solid #F00 } /* Error */
|
||||
pre.pygments .tok-k { color: #008000; font-weight: bold } /* Keyword */
|
||||
pre.pygments .tok-o { color: #666666 } /* Operator */
|
||||
pre.pygments .tok-ch { color: #408080; font-style: italic } /* Comment.Hashbang */
|
||||
pre.pygments .tok-cm { color: #408080; font-style: italic } /* Comment.Multiline */
|
||||
pre.pygments .tok-cp { color: #BC7A00 } /* Comment.Preproc */
|
||||
pre.pygments .tok-cpf { color: #408080; font-style: italic } /* Comment.PreprocFile */
|
||||
pre.pygments .tok-c1 { color: #408080; font-style: italic } /* Comment.Single */
|
||||
pre.pygments .tok-cs { color: #408080; font-style: italic } /* Comment.Special */
|
||||
pre.pygments .tok-o { color: #666 } /* Operator */
|
||||
pre.pygments .tok-ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */
|
||||
pre.pygments .tok-cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */
|
||||
pre.pygments .tok-cp { color: #9C6500 } /* Comment.Preproc */
|
||||
pre.pygments .tok-cpf { color: #3D7B7B; font-style: italic } /* Comment.PreprocFile */
|
||||
pre.pygments .tok-c1 { color: #3D7B7B; font-style: italic } /* Comment.Single */
|
||||
pre.pygments .tok-cs { color: #3D7B7B; font-style: italic } /* Comment.Special */
|
||||
pre.pygments .tok-gd { color: #A00000 } /* Generic.Deleted */
|
||||
pre.pygments .tok-ge { font-style: italic } /* Generic.Emph */
|
||||
pre.pygments .tok-gr { color: #FF0000 } /* Generic.Error */
|
||||
pre.pygments .tok-ges { font-weight: bold; font-style: italic } /* Generic.EmphStrong */
|
||||
pre.pygments .tok-gr { color: #E40000 } /* Generic.Error */
|
||||
pre.pygments .tok-gh { color: #000080; font-weight: bold } /* Generic.Heading */
|
||||
pre.pygments .tok-gi { color: #00A000 } /* Generic.Inserted */
|
||||
pre.pygments .tok-go { color: #888888 } /* Generic.Output */
|
||||
pre.pygments .tok-gi { color: #008400 } /* Generic.Inserted */
|
||||
pre.pygments .tok-go { color: #717171 } /* Generic.Output */
|
||||
pre.pygments .tok-gp { color: #000080; font-weight: bold } /* Generic.Prompt */
|
||||
pre.pygments .tok-gs { font-weight: bold } /* Generic.Strong */
|
||||
pre.pygments .tok-gu { color: #800080; font-weight: bold } /* Generic.Subheading */
|
||||
pre.pygments .tok-gt { color: #0044DD } /* Generic.Traceback */
|
||||
pre.pygments .tok-gt { color: #04D } /* Generic.Traceback */
|
||||
pre.pygments .tok-kc { color: #008000; font-weight: bold } /* Keyword.Constant */
|
||||
pre.pygments .tok-kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
|
||||
pre.pygments .tok-kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
|
||||
pre.pygments .tok-kp { color: #008000 } /* Keyword.Pseudo */
|
||||
pre.pygments .tok-kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
|
||||
pre.pygments .tok-kt { color: #B00040 } /* Keyword.Type */
|
||||
pre.pygments .tok-m { color: #666666 } /* Literal.Number */
|
||||
pre.pygments .tok-m { color: #666 } /* Literal.Number */
|
||||
pre.pygments .tok-s { color: #BA2121 } /* Literal.String */
|
||||
pre.pygments .tok-na { color: #7D9029 } /* Name.Attribute */
|
||||
pre.pygments .tok-na { color: #687822 } /* Name.Attribute */
|
||||
pre.pygments .tok-nb { color: #008000 } /* Name.Builtin */
|
||||
pre.pygments .tok-nc { color: #0000FF; font-weight: bold } /* Name.Class */
|
||||
pre.pygments .tok-no { color: #880000 } /* Name.Constant */
|
||||
pre.pygments .tok-nd { color: #AA22FF } /* Name.Decorator */
|
||||
pre.pygments .tok-ni { color: #999999; font-weight: bold } /* Name.Entity */
|
||||
pre.pygments .tok-ne { color: #D2413A; font-weight: bold } /* Name.Exception */
|
||||
pre.pygments .tok-nf { color: #0000FF } /* Name.Function */
|
||||
pre.pygments .tok-nl { color: #A0A000 } /* Name.Label */
|
||||
pre.pygments .tok-nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
|
||||
pre.pygments .tok-nc { color: #00F; font-weight: bold } /* Name.Class */
|
||||
pre.pygments .tok-no { color: #800 } /* Name.Constant */
|
||||
pre.pygments .tok-nd { color: #A2F } /* Name.Decorator */
|
||||
pre.pygments .tok-ni { color: #717171; font-weight: bold } /* Name.Entity */
|
||||
pre.pygments .tok-ne { color: #CB3F38; font-weight: bold } /* Name.Exception */
|
||||
pre.pygments .tok-nf { color: #00F } /* Name.Function */
|
||||
pre.pygments .tok-nl { color: #767600 } /* Name.Label */
|
||||
pre.pygments .tok-nn { color: #00F; font-weight: bold } /* Name.Namespace */
|
||||
pre.pygments .tok-nt { color: #008000; font-weight: bold } /* Name.Tag */
|
||||
pre.pygments .tok-nv { color: #19177C } /* Name.Variable */
|
||||
pre.pygments .tok-ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
|
||||
pre.pygments .tok-w { color: #bbbbbb } /* Text.Whitespace */
|
||||
pre.pygments .tok-mb { color: #666666 } /* Literal.Number.Bin */
|
||||
pre.pygments .tok-mf { color: #666666 } /* Literal.Number.Float */
|
||||
pre.pygments .tok-mh { color: #666666 } /* Literal.Number.Hex */
|
||||
pre.pygments .tok-mi { color: #666666 } /* Literal.Number.Integer */
|
||||
pre.pygments .tok-mo { color: #666666 } /* Literal.Number.Oct */
|
||||
pre.pygments .tok-ow { color: #A2F; font-weight: bold } /* Operator.Word */
|
||||
pre.pygments .tok-w { color: #BBB } /* Text.Whitespace */
|
||||
pre.pygments .tok-mb { color: #666 } /* Literal.Number.Bin */
|
||||
pre.pygments .tok-mf { color: #666 } /* Literal.Number.Float */
|
||||
pre.pygments .tok-mh { color: #666 } /* Literal.Number.Hex */
|
||||
pre.pygments .tok-mi { color: #666 } /* Literal.Number.Integer */
|
||||
pre.pygments .tok-mo { color: #666 } /* Literal.Number.Oct */
|
||||
pre.pygments .tok-sa { color: #BA2121 } /* Literal.String.Affix */
|
||||
pre.pygments .tok-sb { color: #BA2121 } /* Literal.String.Backtick */
|
||||
pre.pygments .tok-sc { color: #BA2121 } /* Literal.String.Char */
|
||||
pre.pygments .tok-dl { color: #BA2121 } /* Literal.String.Delimiter */
|
||||
pre.pygments .tok-sd { color: #BA2121; font-style: italic } /* Literal.String.Doc */
|
||||
pre.pygments .tok-s2 { color: #BA2121 } /* Literal.String.Double */
|
||||
pre.pygments .tok-se { color: #BB6622; font-weight: bold } /* Literal.String.Escape */
|
||||
pre.pygments .tok-se { color: #AA5D1F; font-weight: bold } /* Literal.String.Escape */
|
||||
pre.pygments .tok-sh { color: #BA2121 } /* Literal.String.Heredoc */
|
||||
pre.pygments .tok-si { color: #BB6688; font-weight: bold } /* Literal.String.Interpol */
|
||||
pre.pygments .tok-si { color: #A45A77; font-weight: bold } /* Literal.String.Interpol */
|
||||
pre.pygments .tok-sx { color: #008000 } /* Literal.String.Other */
|
||||
pre.pygments .tok-sr { color: #BB6688 } /* Literal.String.Regex */
|
||||
pre.pygments .tok-sr { color: #A45A77 } /* Literal.String.Regex */
|
||||
pre.pygments .tok-s1 { color: #BA2121 } /* Literal.String.Single */
|
||||
pre.pygments .tok-ss { color: #19177C } /* Literal.String.Symbol */
|
||||
pre.pygments .tok-bp { color: #008000 } /* Name.Builtin.Pseudo */
|
||||
pre.pygments .tok-fm { color: #0000FF } /* Name.Function.Magic */
|
||||
pre.pygments .tok-fm { color: #00F } /* Name.Function.Magic */
|
||||
pre.pygments .tok-vc { color: #19177C } /* Name.Variable.Class */
|
||||
pre.pygments .tok-vg { color: #19177C } /* Name.Variable.Global */
|
||||
pre.pygments .tok-vi { color: #19177C } /* Name.Variable.Instance */
|
||||
pre.pygments .tok-vm { color: #19177C } /* Name.Variable.Magic */
|
||||
pre.pygments .tok-il { color: #666666 } /* Literal.Number.Integer.Long */
|
||||
pre.pygments .tok-il { color: #666 } /* Literal.Number.Integer.Long */
|
||||
</style>
|
||||
</head>
|
||||
<body class="article toc2 toc-right">
|
||||
<div id="header">
|
||||
<h1>pugixml 1.12 quick start guide</h1>
|
||||
<h1>pugixml 1.16 quick start guide</h1>
|
||||
<div class="details">
|
||||
<span id="author" class="author">website</span><br>
|
||||
<span id="email" class="email"><a href="https://pugixml.org" class="bare">https://pugixml.org</a></span><br>
|
||||
@@ -566,9 +565,9 @@ No documentation is perfect; neither is this one. If you find errors or omission
|
||||
<p>You can download the latest source distribution as an archive:</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p><a href="https://github.com/zeux/pugixml/releases/download/v1.12/pugixml-1.12.zip">pugixml-1.12.zip</a> (Windows line endings)
|
||||
<p><a href="https://github.com/zeux/pugixml/releases/download/v1.16/pugixml-1.16.zip">pugixml-1.16.zip</a> (Windows line endings)
|
||||
/
|
||||
<a href="https://github.com/zeux/pugixml/releases/download/v1.12/pugixml-1.12.tar.gz">pugixml-1.12.tar.gz</a> (Unix line endings)</p>
|
||||
<a href="https://github.com/zeux/pugixml/releases/download/v1.16/pugixml-1.16.tar.gz">pugixml-1.16.tar.gz</a> (Unix line endings)</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>The distribution contains library source, documentation (the guide you’re reading now and the manual) and some code examples. After downloading the distribution, install pugixml by extracting all files from the compressed archive.</p>
|
||||
@@ -652,11 +651,11 @@ All pugixml classes and functions are located in <code>pugi</code> namespace; yo
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_document</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">;</span><span class="tok-w"></span>
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_document</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">;</span>
|
||||
|
||||
<span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_parse_result</span><span class="tok-w"> </span><span class="tok-n">result</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">load_file</span><span class="tok-p">(</span><span class="tok-s">"tree.xml"</span><span class="tok-p">);</span><span class="tok-w"></span>
|
||||
<span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_parse_result</span><span class="tok-w"> </span><span class="tok-n">result</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">load_file</span><span class="tok-p">(</span><span class="tok-s">"tree.xml"</span><span class="tok-p">);</span>
|
||||
|
||||
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"Load result: "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">result</span><span class="tok-p">.</span><span class="tok-n">description</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">", mesh name: "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">child</span><span class="tok-p">(</span><span class="tok-s">"mesh"</span><span class="tok-p">).</span><span class="tok-n">attribute</span><span class="tok-p">(</span><span class="tok-s">"name"</span><span class="tok-p">).</span><span class="tok-n">value</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">endl</span><span class="tok-p">;</span><span class="tok-w"></span></code></pre>
|
||||
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"Load result: "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">result</span><span class="tok-p">.</span><span class="tok-n">description</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">", mesh name: "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">child</span><span class="tok-p">(</span><span class="tok-s">"mesh"</span><span class="tok-p">).</span><span class="tok-n">attribute</span><span class="tok-p">(</span><span class="tok-s">"name"</span><span class="tok-p">).</span><span class="tok-n">value</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">endl</span><span class="tok-p">;</span></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
@@ -670,47 +669,47 @@ All pugixml classes and functions are located in <code>pugi</code> namespace; yo
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_document</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">;</span><span class="tok-w"></span>
|
||||
<span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_parse_result</span><span class="tok-w"> </span><span class="tok-n">result</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">load_string</span><span class="tok-p">(</span><span class="tok-n">source</span><span class="tok-p">);</span><span class="tok-w"></span>
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_document</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">;</span>
|
||||
<span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_parse_result</span><span class="tok-w"> </span><span class="tok-n">result</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">load_string</span><span class="tok-p">(</span><span class="tok-n">source</span><span class="tok-p">);</span>
|
||||
|
||||
<span class="tok-k">if</span><span class="tok-w"> </span><span class="tok-p">(</span><span class="tok-n">result</span><span class="tok-p">)</span><span class="tok-w"></span>
|
||||
<span class="tok-p">{</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"XML ["</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">source</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"] parsed without errors, attr value: ["</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">child</span><span class="tok-p">(</span><span class="tok-s">"node"</span><span class="tok-p">).</span><span class="tok-n">attribute</span><span class="tok-p">(</span><span class="tok-s">"attr"</span><span class="tok-p">).</span><span class="tok-n">value</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"]</span><span class="tok-se">\n\n</span><span class="tok-s">"</span><span class="tok-p">;</span><span class="tok-w"></span>
|
||||
<span class="tok-p">}</span><span class="tok-w"></span>
|
||||
<span class="tok-k">else</span><span class="tok-w"></span>
|
||||
<span class="tok-p">{</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"XML ["</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">source</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"] parsed with errors, attr value: ["</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">child</span><span class="tok-p">(</span><span class="tok-s">"node"</span><span class="tok-p">).</span><span class="tok-n">attribute</span><span class="tok-p">(</span><span class="tok-s">"attr"</span><span class="tok-p">).</span><span class="tok-n">value</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"]</span><span class="tok-se">\n</span><span class="tok-s">"</span><span class="tok-p">;</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"Error description: "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">result</span><span class="tok-p">.</span><span class="tok-n">description</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"</span><span class="tok-se">\n</span><span class="tok-s">"</span><span class="tok-p">;</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"Error offset: "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">result</span><span class="tok-p">.</span><span class="tok-n">offset</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">" (error at [..."</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-p">(</span><span class="tok-n">source</span><span class="tok-w"> </span><span class="tok-o">+</span><span class="tok-w"> </span><span class="tok-n">result</span><span class="tok-p">.</span><span class="tok-n">offset</span><span class="tok-p">)</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"]</span><span class="tok-se">\n\n</span><span class="tok-s">"</span><span class="tok-p">;</span><span class="tok-w"></span>
|
||||
<span class="tok-p">}</span><span class="tok-w"></span></code></pre>
|
||||
<span class="tok-k">if</span><span class="tok-w"> </span><span class="tok-p">(</span><span class="tok-n">result</span><span class="tok-p">)</span>
|
||||
<span class="tok-p">{</span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"XML ["</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">source</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"] parsed without errors, attr value: ["</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">child</span><span class="tok-p">(</span><span class="tok-s">"node"</span><span class="tok-p">).</span><span class="tok-n">attribute</span><span class="tok-p">(</span><span class="tok-s">"attr"</span><span class="tok-p">).</span><span class="tok-n">value</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"]</span><span class="tok-se">\n\n</span><span class="tok-s">"</span><span class="tok-p">;</span>
|
||||
<span class="tok-p">}</span>
|
||||
<span class="tok-k">else</span>
|
||||
<span class="tok-p">{</span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"XML ["</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">source</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"] parsed with errors, attr value: ["</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">child</span><span class="tok-p">(</span><span class="tok-s">"node"</span><span class="tok-p">).</span><span class="tok-n">attribute</span><span class="tok-p">(</span><span class="tok-s">"attr"</span><span class="tok-p">).</span><span class="tok-n">value</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"]</span><span class="tok-se">\n</span><span class="tok-s">"</span><span class="tok-p">;</span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"Error description: "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">result</span><span class="tok-p">.</span><span class="tok-n">description</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"</span><span class="tok-se">\n</span><span class="tok-s">"</span><span class="tok-p">;</span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"Error offset: "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">result</span><span class="tok-p">.</span><span class="tok-n">offset</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">" (error at [..."</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-p">(</span><span class="tok-n">source</span><span class="tok-w"> </span><span class="tok-o">+</span><span class="tok-w"> </span><span class="tok-n">result</span><span class="tok-p">.</span><span class="tok-n">offset</span><span class="tok-p">)</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"]</span><span class="tok-se">\n\n</span><span class="tok-s">"</span><span class="tok-p">;</span>
|
||||
<span class="tok-p">}</span></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Sometimes XML data should be loaded from some other source than file, i.e. HTTP URL; also you may want to load XML data from file using non-standard functions, i.e. to use your virtual file system facilities or to load XML from gzip-compressed files. These scenarios either require loading document from memory, in which case you should prepare a contiguous memory block with all XML data and to pass it to one of buffer loading functions, or loading document from C++ IOstream, in which case you should provide an object which implements <code>std::istream</code> or <code>std::wistream</code> interface.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>There are different functions for loading document from memory; they treat the passed buffer as either an immutable one (<code>load_buffer</code>), a mutable buffer which is owned by the caller (<code>load_buffer_inplace</code>), or a mutable buffer which ownership belongs to pugixml (<code>load_buffer_inplace_own</code>). There is also a simple helper function, <code>xml_document::load</code>, for cases when you want to load the XML document from null-terminated character string.</p>
|
||||
<p>There are different functions for loading document from memory; they treat the passed buffer as either an immutable one (<code>load_buffer</code>), a mutable buffer which is owned by the caller (<code>load_buffer_inplace</code>), or a mutable buffer which ownership belongs to pugixml (<code>load_buffer_inplace_own</code>). There is also a simple helper function, <code>xml_document::load_string</code>, for cases when you want to load the XML document from null-terminated character string.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>This is an example of loading XML document from memory using one of these functions (<a href="samples/load_memory.cpp" class="bare">samples/load_memory.cpp</a>); read the sample code for more examples:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">const</span><span class="tok-w"> </span><span class="tok-kt">char</span><span class="tok-w"> </span><span class="tok-n">source</span><span class="tok-p">[]</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-s">"<mesh name='sphere'><bounds>0 0 1 1</bounds></mesh>"</span><span class="tok-p">;</span><span class="tok-w"></span>
|
||||
<span class="tok-kt">size_t</span><span class="tok-w"> </span><span class="tok-n">size</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-k">sizeof</span><span class="tok-p">(</span><span class="tok-n">source</span><span class="tok-p">);</span><span class="tok-w"></span></code></pre>
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">const</span><span class="tok-w"> </span><span class="tok-kt">char</span><span class="tok-w"> </span><span class="tok-n">source</span><span class="tok-p">[]</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-s">"<mesh name='sphere'><bounds>0 0 1 1</bounds></mesh>"</span><span class="tok-p">;</span>
|
||||
<span class="tok-kt">size_t</span><span class="tok-w"> </span><span class="tok-n">size</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-k">sizeof</span><span class="tok-p">(</span><span class="tok-n">source</span><span class="tok-p">);</span></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-c1">// You can use load_buffer_inplace to load document from mutable memory block; the block's lifetime must exceed that of document</span>
|
||||
<span class="tok-kt">char</span><span class="tok-o">*</span><span class="tok-w"> </span><span class="tok-n">buffer</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-k">new</span><span class="tok-w"> </span><span class="tok-kt">char</span><span class="tok-p">[</span><span class="tok-n">size</span><span class="tok-p">];</span><span class="tok-w"></span>
|
||||
<span class="tok-n">memcpy</span><span class="tok-p">(</span><span class="tok-n">buffer</span><span class="tok-p">,</span><span class="tok-w"> </span><span class="tok-n">source</span><span class="tok-p">,</span><span class="tok-w"> </span><span class="tok-n">size</span><span class="tok-p">);</span><span class="tok-w"></span>
|
||||
<span class="tok-kt">char</span><span class="tok-o">*</span><span class="tok-w"> </span><span class="tok-n">buffer</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-k">new</span><span class="tok-w"> </span><span class="tok-kt">char</span><span class="tok-p">[</span><span class="tok-n">size</span><span class="tok-p">];</span>
|
||||
<span class="tok-n">memcpy</span><span class="tok-p">(</span><span class="tok-n">buffer</span><span class="tok-p">,</span><span class="tok-w"> </span><span class="tok-n">source</span><span class="tok-p">,</span><span class="tok-w"> </span><span class="tok-n">size</span><span class="tok-p">);</span>
|
||||
|
||||
<span class="tok-c1">// The block can be allocated by any method; the block is modified during parsing</span>
|
||||
<span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_parse_result</span><span class="tok-w"> </span><span class="tok-n">result</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">load_buffer_inplace</span><span class="tok-p">(</span><span class="tok-n">buffer</span><span class="tok-p">,</span><span class="tok-w"> </span><span class="tok-n">size</span><span class="tok-p">);</span><span class="tok-w"></span>
|
||||
<span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_parse_result</span><span class="tok-w"> </span><span class="tok-n">result</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">load_buffer_inplace</span><span class="tok-p">(</span><span class="tok-n">buffer</span><span class="tok-p">,</span><span class="tok-w"> </span><span class="tok-n">size</span><span class="tok-p">);</span>
|
||||
|
||||
<span class="tok-c1">// You have to destroy the block yourself after the document is no longer used</span>
|
||||
<span class="tok-k">delete</span><span class="tok-p">[]</span><span class="tok-w"> </span><span class="tok-n">buffer</span><span class="tok-p">;</span><span class="tok-w"></span></code></pre>
|
||||
<span class="tok-k">delete</span><span class="tok-p">[]</span><span class="tok-w"> </span><span class="tok-n">buffer</span><span class="tok-p">;</span></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
@@ -718,8 +717,8 @@ All pugixml classes and functions are located in <code>pugi</code> namespace; yo
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">ifstream</span><span class="tok-w"> </span><span class="tok-nf">stream</span><span class="tok-p">(</span><span class="tok-s">"weekly-utf-8.xml"</span><span class="tok-p">);</span><span class="tok-w"></span>
|
||||
<span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_parse_result</span><span class="tok-w"> </span><span class="tok-n">result</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">load</span><span class="tok-p">(</span><span class="tok-n">stream</span><span class="tok-p">);</span><span class="tok-w"></span></code></pre>
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">ifstream</span><span class="tok-w"> </span><span class="tok-n">stream</span><span class="tok-p">(</span><span class="tok-s">"weekly-utf-8.xml"</span><span class="tok-p">);</span>
|
||||
<span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_parse_result</span><span class="tok-w"> </span><span class="tok-n">result</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">load</span><span class="tok-p">(</span><span class="tok-n">stream</span><span class="tok-p">);</span></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -748,13 +747,13 @@ All pugixml classes and functions are located in <code>pugi</code> namespace; yo
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">for</span><span class="tok-w"> </span><span class="tok-p">(</span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_node</span><span class="tok-w"> </span><span class="tok-n">tool</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">tools</span><span class="tok-p">.</span><span class="tok-n">child</span><span class="tok-p">(</span><span class="tok-s">"Tool"</span><span class="tok-p">);</span><span class="tok-w"> </span><span class="tok-n">tool</span><span class="tok-p">;</span><span class="tok-w"> </span><span class="tok-n">tool</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">tool</span><span class="tok-p">.</span><span class="tok-n">next_sibling</span><span class="tok-p">(</span><span class="tok-s">"Tool"</span><span class="tok-p">))</span><span class="tok-w"></span>
|
||||
<span class="tok-p">{</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"Tool "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">tool</span><span class="tok-p">.</span><span class="tok-n">attribute</span><span class="tok-p">(</span><span class="tok-s">"Filename"</span><span class="tok-p">).</span><span class="tok-n">value</span><span class="tok-p">();</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">": AllowRemote "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">tool</span><span class="tok-p">.</span><span class="tok-n">attribute</span><span class="tok-p">(</span><span class="tok-s">"AllowRemote"</span><span class="tok-p">).</span><span class="tok-n">as_bool</span><span class="tok-p">();</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">", Timeout "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">tool</span><span class="tok-p">.</span><span class="tok-n">attribute</span><span class="tok-p">(</span><span class="tok-s">"Timeout"</span><span class="tok-p">).</span><span class="tok-n">as_int</span><span class="tok-p">();</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">", Description '"</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">tool</span><span class="tok-p">.</span><span class="tok-n">child_value</span><span class="tok-p">(</span><span class="tok-s">"Description"</span><span class="tok-p">)</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"'</span><span class="tok-se">\n</span><span class="tok-s">"</span><span class="tok-p">;</span><span class="tok-w"></span>
|
||||
<span class="tok-p">}</span><span class="tok-w"></span></code></pre>
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">for</span><span class="tok-w"> </span><span class="tok-p">(</span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_node</span><span class="tok-w"> </span><span class="tok-n">tool</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">tools</span><span class="tok-p">.</span><span class="tok-n">child</span><span class="tok-p">(</span><span class="tok-s">"Tool"</span><span class="tok-p">);</span><span class="tok-w"> </span><span class="tok-n">tool</span><span class="tok-p">;</span><span class="tok-w"> </span><span class="tok-n">tool</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">tool</span><span class="tok-p">.</span><span class="tok-n">next_sibling</span><span class="tok-p">(</span><span class="tok-s">"Tool"</span><span class="tok-p">))</span>
|
||||
<span class="tok-p">{</span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"Tool "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">tool</span><span class="tok-p">.</span><span class="tok-n">attribute</span><span class="tok-p">(</span><span class="tok-s">"Filename"</span><span class="tok-p">).</span><span class="tok-n">value</span><span class="tok-p">();</span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">": AllowRemote "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">tool</span><span class="tok-p">.</span><span class="tok-n">attribute</span><span class="tok-p">(</span><span class="tok-s">"AllowRemote"</span><span class="tok-p">).</span><span class="tok-n">as_bool</span><span class="tok-p">();</span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">", Timeout "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">tool</span><span class="tok-p">.</span><span class="tok-n">attribute</span><span class="tok-p">(</span><span class="tok-s">"Timeout"</span><span class="tok-p">).</span><span class="tok-n">as_int</span><span class="tok-p">();</span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">", Description '"</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">tool</span><span class="tok-p">.</span><span class="tok-n">child_value</span><span class="tok-p">(</span><span class="tok-s">"Description"</span><span class="tok-p">)</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"'</span><span class="tok-se">\n</span><span class="tok-s">"</span><span class="tok-p">;</span>
|
||||
<span class="tok-p">}</span></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
@@ -762,12 +761,12 @@ All pugixml classes and functions are located in <code>pugi</code> namespace; yo
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"Tool for *.dae generation: "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">tools</span><span class="tok-p">.</span><span class="tok-n">find_child_by_attribute</span><span class="tok-p">(</span><span class="tok-s">"Tool"</span><span class="tok-p">,</span><span class="tok-w"> </span><span class="tok-s">"OutputFileMasks"</span><span class="tok-p">,</span><span class="tok-w"> </span><span class="tok-s">"*.dae"</span><span class="tok-p">).</span><span class="tok-n">attribute</span><span class="tok-p">(</span><span class="tok-s">"Filename"</span><span class="tok-p">).</span><span class="tok-n">value</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"</span><span class="tok-se">\n</span><span class="tok-s">"</span><span class="tok-p">;</span><span class="tok-w"></span>
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"Tool for *.dae generation: "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">tools</span><span class="tok-p">.</span><span class="tok-n">find_child_by_attribute</span><span class="tok-p">(</span><span class="tok-s">"Tool"</span><span class="tok-p">,</span><span class="tok-w"> </span><span class="tok-s">"OutputFileMasks"</span><span class="tok-p">,</span><span class="tok-w"> </span><span class="tok-s">"*.dae"</span><span class="tok-p">).</span><span class="tok-n">attribute</span><span class="tok-p">(</span><span class="tok-s">"Filename"</span><span class="tok-p">).</span><span class="tok-n">value</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"</span><span class="tok-se">\n</span><span class="tok-s">"</span><span class="tok-p">;</span>
|
||||
|
||||
<span class="tok-k">for</span><span class="tok-w"> </span><span class="tok-p">(</span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_node</span><span class="tok-w"> </span><span class="tok-n">tool</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">tools</span><span class="tok-p">.</span><span class="tok-n">child</span><span class="tok-p">(</span><span class="tok-s">"Tool"</span><span class="tok-p">);</span><span class="tok-w"> </span><span class="tok-n">tool</span><span class="tok-p">;</span><span class="tok-w"> </span><span class="tok-n">tool</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">tool</span><span class="tok-p">.</span><span class="tok-n">next_sibling</span><span class="tok-p">(</span><span class="tok-s">"Tool"</span><span class="tok-p">))</span><span class="tok-w"></span>
|
||||
<span class="tok-p">{</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"Tool "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">tool</span><span class="tok-p">.</span><span class="tok-n">attribute</span><span class="tok-p">(</span><span class="tok-s">"Filename"</span><span class="tok-p">).</span><span class="tok-n">value</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"</span><span class="tok-se">\n</span><span class="tok-s">"</span><span class="tok-p">;</span><span class="tok-w"></span>
|
||||
<span class="tok-p">}</span><span class="tok-w"></span></code></pre>
|
||||
<span class="tok-k">for</span><span class="tok-w"> </span><span class="tok-p">(</span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_node</span><span class="tok-w"> </span><span class="tok-n">tool</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">tools</span><span class="tok-p">.</span><span class="tok-n">child</span><span class="tok-p">(</span><span class="tok-s">"Tool"</span><span class="tok-p">);</span><span class="tok-w"> </span><span class="tok-n">tool</span><span class="tok-p">;</span><span class="tok-w"> </span><span class="tok-n">tool</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">tool</span><span class="tok-p">.</span><span class="tok-n">next_sibling</span><span class="tok-p">(</span><span class="tok-s">"Tool"</span><span class="tok-p">))</span>
|
||||
<span class="tok-p">{</span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"Tool "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">tool</span><span class="tok-p">.</span><span class="tok-n">attribute</span><span class="tok-p">(</span><span class="tok-s">"Filename"</span><span class="tok-p">).</span><span class="tok-n">value</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"</span><span class="tok-se">\n</span><span class="tok-s">"</span><span class="tok-p">;</span>
|
||||
<span class="tok-p">}</span></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
@@ -778,43 +777,43 @@ All pugixml classes and functions are located in <code>pugi</code> namespace; yo
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">for</span><span class="tok-w"> </span><span class="tok-p">(</span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_node_iterator</span><span class="tok-w"> </span><span class="tok-n">it</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">tools</span><span class="tok-p">.</span><span class="tok-n">begin</span><span class="tok-p">();</span><span class="tok-w"> </span><span class="tok-n">it</span><span class="tok-w"> </span><span class="tok-o">!=</span><span class="tok-w"> </span><span class="tok-n">tools</span><span class="tok-p">.</span><span class="tok-n">end</span><span class="tok-p">();</span><span class="tok-w"> </span><span class="tok-o">++</span><span class="tok-n">it</span><span class="tok-p">)</span><span class="tok-w"></span>
|
||||
<span class="tok-p">{</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"Tool:"</span><span class="tok-p">;</span><span class="tok-w"></span>
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">for</span><span class="tok-w"> </span><span class="tok-p">(</span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_node_iterator</span><span class="tok-w"> </span><span class="tok-n">it</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">tools</span><span class="tok-p">.</span><span class="tok-n">begin</span><span class="tok-p">();</span><span class="tok-w"> </span><span class="tok-n">it</span><span class="tok-w"> </span><span class="tok-o">!=</span><span class="tok-w"> </span><span class="tok-n">tools</span><span class="tok-p">.</span><span class="tok-n">end</span><span class="tok-p">();</span><span class="tok-w"> </span><span class="tok-o">++</span><span class="tok-n">it</span><span class="tok-p">)</span>
|
||||
<span class="tok-p">{</span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"Tool:"</span><span class="tok-p">;</span>
|
||||
|
||||
<span class="tok-w"> </span><span class="tok-k">for</span><span class="tok-w"> </span><span class="tok-p">(</span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_attribute_iterator</span><span class="tok-w"> </span><span class="tok-n">ait</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">it</span><span class="tok-o">-></span><span class="tok-n">attributes_begin</span><span class="tok-p">();</span><span class="tok-w"> </span><span class="tok-n">ait</span><span class="tok-w"> </span><span class="tok-o">!=</span><span class="tok-w"> </span><span class="tok-n">it</span><span class="tok-o">-></span><span class="tok-n">attributes_end</span><span class="tok-p">();</span><span class="tok-w"> </span><span class="tok-o">++</span><span class="tok-n">ait</span><span class="tok-p">)</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-p">{</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">" "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">ait</span><span class="tok-o">-></span><span class="tok-n">name</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"="</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">ait</span><span class="tok-o">-></span><span class="tok-n">value</span><span class="tok-p">();</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-p">}</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-k">for</span><span class="tok-w"> </span><span class="tok-p">(</span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_attribute_iterator</span><span class="tok-w"> </span><span class="tok-n">ait</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">it</span><span class="tok-o">-></span><span class="tok-n">attributes_begin</span><span class="tok-p">();</span><span class="tok-w"> </span><span class="tok-n">ait</span><span class="tok-w"> </span><span class="tok-o">!=</span><span class="tok-w"> </span><span class="tok-n">it</span><span class="tok-o">-></span><span class="tok-n">attributes_end</span><span class="tok-p">();</span><span class="tok-w"> </span><span class="tok-o">++</span><span class="tok-n">ait</span><span class="tok-p">)</span>
|
||||
<span class="tok-w"> </span><span class="tok-p">{</span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">" "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">ait</span><span class="tok-o">-></span><span class="tok-n">name</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"="</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">ait</span><span class="tok-o">-></span><span class="tok-n">value</span><span class="tok-p">();</span>
|
||||
<span class="tok-w"> </span><span class="tok-p">}</span>
|
||||
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">endl</span><span class="tok-p">;</span><span class="tok-w"></span>
|
||||
<span class="tok-p">}</span><span class="tok-w"></span></code></pre>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">endl</span><span class="tok-p">;</span>
|
||||
<span class="tok-p">}</span></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>If your C++ compiler supports range-based for-loop (this is a C++11 feature, at the time of writing it’s supported by Microsoft Visual Studio 11 Beta, GCC 4.6 and Clang 3.0), you can use it to enumerate nodes/attributes. Additional helpers are provided to support this; note that they are also compatible with <a href="http://www.boost.org/libs/foreach/">Boost Foreach</a>, and possibly other pre-C++11 foreach facilities.</p>
|
||||
<p>If your C++ compiler supports range-based for-loop (this is a C++11 feature, supported by Microsoft Visual Studio 2012+, GCC 4.6+ and Clang 3.0+), you can use it to enumerate nodes/attributes. Additional helpers are provided to support this; note that they are also compatible with <a href="http://www.boost.org/libs/foreach/">Boost Foreach</a>, and possibly other pre-C++11 foreach facilities.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>Here is an example of using C++11 range-based for loop for document traversal (<a href="samples/traverse_rangefor.cpp" class="bare">samples/traverse_rangefor.cpp</a>):</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">for</span><span class="tok-w"> </span><span class="tok-p">(</span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_node</span><span class="tok-w"> </span><span class="tok-nl">tool</span><span class="tok-p">:</span><span class="tok-w"> </span><span class="tok-n">tools</span><span class="tok-p">.</span><span class="tok-n">children</span><span class="tok-p">(</span><span class="tok-s">"Tool"</span><span class="tok-p">))</span><span class="tok-w"></span>
|
||||
<span class="tok-p">{</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"Tool:"</span><span class="tok-p">;</span><span class="tok-w"></span>
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">for</span><span class="tok-w"> </span><span class="tok-p">(</span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_node</span><span class="tok-w"> </span><span class="tok-n">tool</span><span class="tok-o">:</span><span class="tok-w"> </span><span class="tok-n">tools</span><span class="tok-p">.</span><span class="tok-n">children</span><span class="tok-p">(</span><span class="tok-s">"Tool"</span><span class="tok-p">))</span>
|
||||
<span class="tok-p">{</span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"Tool:"</span><span class="tok-p">;</span>
|
||||
|
||||
<span class="tok-w"> </span><span class="tok-k">for</span><span class="tok-w"> </span><span class="tok-p">(</span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_attribute</span><span class="tok-w"> </span><span class="tok-nl">attr</span><span class="tok-p">:</span><span class="tok-w"> </span><span class="tok-n">tool</span><span class="tok-p">.</span><span class="tok-n">attributes</span><span class="tok-p">())</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-p">{</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">" "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">attr</span><span class="tok-p">.</span><span class="tok-n">name</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"="</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">attr</span><span class="tok-p">.</span><span class="tok-n">value</span><span class="tok-p">();</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-p">}</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-k">for</span><span class="tok-w"> </span><span class="tok-p">(</span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_attribute</span><span class="tok-w"> </span><span class="tok-n">attr</span><span class="tok-o">:</span><span class="tok-w"> </span><span class="tok-n">tool</span><span class="tok-p">.</span><span class="tok-n">attributes</span><span class="tok-p">())</span>
|
||||
<span class="tok-w"> </span><span class="tok-p">{</span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">" "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">attr</span><span class="tok-p">.</span><span class="tok-n">name</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"="</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">attr</span><span class="tok-p">.</span><span class="tok-n">value</span><span class="tok-p">();</span>
|
||||
<span class="tok-w"> </span><span class="tok-p">}</span>
|
||||
|
||||
<span class="tok-w"> </span><span class="tok-k">for</span><span class="tok-w"> </span><span class="tok-p">(</span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_node</span><span class="tok-w"> </span><span class="tok-nl">child</span><span class="tok-p">:</span><span class="tok-w"> </span><span class="tok-n">tool</span><span class="tok-p">.</span><span class="tok-n">children</span><span class="tok-p">())</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-p">{</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">", child "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">child</span><span class="tok-p">.</span><span class="tok-n">name</span><span class="tok-p">();</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-p">}</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-k">for</span><span class="tok-w"> </span><span class="tok-p">(</span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_node</span><span class="tok-w"> </span><span class="tok-n">child</span><span class="tok-o">:</span><span class="tok-w"> </span><span class="tok-n">tool</span><span class="tok-p">.</span><span class="tok-n">children</span><span class="tok-p">())</span>
|
||||
<span class="tok-w"> </span><span class="tok-p">{</span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">", child "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">child</span><span class="tok-p">.</span><span class="tok-n">name</span><span class="tok-p">();</span>
|
||||
<span class="tok-w"> </span><span class="tok-p">}</span>
|
||||
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">endl</span><span class="tok-p">;</span><span class="tok-w"></span>
|
||||
<span class="tok-p">}</span><span class="tok-w"></span></code></pre>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">endl</span><span class="tok-p">;</span>
|
||||
<span class="tok-p">}</span></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
@@ -825,23 +824,23 @@ All pugixml classes and functions are located in <code>pugi</code> namespace; yo
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">struct</span> <span class="tok-nc">simple_walker</span><span class="tok-o">:</span><span class="tok-w"> </span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_tree_walker</span><span class="tok-w"></span>
|
||||
<span class="tok-p">{</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-k">virtual</span><span class="tok-w"> </span><span class="tok-kt">bool</span><span class="tok-w"> </span><span class="tok-nf">for_each</span><span class="tok-p">(</span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_node</span><span class="tok-o">&</span><span class="tok-w"> </span><span class="tok-n">node</span><span class="tok-p">)</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-p">{</span><span class="tok-w"></span>
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">struct</span><span class="tok-w"> </span><span class="tok-nc">simple_walker</span><span class="tok-o">:</span><span class="tok-w"> </span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_tree_walker</span>
|
||||
<span class="tok-p">{</span>
|
||||
<span class="tok-w"> </span><span class="tok-k">virtual</span><span class="tok-w"> </span><span class="tok-kt">bool</span><span class="tok-w"> </span><span class="tok-nf">for_each</span><span class="tok-p">(</span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_node</span><span class="tok-o">&</span><span class="tok-w"> </span><span class="tok-n">node</span><span class="tok-p">)</span>
|
||||
<span class="tok-w"> </span><span class="tok-p">{</span>
|
||||
<span class="tok-w"> </span><span class="tok-k">for</span><span class="tok-w"> </span><span class="tok-p">(</span><span class="tok-kt">int</span><span class="tok-w"> </span><span class="tok-n">i</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-mi">0</span><span class="tok-p">;</span><span class="tok-w"> </span><span class="tok-n">i</span><span class="tok-w"> </span><span class="tok-o"><</span><span class="tok-w"> </span><span class="tok-n">depth</span><span class="tok-p">();</span><span class="tok-w"> </span><span class="tok-o">++</span><span class="tok-n">i</span><span class="tok-p">)</span><span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">" "</span><span class="tok-p">;</span><span class="tok-w"> </span><span class="tok-c1">// indentation</span>
|
||||
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">node_types</span><span class="tok-p">[</span><span class="tok-n">node</span><span class="tok-p">.</span><span class="tok-n">type</span><span class="tok-p">()]</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">": name='"</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">node</span><span class="tok-p">.</span><span class="tok-n">name</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"', value='"</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">node</span><span class="tok-p">.</span><span class="tok-n">value</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"'</span><span class="tok-se">\n</span><span class="tok-s">"</span><span class="tok-p">;</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">node_types</span><span class="tok-p">[</span><span class="tok-n">node</span><span class="tok-p">.</span><span class="tok-n">type</span><span class="tok-p">()]</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">": name='"</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">node</span><span class="tok-p">.</span><span class="tok-n">name</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"', value='"</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">node</span><span class="tok-p">.</span><span class="tok-n">value</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"'</span><span class="tok-se">\n</span><span class="tok-s">"</span><span class="tok-p">;</span>
|
||||
|
||||
<span class="tok-w"> </span><span class="tok-k">return</span><span class="tok-w"> </span><span class="tok-nb">true</span><span class="tok-p">;</span><span class="tok-w"> </span><span class="tok-c1">// continue traversal</span>
|
||||
<span class="tok-w"> </span><span class="tok-p">}</span><span class="tok-w"></span>
|
||||
<span class="tok-p">};</span><span class="tok-w"></span></code></pre>
|
||||
<span class="tok-w"> </span><span class="tok-p">}</span>
|
||||
<span class="tok-p">};</span></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-n">simple_walker</span><span class="tok-w"> </span><span class="tok-n">walker</span><span class="tok-p">;</span><span class="tok-w"></span>
|
||||
<span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">traverse</span><span class="tok-p">(</span><span class="tok-n">walker</span><span class="tok-p">);</span><span class="tok-w"></span></code></pre>
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-n">simple_walker</span><span class="tok-w"> </span><span class="tok-n">walker</span><span class="tok-p">;</span>
|
||||
<span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">traverse</span><span class="tok-p">(</span><span class="tok-n">walker</span><span class="tok-p">);</span></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
@@ -849,20 +848,20 @@ All pugixml classes and functions are located in <code>pugi</code> namespace; yo
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xpath_node_set</span><span class="tok-w"> </span><span class="tok-n">tools</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">select_nodes</span><span class="tok-p">(</span><span class="tok-s">"/Profile/Tools/Tool[@AllowRemote='true' and @DeriveCaptionFrom='lastparam']"</span><span class="tok-p">);</span><span class="tok-w"></span>
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xpath_node_set</span><span class="tok-w"> </span><span class="tok-n">tools</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">select_nodes</span><span class="tok-p">(</span><span class="tok-s">"/Profile/Tools/Tool[@AllowRemote='true' and @DeriveCaptionFrom='lastparam']"</span><span class="tok-p">);</span>
|
||||
|
||||
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"Tools:</span><span class="tok-se">\n</span><span class="tok-s">"</span><span class="tok-p">;</span><span class="tok-w"></span>
|
||||
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"Tools:</span><span class="tok-se">\n</span><span class="tok-s">"</span><span class="tok-p">;</span>
|
||||
|
||||
<span class="tok-k">for</span><span class="tok-w"> </span><span class="tok-p">(</span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xpath_node_set</span><span class="tok-o">::</span><span class="tok-n">const_iterator</span><span class="tok-w"> </span><span class="tok-n">it</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">tools</span><span class="tok-p">.</span><span class="tok-n">begin</span><span class="tok-p">();</span><span class="tok-w"> </span><span class="tok-n">it</span><span class="tok-w"> </span><span class="tok-o">!=</span><span class="tok-w"> </span><span class="tok-n">tools</span><span class="tok-p">.</span><span class="tok-n">end</span><span class="tok-p">();</span><span class="tok-w"> </span><span class="tok-o">++</span><span class="tok-n">it</span><span class="tok-p">)</span><span class="tok-w"></span>
|
||||
<span class="tok-p">{</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xpath_node</span><span class="tok-w"> </span><span class="tok-n">node</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-o">*</span><span class="tok-n">it</span><span class="tok-p">;</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">node</span><span class="tok-p">.</span><span class="tok-n">node</span><span class="tok-p">().</span><span class="tok-n">attribute</span><span class="tok-p">(</span><span class="tok-s">"Filename"</span><span class="tok-p">).</span><span class="tok-n">value</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"</span><span class="tok-se">\n</span><span class="tok-s">"</span><span class="tok-p">;</span><span class="tok-w"></span>
|
||||
<span class="tok-p">}</span><span class="tok-w"></span>
|
||||
<span class="tok-k">for</span><span class="tok-w"> </span><span class="tok-p">(</span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xpath_node_set</span><span class="tok-o">::</span><span class="tok-n">const_iterator</span><span class="tok-w"> </span><span class="tok-n">it</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">tools</span><span class="tok-p">.</span><span class="tok-n">begin</span><span class="tok-p">();</span><span class="tok-w"> </span><span class="tok-n">it</span><span class="tok-w"> </span><span class="tok-o">!=</span><span class="tok-w"> </span><span class="tok-n">tools</span><span class="tok-p">.</span><span class="tok-n">end</span><span class="tok-p">();</span><span class="tok-w"> </span><span class="tok-o">++</span><span class="tok-n">it</span><span class="tok-p">)</span>
|
||||
<span class="tok-p">{</span>
|
||||
<span class="tok-w"> </span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xpath_node</span><span class="tok-w"> </span><span class="tok-n">node</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-o">*</span><span class="tok-n">it</span><span class="tok-p">;</span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">node</span><span class="tok-p">.</span><span class="tok-n">node</span><span class="tok-p">().</span><span class="tok-n">attribute</span><span class="tok-p">(</span><span class="tok-s">"Filename"</span><span class="tok-p">).</span><span class="tok-n">value</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"</span><span class="tok-se">\n</span><span class="tok-s">"</span><span class="tok-p">;</span>
|
||||
<span class="tok-p">}</span>
|
||||
|
||||
<span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xpath_node</span><span class="tok-w"> </span><span class="tok-n">build_tool</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">select_node</span><span class="tok-p">(</span><span class="tok-s">"//Tool[contains(Description, 'build system')]"</span><span class="tok-p">);</span><span class="tok-w"></span>
|
||||
<span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xpath_node</span><span class="tok-w"> </span><span class="tok-n">build_tool</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">select_node</span><span class="tok-p">(</span><span class="tok-s">"//Tool[contains(Description, 'build system')]"</span><span class="tok-p">);</span>
|
||||
|
||||
<span class="tok-k">if</span><span class="tok-w"> </span><span class="tok-p">(</span><span class="tok-n">build_tool</span><span class="tok-p">)</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"Build tool: "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">build_tool</span><span class="tok-p">.</span><span class="tok-n">node</span><span class="tok-p">().</span><span class="tok-n">attribute</span><span class="tok-p">(</span><span class="tok-s">"Filename"</span><span class="tok-p">).</span><span class="tok-n">value</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"</span><span class="tok-se">\n</span><span class="tok-s">"</span><span class="tok-p">;</span><span class="tok-w"></span></code></pre>
|
||||
<span class="tok-k">if</span><span class="tok-w"> </span><span class="tok-p">(</span><span class="tok-n">build_tool</span><span class="tok-p">)</span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"Build tool: "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">build_tool</span><span class="tok-p">.</span><span class="tok-n">node</span><span class="tok-p">().</span><span class="tok-n">attribute</span><span class="tok-p">(</span><span class="tok-s">"Filename"</span><span class="tok-p">).</span><span class="tok-n">value</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"</span><span class="tok-se">\n</span><span class="tok-s">"</span><span class="tok-p">;</span></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="admonitionblock caution">
|
||||
@@ -893,35 +892,35 @@ XPath functions throw <code>xpath_exception</code> objects on error; the sample
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_node</span><span class="tok-w"> </span><span class="tok-n">node</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">child</span><span class="tok-p">(</span><span class="tok-s">"node"</span><span class="tok-p">);</span><span class="tok-w"></span>
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_node</span><span class="tok-w"> </span><span class="tok-n">node</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">child</span><span class="tok-p">(</span><span class="tok-s">"node"</span><span class="tok-p">);</span>
|
||||
|
||||
<span class="tok-c1">// change node name</span>
|
||||
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">node</span><span class="tok-p">.</span><span class="tok-n">set_name</span><span class="tok-p">(</span><span class="tok-s">"notnode"</span><span class="tok-p">);</span><span class="tok-w"></span>
|
||||
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">", new node name: "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">node</span><span class="tok-p">.</span><span class="tok-n">name</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">endl</span><span class="tok-p">;</span><span class="tok-w"></span>
|
||||
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">node</span><span class="tok-p">.</span><span class="tok-n">set_name</span><span class="tok-p">(</span><span class="tok-s">"notnode"</span><span class="tok-p">);</span>
|
||||
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">", new node name: "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">node</span><span class="tok-p">.</span><span class="tok-n">name</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">endl</span><span class="tok-p">;</span>
|
||||
|
||||
<span class="tok-c1">// change comment text</span>
|
||||
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">last_child</span><span class="tok-p">().</span><span class="tok-n">set_value</span><span class="tok-p">(</span><span class="tok-s">"useless comment"</span><span class="tok-p">);</span><span class="tok-w"></span>
|
||||
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">", new comment text: "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">last_child</span><span class="tok-p">().</span><span class="tok-n">value</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">endl</span><span class="tok-p">;</span><span class="tok-w"></span>
|
||||
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">last_child</span><span class="tok-p">().</span><span class="tok-n">set_value</span><span class="tok-p">(</span><span class="tok-s">"useless comment"</span><span class="tok-p">);</span>
|
||||
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">", new comment text: "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">last_child</span><span class="tok-p">().</span><span class="tok-n">value</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">endl</span><span class="tok-p">;</span>
|
||||
|
||||
<span class="tok-c1">// we can't change value of the element or name of the comment</span>
|
||||
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">node</span><span class="tok-p">.</span><span class="tok-n">set_value</span><span class="tok-p">(</span><span class="tok-s">"1"</span><span class="tok-p">)</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">", "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">last_child</span><span class="tok-p">().</span><span class="tok-n">set_name</span><span class="tok-p">(</span><span class="tok-s">"2"</span><span class="tok-p">)</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">endl</span><span class="tok-p">;</span><span class="tok-w"></span></code></pre>
|
||||
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">node</span><span class="tok-p">.</span><span class="tok-n">set_value</span><span class="tok-p">(</span><span class="tok-s">"1"</span><span class="tok-p">)</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">", "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">last_child</span><span class="tok-p">().</span><span class="tok-n">set_name</span><span class="tok-p">(</span><span class="tok-s">"2"</span><span class="tok-p">)</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">endl</span><span class="tok-p">;</span></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_attribute</span><span class="tok-w"> </span><span class="tok-n">attr</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">node</span><span class="tok-p">.</span><span class="tok-n">attribute</span><span class="tok-p">(</span><span class="tok-s">"id"</span><span class="tok-p">);</span><span class="tok-w"></span>
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_attribute</span><span class="tok-w"> </span><span class="tok-n">attr</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">node</span><span class="tok-p">.</span><span class="tok-n">attribute</span><span class="tok-p">(</span><span class="tok-s">"id"</span><span class="tok-p">);</span>
|
||||
|
||||
<span class="tok-c1">// change attribute name/value</span>
|
||||
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">attr</span><span class="tok-p">.</span><span class="tok-n">set_name</span><span class="tok-p">(</span><span class="tok-s">"key"</span><span class="tok-p">)</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">", "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">attr</span><span class="tok-p">.</span><span class="tok-n">set_value</span><span class="tok-p">(</span><span class="tok-s">"345"</span><span class="tok-p">);</span><span class="tok-w"></span>
|
||||
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">", new attribute: "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">attr</span><span class="tok-p">.</span><span class="tok-n">name</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"="</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">attr</span><span class="tok-p">.</span><span class="tok-n">value</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">endl</span><span class="tok-p">;</span><span class="tok-w"></span>
|
||||
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">attr</span><span class="tok-p">.</span><span class="tok-n">set_name</span><span class="tok-p">(</span><span class="tok-s">"key"</span><span class="tok-p">)</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">", "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">attr</span><span class="tok-p">.</span><span class="tok-n">set_value</span><span class="tok-p">(</span><span class="tok-s">"345"</span><span class="tok-p">);</span>
|
||||
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">", new attribute: "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">attr</span><span class="tok-p">.</span><span class="tok-n">name</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"="</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">attr</span><span class="tok-p">.</span><span class="tok-n">value</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">endl</span><span class="tok-p">;</span>
|
||||
|
||||
<span class="tok-c1">// we can use numbers or booleans</span>
|
||||
<span class="tok-n">attr</span><span class="tok-p">.</span><span class="tok-n">set_value</span><span class="tok-p">(</span><span class="tok-mf">1.234</span><span class="tok-p">);</span><span class="tok-w"></span>
|
||||
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"new attribute value: "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">attr</span><span class="tok-p">.</span><span class="tok-n">value</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">endl</span><span class="tok-p">;</span><span class="tok-w"></span>
|
||||
<span class="tok-n">attr</span><span class="tok-p">.</span><span class="tok-n">set_value</span><span class="tok-p">(</span><span class="tok-mf">1.234</span><span class="tok-p">);</span>
|
||||
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"new attribute value: "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">attr</span><span class="tok-p">.</span><span class="tok-n">value</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">endl</span><span class="tok-p">;</span>
|
||||
|
||||
<span class="tok-c1">// we can also use assignment operators for more concise code</span>
|
||||
<span class="tok-n">attr</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-nb">true</span><span class="tok-p">;</span><span class="tok-w"></span>
|
||||
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"final attribute value: "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">attr</span><span class="tok-p">.</span><span class="tok-n">value</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">endl</span><span class="tok-p">;</span><span class="tok-w"></span></code></pre>
|
||||
<span class="tok-n">attr</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-nb">true</span><span class="tok-p">;</span>
|
||||
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"final attribute value: "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">attr</span><span class="tok-p">.</span><span class="tok-n">value</span><span class="tok-p">()</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">endl</span><span class="tok-p">;</span></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
@@ -945,19 +944,19 @@ XPath functions throw <code>xpath_exception</code> objects on error; the sample
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-c1">// add node with some name</span>
|
||||
<span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_node</span><span class="tok-w"> </span><span class="tok-n">node</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">append_child</span><span class="tok-p">(</span><span class="tok-s">"node"</span><span class="tok-p">);</span><span class="tok-w"></span>
|
||||
<span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_node</span><span class="tok-w"> </span><span class="tok-n">node</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">append_child</span><span class="tok-p">(</span><span class="tok-s">"node"</span><span class="tok-p">);</span>
|
||||
|
||||
<span class="tok-c1">// add description node with text child</span>
|
||||
<span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_node</span><span class="tok-w"> </span><span class="tok-n">descr</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">node</span><span class="tok-p">.</span><span class="tok-n">append_child</span><span class="tok-p">(</span><span class="tok-s">"description"</span><span class="tok-p">);</span><span class="tok-w"></span>
|
||||
<span class="tok-n">descr</span><span class="tok-p">.</span><span class="tok-n">append_child</span><span class="tok-p">(</span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">node_pcdata</span><span class="tok-p">).</span><span class="tok-n">set_value</span><span class="tok-p">(</span><span class="tok-s">"Simple node"</span><span class="tok-p">);</span><span class="tok-w"></span>
|
||||
<span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_node</span><span class="tok-w"> </span><span class="tok-n">descr</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">node</span><span class="tok-p">.</span><span class="tok-n">append_child</span><span class="tok-p">(</span><span class="tok-s">"description"</span><span class="tok-p">);</span>
|
||||
<span class="tok-n">descr</span><span class="tok-p">.</span><span class="tok-n">append_child</span><span class="tok-p">(</span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">node_pcdata</span><span class="tok-p">).</span><span class="tok-n">set_value</span><span class="tok-p">(</span><span class="tok-s">"Simple node"</span><span class="tok-p">);</span>
|
||||
|
||||
<span class="tok-c1">// add param node before the description</span>
|
||||
<span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_node</span><span class="tok-w"> </span><span class="tok-n">param</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">node</span><span class="tok-p">.</span><span class="tok-n">insert_child_before</span><span class="tok-p">(</span><span class="tok-s">"param"</span><span class="tok-p">,</span><span class="tok-w"> </span><span class="tok-n">descr</span><span class="tok-p">);</span><span class="tok-w"></span>
|
||||
<span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_node</span><span class="tok-w"> </span><span class="tok-n">param</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">node</span><span class="tok-p">.</span><span class="tok-n">insert_child_before</span><span class="tok-p">(</span><span class="tok-s">"param"</span><span class="tok-p">,</span><span class="tok-w"> </span><span class="tok-n">descr</span><span class="tok-p">);</span>
|
||||
|
||||
<span class="tok-c1">// add attributes to param node</span>
|
||||
<span class="tok-n">param</span><span class="tok-p">.</span><span class="tok-n">append_attribute</span><span class="tok-p">(</span><span class="tok-s">"name"</span><span class="tok-p">)</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-s">"version"</span><span class="tok-p">;</span><span class="tok-w"></span>
|
||||
<span class="tok-n">param</span><span class="tok-p">.</span><span class="tok-n">append_attribute</span><span class="tok-p">(</span><span class="tok-s">"value"</span><span class="tok-p">)</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-mf">1.1</span><span class="tok-p">;</span><span class="tok-w"></span>
|
||||
<span class="tok-n">param</span><span class="tok-p">.</span><span class="tok-n">insert_attribute_after</span><span class="tok-p">(</span><span class="tok-s">"type"</span><span class="tok-p">,</span><span class="tok-w"> </span><span class="tok-n">param</span><span class="tok-p">.</span><span class="tok-n">attribute</span><span class="tok-p">(</span><span class="tok-s">"name"</span><span class="tok-p">))</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-s">"float"</span><span class="tok-p">;</span><span class="tok-w"></span></code></pre>
|
||||
<span class="tok-n">param</span><span class="tok-p">.</span><span class="tok-n">append_attribute</span><span class="tok-p">(</span><span class="tok-s">"name"</span><span class="tok-p">)</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-s">"version"</span><span class="tok-p">;</span>
|
||||
<span class="tok-n">param</span><span class="tok-p">.</span><span class="tok-n">append_attribute</span><span class="tok-p">(</span><span class="tok-s">"value"</span><span class="tok-p">)</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-mf">1.1</span><span class="tok-p">;</span>
|
||||
<span class="tok-n">param</span><span class="tok-p">.</span><span class="tok-n">insert_attribute_after</span><span class="tok-p">(</span><span class="tok-s">"type"</span><span class="tok-p">,</span><span class="tok-w"> </span><span class="tok-n">param</span><span class="tok-p">.</span><span class="tok-n">attribute</span><span class="tok-p">(</span><span class="tok-s">"name"</span><span class="tok-p">))</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-s">"float"</span><span class="tok-p">;</span></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
@@ -969,16 +968,16 @@ XPath functions throw <code>xpath_exception</code> objects on error; the sample
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-c1">// remove description node with the whole subtree</span>
|
||||
<span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_node</span><span class="tok-w"> </span><span class="tok-n">node</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">child</span><span class="tok-p">(</span><span class="tok-s">"node"</span><span class="tok-p">);</span><span class="tok-w"></span>
|
||||
<span class="tok-n">node</span><span class="tok-p">.</span><span class="tok-n">remove_child</span><span class="tok-p">(</span><span class="tok-s">"description"</span><span class="tok-p">);</span><span class="tok-w"></span>
|
||||
<span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_node</span><span class="tok-w"> </span><span class="tok-n">node</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">child</span><span class="tok-p">(</span><span class="tok-s">"node"</span><span class="tok-p">);</span>
|
||||
<span class="tok-n">node</span><span class="tok-p">.</span><span class="tok-n">remove_child</span><span class="tok-p">(</span><span class="tok-s">"description"</span><span class="tok-p">);</span>
|
||||
|
||||
<span class="tok-c1">// remove id attribute</span>
|
||||
<span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_node</span><span class="tok-w"> </span><span class="tok-n">param</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">node</span><span class="tok-p">.</span><span class="tok-n">child</span><span class="tok-p">(</span><span class="tok-s">"param"</span><span class="tok-p">);</span><span class="tok-w"></span>
|
||||
<span class="tok-n">param</span><span class="tok-p">.</span><span class="tok-n">remove_attribute</span><span class="tok-p">(</span><span class="tok-s">"value"</span><span class="tok-p">);</span><span class="tok-w"></span>
|
||||
<span class="tok-c1">// remove value attribute</span>
|
||||
<span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_node</span><span class="tok-w"> </span><span class="tok-n">param</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">node</span><span class="tok-p">.</span><span class="tok-n">child</span><span class="tok-p">(</span><span class="tok-s">"param"</span><span class="tok-p">);</span>
|
||||
<span class="tok-n">param</span><span class="tok-p">.</span><span class="tok-n">remove_attribute</span><span class="tok-p">(</span><span class="tok-s">"value"</span><span class="tok-p">);</span>
|
||||
|
||||
<span class="tok-c1">// we can also remove nodes/attributes by handles</span>
|
||||
<span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_attribute</span><span class="tok-w"> </span><span class="tok-n">id</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">param</span><span class="tok-p">.</span><span class="tok-n">attribute</span><span class="tok-p">(</span><span class="tok-s">"name"</span><span class="tok-p">);</span><span class="tok-w"></span>
|
||||
<span class="tok-n">param</span><span class="tok-p">.</span><span class="tok-n">remove_attribute</span><span class="tok-p">(</span><span class="tok-n">id</span><span class="tok-p">);</span><span class="tok-w"></span></code></pre>
|
||||
<span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_attribute</span><span class="tok-w"> </span><span class="tok-n">id</span><span class="tok-w"> </span><span class="tok-o">=</span><span class="tok-w"> </span><span class="tok-n">param</span><span class="tok-p">.</span><span class="tok-n">attribute</span><span class="tok-p">(</span><span class="tok-s">"name"</span><span class="tok-p">);</span>
|
||||
<span class="tok-n">param</span><span class="tok-p">.</span><span class="tok-n">remove_attribute</span><span class="tok-p">(</span><span class="tok-n">id</span><span class="tok-p">);</span></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -998,7 +997,7 @@ XPath functions throw <code>xpath_exception</code> objects on error; the sample
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-c1">// save document to file</span>
|
||||
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"Saving result: "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">save_file</span><span class="tok-p">(</span><span class="tok-s">"save_file_output.xml"</span><span class="tok-p">)</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">endl</span><span class="tok-p">;</span><span class="tok-w"></span></code></pre>
|
||||
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"Saving result: "</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">save_file</span><span class="tok-p">(</span><span class="tok-s">"save_file_output.xml"</span><span class="tok-p">)</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">endl</span><span class="tok-p">;</span></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
@@ -1010,27 +1009,27 @@ XPath functions throw <code>xpath_exception</code> objects on error; the sample
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-c1">// save document to standard output</span>
|
||||
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"Document:</span><span class="tok-se">\n</span><span class="tok-s">"</span><span class="tok-p">;</span><span class="tok-w"></span>
|
||||
<span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">save</span><span class="tok-p">(</span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-p">);</span><span class="tok-w"></span></code></pre>
|
||||
<span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-w"> </span><span class="tok-o"><<</span><span class="tok-w"> </span><span class="tok-s">"Document:</span><span class="tok-se">\n</span><span class="tok-s">"</span><span class="tok-p">;</span>
|
||||
<span class="tok-n">doc</span><span class="tok-p">.</span><span class="tok-n">save</span><span class="tok-p">(</span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">cout</span><span class="tok-p">);</span></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>All of the above saving functions are implemented in terms of writer interface. This is a simple interface with a single function, which is called several times during output process with chunks of document data as input. In order to output the document via some custom transport, for example sockets, you should create an object which implements <code>xml_writer_file</code> interface and pass it to <code>xml_document::save</code> function.</p>
|
||||
<p>All of the above saving functions are implemented in terms of writer interface. This is a simple interface with a single function, which is called several times during output process with chunks of document data as input. In order to output the document via some custom transport, for example sockets, you should create an object which implements <code>xml_writer</code> interface and pass it to <code>xml_document::save</code> function.</p>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
<p>This is a simple example of custom writer for saving document data to STL string (<a href="samples/save_custom_writer.cpp" class="bare">samples/save_custom_writer.cpp</a>); read the sample code for more complex examples:</p>
|
||||
</div>
|
||||
<div class="listingblock">
|
||||
<div class="content">
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">struct</span> <span class="tok-nc">xml_string_writer</span><span class="tok-o">:</span><span class="tok-w"> </span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_writer</span><span class="tok-w"></span>
|
||||
<span class="tok-p">{</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">string</span><span class="tok-w"> </span><span class="tok-n">result</span><span class="tok-p">;</span><span class="tok-w"></span>
|
||||
<pre class="pygments highlight"><code data-lang="c++"><span></span><span class="tok-k">struct</span><span class="tok-w"> </span><span class="tok-nc">xml_string_writer</span><span class="tok-o">:</span><span class="tok-w"> </span><span class="tok-n">pugi</span><span class="tok-o">::</span><span class="tok-n">xml_writer</span>
|
||||
<span class="tok-p">{</span>
|
||||
<span class="tok-w"> </span><span class="tok-n">std</span><span class="tok-o">::</span><span class="tok-n">string</span><span class="tok-w"> </span><span class="tok-n">result</span><span class="tok-p">;</span>
|
||||
|
||||
<span class="tok-w"> </span><span class="tok-k">virtual</span><span class="tok-w"> </span><span class="tok-kt">void</span><span class="tok-w"> </span><span class="tok-nf">write</span><span class="tok-p">(</span><span class="tok-k">const</span><span class="tok-w"> </span><span class="tok-kt">void</span><span class="tok-o">*</span><span class="tok-w"> </span><span class="tok-n">data</span><span class="tok-p">,</span><span class="tok-w"> </span><span class="tok-kt">size_t</span><span class="tok-w"> </span><span class="tok-n">size</span><span class="tok-p">)</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-p">{</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-n">result</span><span class="tok-p">.</span><span class="tok-n">append</span><span class="tok-p">(</span><span class="tok-k">static_cast</span><span class="tok-o"><</span><span class="tok-k">const</span><span class="tok-w"> </span><span class="tok-kt">char</span><span class="tok-o">*></span><span class="tok-p">(</span><span class="tok-n">data</span><span class="tok-p">),</span><span class="tok-w"> </span><span class="tok-n">size</span><span class="tok-p">);</span><span class="tok-w"></span>
|
||||
<span class="tok-w"> </span><span class="tok-p">}</span><span class="tok-w"></span>
|
||||
<span class="tok-p">};</span><span class="tok-w"></span></code></pre>
|
||||
<span class="tok-w"> </span><span class="tok-k">virtual</span><span class="tok-w"> </span><span class="tok-kt">void</span><span class="tok-w"> </span><span class="tok-nf">write</span><span class="tok-p">(</span><span class="tok-k">const</span><span class="tok-w"> </span><span class="tok-kt">void</span><span class="tok-o">*</span><span class="tok-w"> </span><span class="tok-n">data</span><span class="tok-p">,</span><span class="tok-w"> </span><span class="tok-kt">size_t</span><span class="tok-w"> </span><span class="tok-n">size</span><span class="tok-p">)</span>
|
||||
<span class="tok-w"> </span><span class="tok-p">{</span>
|
||||
<span class="tok-w"> </span><span class="tok-n">result</span><span class="tok-p">.</span><span class="tok-n">append</span><span class="tok-p">(</span><span class="tok-k">static_cast</span><span class="tok-o"><</span><span class="tok-k">const</span><span class="tok-w"> </span><span class="tok-kt">char</span><span class="tok-o">*></span><span class="tok-p">(</span><span class="tok-n">data</span><span class="tok-p">),</span><span class="tok-w"> </span><span class="tok-n">size</span><span class="tok-p">);</span>
|
||||
<span class="tok-w"> </span><span class="tok-p">}</span>
|
||||
<span class="tok-p">};</span></code></pre>
|
||||
</div>
|
||||
</div>
|
||||
<div class="paragraph">
|
||||
@@ -1057,7 +1056,7 @@ XPath functions throw <code>xpath_exception</code> objects on error; the sample
|
||||
</div>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>Copyright (c) 2006-2022 Arseny Kapoulkine
|
||||
<pre>Copyright (c) 2006-2026 Arseny Kapoulkine
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
@@ -1087,7 +1086,7 @@ OTHER DEALINGS IN THE SOFTWARE.</pre>
|
||||
<div class="literalblock">
|
||||
<div class="content">
|
||||
<pre>This software is based on pugixml library (https://pugixml.org).
|
||||
pugixml is Copyright (C) 2006-2022 Arseny Kapoulkine.</pre>
|
||||
pugixml is Copyright (C) 2006-2026 Arseny Kapoulkine.</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1101,7 +1100,7 @@ pugixml is Copyright (C) 2006-2022 Arseny Kapoulkine.</pre>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div id="footer-text">
|
||||
Last updated 2022-02-08 19:57:47 -0800
|
||||
Last updated 2026-06-12 14:06:53 -0700
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -12,7 +12,7 @@ int main()
|
||||
pugi::xml_node node = doc.child("node");
|
||||
node.remove_child("description");
|
||||
|
||||
// remove id attribute
|
||||
// remove value attribute
|
||||
pugi::xml_node param = node.child("param");
|
||||
param.remove_attribute("value");
|
||||
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
pugixml 1.12 - an XML processing library
|
||||
pugixml 1.16 - an XML processing library
|
||||
|
||||
Copyright (C) 2006-2022, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
|
||||
Copyright (C) 2006-2026, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
|
||||
Report bugs and download new versions at https://pugixml.org/
|
||||
|
||||
This is the distribution of pugixml, which is a C++ XML processing library,
|
||||
@@ -26,7 +26,7 @@ The distribution contains the following folders:
|
||||
|
||||
This library is distributed under the MIT License:
|
||||
|
||||
Copyright (c) 2006-2022 Arseny Kapoulkine
|
||||
Copyright (c) 2006-2026 Arseny Kapoulkine
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<package xmlns="http://schemas.microsoft.com/packaging/2011/10/nuspec.xsd">
|
||||
<metadata>
|
||||
<id>pugixml</id>
|
||||
<version>1.12.0-appveyor</version>
|
||||
<version>1.16.0</version>
|
||||
<title>pugixml</title>
|
||||
<authors>Arseny Kapoulkine</authors>
|
||||
<owners>Arseny Kapoulkine</owners>
|
||||
@@ -11,10 +11,10 @@
|
||||
<projectUrl>https://pugixml.org/</projectUrl>
|
||||
<description>pugixml is a C++ XML processing library, which consists of a DOM-like interface with rich traversal/modification capabilities, an extremely fast XML parser which constructs the DOM tree from an XML file/buffer, and an XPath 1.0 implementation for complex data-driven tree queries. Full Unicode support is also available, with Unicode interface variants and conversions between different Unicode encodings (which happen automatically during parsing/saving).
|
||||
pugixml is used by a lot of projects, both open-source and proprietary, for performance and easy-to-use interface.
|
||||
This package contains builds for VS2013, VS2015, VS2017, VS2019 and VS2022, for both statically linked and DLL CRT; you can switch the CRT linkage in Project -> Properties -> Referenced Packages -> pugixml.</description>
|
||||
This package contains builds for VS2017, VS2019, VS2022 and VS2026, for both statically linked and DLL CRT; you can switch the CRT linkage in Project -> Properties -> Referenced Packages -> pugixml.</description>
|
||||
<summary>Light-weight, simple and fast XML parser for C++ with XPath support</summary>
|
||||
<releaseNotes>https://pugixml.org/docs/manual.html#changes</releaseNotes>
|
||||
<copyright>Copyright (c) 2006-2022 Arseny Kapoulkine</copyright>
|
||||
<copyright>Copyright (c) 2006-2026 Arseny Kapoulkine</copyright>
|
||||
<tags>native nativepackage</tags>
|
||||
</metadata>
|
||||
</package>
|
||||
|
||||
+7
-17
@@ -35,7 +35,10 @@ Force-Copy "../src/pugiconfig.hpp" "nuget/build/native/include/pugiconfig.hpp"
|
||||
Force-Copy "../src/pugixml.hpp" "nuget/build/native/include/pugixml.hpp"
|
||||
Force-Copy "../src/pugixml.cpp" "nuget/build/native/include/pugixml.cpp"
|
||||
|
||||
if ($args[0] -eq 2022){
|
||||
if ($args[0] -eq 2026){
|
||||
Build-Version "vs2026" "v145" "dynamic"
|
||||
Build-Version "vs2026" "v145" "static"
|
||||
} elseif ($args[0] -eq 2022){
|
||||
Build-Version "vs2022" "v143" "dynamic"
|
||||
Build-Version "vs2022" "v143" "static"
|
||||
|
||||
@@ -47,22 +50,9 @@ if ($args[0] -eq 2022){
|
||||
Build-Version "vs2017" "v141" "dynamic"
|
||||
Build-Version "vs2017" "v141" "static"
|
||||
|
||||
Build-Version "vs2015" "v140" "dynamic"
|
||||
Build-Version "vs2015" "v140" "static"
|
||||
|
||||
Build-Version "vs2013" "v120" "dynamic"
|
||||
Build-Version "vs2013" "v120" "static"
|
||||
|
||||
} elseif($args[0] -eq 2015){
|
||||
Build-Version "vs2015" "v140" "dynamic"
|
||||
Build-Version "vs2015" "v140" "static"
|
||||
|
||||
Build-Version "vs2013" "v120" "dynamic"
|
||||
Build-Version "vs2013" "v120" "static"
|
||||
|
||||
} elseif($args[0] -eq 2013){
|
||||
Build-Version "vs2013" "v120" "dynamic"
|
||||
Build-Version "vs2013" "v120" "static"
|
||||
} else {
|
||||
Write-Error "Unsupported Visual Studio version '$($args[0])'"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Run-Command "nuget pack nuget"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
prefix=@CMAKE_INSTALL_PREFIX@
|
||||
exec_prefix=${prefix}
|
||||
includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@@INSTALL_SUFFIX@
|
||||
libdir=@CMAKE_INSTALL_FULL_LIBDIR@@INSTALL_SUFFIX@
|
||||
includedir=@PUGIXML_PC_INCLUDEDIR@
|
||||
libdir=@PUGIXML_PC_LIBDIR@
|
||||
|
||||
Name: pugixml
|
||||
Description: Light-weight, simple and fast XML parser for C++ with XPath support.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = "pugixml"
|
||||
s.version = "1.12"
|
||||
s.version = "1.16"
|
||||
s.summary = "C++ XML parser library."
|
||||
s.homepage = "https://pugixml.org"
|
||||
s.license = "MIT"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#include <winver.h>
|
||||
|
||||
#define PUGIXML_VERSION_MAJOR 1
|
||||
#define PUGIXML_VERSION_MINOR 12
|
||||
#define PUGIXML_VERSION_MINOR 16
|
||||
#define PUGIXML_VERSION_PATCH 0
|
||||
#define PUGIXML_VERSION_NUMBER "1.12.0\0"
|
||||
#define PUGIXML_VERSION_NUMBER "1.16.0\0"
|
||||
|
||||
#if defined(GCC_WINDRES) || defined(__MINGW32__) || defined(__CYGWIN__)
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
@@ -31,7 +31,7 @@ BEGIN
|
||||
VALUE "FileDescription", "pugixml library\0"
|
||||
VALUE "FileVersion", PUGIXML_VERSION_NUMBER
|
||||
VALUE "InternalName", "pugixml.dll\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2006-2022, by Arseny Kapoulkine\0"
|
||||
VALUE "LegalCopyright", "Copyright (C) 2006-2026, by Arseny Kapoulkine\0"
|
||||
VALUE "OriginalFilename", "pugixml.dll\0"
|
||||
VALUE "ProductName", "pugixml\0"
|
||||
VALUE "ProductVersion", PUGIXML_VERSION_NUMBER
|
||||
|
||||
@@ -99,6 +99,7 @@
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
<DebugInformationFormat>OldStyle</DebugInformationFormat>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -115,6 +116,7 @@
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
<DebugInformationFormat>OldStyle</DebugInformationFormat>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -132,6 +134,7 @@
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
<DebugInformationFormat>OldStyle</DebugInformationFormat>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -151,6 +154,7 @@
|
||||
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
<DebugInformationFormat>OldStyle</DebugInformationFormat>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
|
||||
@@ -100,6 +100,7 @@
|
||||
<DebugInformationFormat>OldStyle</DebugInformationFormat>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -117,6 +118,7 @@
|
||||
<DebugInformationFormat>OldStyle</DebugInformationFormat>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -135,6 +137,7 @@
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
<DebugInformationFormat>OldStyle</DebugInformationFormat>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -155,6 +158,7 @@
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
<DebugInformationFormat>OldStyle</DebugInformationFormat>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
|
||||
@@ -99,6 +99,7 @@
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
<DebugInformationFormat>OldStyle</DebugInformationFormat>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -115,6 +116,7 @@
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
<DebugInformationFormat>OldStyle</DebugInformationFormat>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -132,6 +134,7 @@
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
<DebugInformationFormat>OldStyle</DebugInformationFormat>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -151,6 +154,7 @@
|
||||
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
<DebugInformationFormat>OldStyle</DebugInformationFormat>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
|
||||
@@ -100,6 +100,7 @@
|
||||
<DebugInformationFormat>OldStyle</DebugInformationFormat>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -117,6 +118,7 @@
|
||||
<DebugInformationFormat>OldStyle</DebugInformationFormat>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -135,6 +137,7 @@
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
<DebugInformationFormat>OldStyle</DebugInformationFormat>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -155,6 +158,7 @@
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
<DebugInformationFormat>OldStyle</DebugInformationFormat>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
|
||||
@@ -0,0 +1,176 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{07CF01C0-B887-499D-AD9C-799CB6A9FE64}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>pugixml</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v145</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v145</PlatformToolset>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v145</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v145</PlatformToolset>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>vs2026\$(Platform)_$(Configuration)\</OutDir>
|
||||
<IntDir>vs2026\$(Platform)_$(Configuration)\</IntDir>
|
||||
<TargetName>pugixml</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>vs2026\$(Platform)_$(Configuration)\</OutDir>
|
||||
<IntDir>vs2026\$(Platform)_$(Configuration)\</IntDir>
|
||||
<TargetName>pugixml</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>vs2026\$(Platform)_$(Configuration)\</OutDir>
|
||||
<IntDir>vs2026\$(Platform)_$(Configuration)\</IntDir>
|
||||
<TargetName>pugixml</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>vs2026\$(Platform)_$(Configuration)\</OutDir>
|
||||
<IntDir>vs2026\$(Platform)_$(Configuration)\</IntDir>
|
||||
<TargetName>pugixml</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
<DebugInformationFormat>OldStyle</DebugInformationFormat>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
<DebugInformationFormat>OldStyle</DebugInformationFormat>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
<DebugInformationFormat>OldStyle</DebugInformationFormat>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
<DebugInformationFormat>OldStyle</DebugInformationFormat>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\pugiconfig.hpp" />
|
||||
<ClInclude Include="..\src\pugixml.hpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\pugixml.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,180 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{07CF01C0-B887-499D-AD9C-799CB6A9FE64}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>pugixml</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v145</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v145</PlatformToolset>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v145</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v145</PlatformToolset>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>vs2026\$(Platform)_$(Configuration)Static\</OutDir>
|
||||
<IntDir>vs2026\$(Platform)_$(Configuration)Static\</IntDir>
|
||||
<TargetName>pugixml</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>vs2026\$(Platform)_$(Configuration)Static\</OutDir>
|
||||
<IntDir>vs2026\$(Platform)_$(Configuration)Static\</IntDir>
|
||||
<TargetName>pugixml</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>vs2026\$(Platform)_$(Configuration)Static\</OutDir>
|
||||
<IntDir>vs2026\$(Platform)_$(Configuration)Static\</IntDir>
|
||||
<TargetName>pugixml</TargetName>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>vs2026\$(Platform)_$(Configuration)Static\</OutDir>
|
||||
<IntDir>vs2026\$(Platform)_$(Configuration)Static\</IntDir>
|
||||
<TargetName>pugixml</TargetName>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
<DebugInformationFormat>OldStyle</DebugInformationFormat>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
<DebugInformationFormat>OldStyle</DebugInformationFormat>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
<DebugInformationFormat>OldStyle</DebugInformationFormat>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>
|
||||
</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
<DebugInformationFormat>OldStyle</DebugInformationFormat>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\pugiconfig.hpp" />
|
||||
<ClInclude Include="..\src\pugixml.hpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\src\pugixml.cpp" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"bomFormat": "CycloneDX",
|
||||
"specVersion": "1.6",
|
||||
"version": 1,
|
||||
"metadata": {
|
||||
"authors": [
|
||||
{
|
||||
"name": "@VCS_SBOM_AUTHORS@"
|
||||
}
|
||||
]
|
||||
},
|
||||
"components": [
|
||||
{
|
||||
"type": "library",
|
||||
"bom-ref": "pkg:github/zeux/pugixml@@VCS_TAG@",
|
||||
"cpe": "cpe:2.3:a:pugixml_project:pugixml:@VCS_TAG@:*:*:*:*:*:*:*",
|
||||
"name": "pugixml",
|
||||
"version": "@VCS_VERSION@",
|
||||
"description": "C++ XML processing library",
|
||||
"supplier": {
|
||||
"name": "pugixml developers"
|
||||
},
|
||||
"authors": [
|
||||
{
|
||||
"name": "@VCS_AUTHORS@"
|
||||
}
|
||||
],
|
||||
"licenses": [
|
||||
{
|
||||
"license": {
|
||||
"id": "MIT"
|
||||
}
|
||||
}
|
||||
],
|
||||
"externalReferences": [
|
||||
{
|
||||
"type": "website",
|
||||
"url": "https://pugixml.org/"
|
||||
},
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/zeux/pugixml"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
+12
-8
@@ -1,14 +1,12 @@
|
||||
/**
|
||||
* pugixml parser - version 1.12
|
||||
* pugixml parser - version 1.16
|
||||
* --------------------------------------------------------
|
||||
* Copyright (C) 2006-2022, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
|
||||
* Report bugs and download new versions at https://pugixml.org/
|
||||
*
|
||||
* This library is distributed under the MIT License. See notice at the end
|
||||
* of this file.
|
||||
* SPDX-FileCopyrightText: Copyright (C) 2006-2026, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* This work is based on the pugxml parser, which is:
|
||||
* Copyright (C) 2003, by Kristen Wegner (kristen@tima.net)
|
||||
* See LICENSE.md or notice at the end of this file.
|
||||
*/
|
||||
|
||||
#ifndef HEADER_PUGICONFIG_HPP
|
||||
@@ -17,6 +15,9 @@
|
||||
// Uncomment this to enable wchar_t mode
|
||||
// #define PUGIXML_WCHAR_MODE
|
||||
|
||||
// Uncomment this to enable from_chars/to_chars for number conversion
|
||||
// #define PUGIXML_CHARCONV_FLOAT
|
||||
|
||||
// Uncomment this to enable compact mode
|
||||
// #define PUGIXML_COMPACT
|
||||
|
||||
@@ -46,13 +47,16 @@
|
||||
// Uncomment this to switch to header-only version
|
||||
// #define PUGIXML_HEADER_ONLY
|
||||
|
||||
// Uncomment this to enable long long support
|
||||
// Uncomment this to enable long long support (usually enabled automatically)
|
||||
// #define PUGIXML_HAS_LONG_LONG
|
||||
|
||||
// Uncomment this to enable support for std::string_view (usually enabled automatically)
|
||||
// #define PUGIXML_HAS_STRING_VIEW
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Copyright (c) 2006-2022 Arseny Kapoulkine
|
||||
* Copyright (c) 2006-2026 Arseny Kapoulkine
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
|
||||
+2002
-1255
File diff suppressed because it is too large
Load Diff
+168
-65
@@ -1,20 +1,18 @@
|
||||
/**
|
||||
* pugixml parser - version 1.12
|
||||
* pugixml parser - version 1.16
|
||||
* --------------------------------------------------------
|
||||
* Copyright (C) 2006-2022, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
|
||||
* Report bugs and download new versions at https://pugixml.org/
|
||||
*
|
||||
* This library is distributed under the MIT License. See notice at the end
|
||||
* of this file.
|
||||
* SPDX-FileCopyrightText: Copyright (C) 2006-2026, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* This work is based on the pugxml parser, which is:
|
||||
* Copyright (C) 2003, by Kristen Wegner (kristen@tima.net)
|
||||
* See LICENSE.md or notice at the end of this file.
|
||||
*/
|
||||
|
||||
#ifndef PUGIXML_VERSION
|
||||
// Define version macro; evaluates to major * 1000 + minor * 10 + patch so that it's safe to use in less-than comparisons
|
||||
// Note: pugixml used major * 100 + minor * 10 + patch format up until 1.9 (which had version identifier 190); starting from pugixml 1.10, the minor version number is two digits
|
||||
# define PUGIXML_VERSION 1110
|
||||
#ifndef PUGIXML_VERSION
|
||||
# define PUGIXML_VERSION 1160 // 1.16
|
||||
#endif
|
||||
|
||||
// Include user configuration file (this can define various configuration macros)
|
||||
@@ -38,6 +36,20 @@
|
||||
# include <string>
|
||||
#endif
|
||||
|
||||
// Check if std::string_view is available
|
||||
#if !defined(PUGIXML_HAS_STRING_VIEW) && !defined(PUGIXML_NO_STL)
|
||||
# if __cplusplus >= 201703L
|
||||
# define PUGIXML_HAS_STRING_VIEW
|
||||
# elif defined(_MSVC_LANG) && _MSVC_LANG >= 201703L
|
||||
# define PUGIXML_HAS_STRING_VIEW
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Include string_view if appropriate
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
# include <string_view>
|
||||
#endif
|
||||
|
||||
// Macro for deprecated features
|
||||
#ifndef PUGIXML_DEPRECATED
|
||||
# if defined(__GNUC__)
|
||||
@@ -82,14 +94,14 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// If C++ is 2011 or higher, add 'noexcept' specifiers
|
||||
// If C++ is 2011 or higher, use 'noexcept' specifiers
|
||||
#ifndef PUGIXML_NOEXCEPT
|
||||
# if __cplusplus >= 201103
|
||||
# define PUGIXML_NOEXCEPT noexcept
|
||||
# elif defined(_MSC_VER) && _MSC_VER >= 1900
|
||||
# define PUGIXML_NOEXCEPT noexcept
|
||||
# else
|
||||
# define PUGIXML_NOEXCEPT
|
||||
# define PUGIXML_NOEXCEPT throw()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@@ -115,11 +127,22 @@
|
||||
#ifndef PUGIXML_NULL
|
||||
# if __cplusplus >= 201103
|
||||
# define PUGIXML_NULL nullptr
|
||||
# elif defined(_MSC_VER) && _MSC_VER >= 1600
|
||||
# define PUGIXML_NULL nullptr
|
||||
# else
|
||||
# define PUGIXML_NULL 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// If C++ is 2017 or higher, add 'inline' variables
|
||||
#ifndef PUGIXML_INLINE_VAR
|
||||
# ifdef __cpp_inline_variables
|
||||
# define PUGIXML_INLINE_VAR inline
|
||||
# else
|
||||
# define PUGIXML_INLINE_VAR
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// Character interface macros
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
# define PUGIXML_TEXT(t) L ## t
|
||||
@@ -136,7 +159,12 @@ namespace pugi
|
||||
|
||||
#ifndef PUGIXML_NO_STL
|
||||
// String type used for operations that work with STL string; depends on PUGIXML_WCHAR_MODE
|
||||
typedef std::basic_string<PUGIXML_CHAR, std::char_traits<PUGIXML_CHAR>, std::allocator<PUGIXML_CHAR> > string_t;
|
||||
typedef std::basic_string<PUGIXML_CHAR> string_t;
|
||||
#endif
|
||||
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
// String view type used for operations that can work with a length delimited string; depends on PUGIXML_WCHAR_MODE
|
||||
typedef std::basic_string_view<PUGIXML_CHAR> string_view_t;
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -161,65 +189,69 @@ namespace pugi
|
||||
|
||||
// Minimal parsing mode (equivalent to turning all other flags off).
|
||||
// Only elements and PCDATA sections are added to the DOM tree, no text conversions are performed.
|
||||
const unsigned int parse_minimal = 0x0000;
|
||||
PUGIXML_INLINE_VAR const unsigned int parse_minimal = 0x0000;
|
||||
|
||||
// This flag determines if processing instructions (node_pi) are added to the DOM tree. This flag is off by default.
|
||||
const unsigned int parse_pi = 0x0001;
|
||||
PUGIXML_INLINE_VAR const unsigned int parse_pi = 0x0001;
|
||||
|
||||
// This flag determines if comments (node_comment) are added to the DOM tree. This flag is off by default.
|
||||
const unsigned int parse_comments = 0x0002;
|
||||
PUGIXML_INLINE_VAR const unsigned int parse_comments = 0x0002;
|
||||
|
||||
// This flag determines if CDATA sections (node_cdata) are added to the DOM tree. This flag is on by default.
|
||||
const unsigned int parse_cdata = 0x0004;
|
||||
PUGIXML_INLINE_VAR const unsigned int parse_cdata = 0x0004;
|
||||
|
||||
// This flag determines if plain character data (node_pcdata) that consist only of whitespace are added to the DOM tree.
|
||||
// This flag is off by default; turning it on usually results in slower parsing and more memory consumption.
|
||||
const unsigned int parse_ws_pcdata = 0x0008;
|
||||
PUGIXML_INLINE_VAR const unsigned int parse_ws_pcdata = 0x0008;
|
||||
|
||||
// This flag determines if character and entity references are expanded during parsing. This flag is on by default.
|
||||
const unsigned int parse_escapes = 0x0010;
|
||||
PUGIXML_INLINE_VAR const unsigned int parse_escapes = 0x0010;
|
||||
|
||||
// This flag determines if EOL characters are normalized (converted to #xA) during parsing. This flag is on by default.
|
||||
const unsigned int parse_eol = 0x0020;
|
||||
PUGIXML_INLINE_VAR const unsigned int parse_eol = 0x0020;
|
||||
|
||||
// This flag determines if attribute values are normalized using CDATA normalization rules during parsing. This flag is on by default.
|
||||
const unsigned int parse_wconv_attribute = 0x0040;
|
||||
PUGIXML_INLINE_VAR const unsigned int parse_wconv_attribute = 0x0040;
|
||||
|
||||
// This flag determines if attribute values are normalized using NMTOKENS normalization rules during parsing. This flag is off by default.
|
||||
const unsigned int parse_wnorm_attribute = 0x0080;
|
||||
PUGIXML_INLINE_VAR const unsigned int parse_wnorm_attribute = 0x0080;
|
||||
|
||||
// This flag determines if document declaration (node_declaration) is added to the DOM tree. This flag is off by default.
|
||||
const unsigned int parse_declaration = 0x0100;
|
||||
PUGIXML_INLINE_VAR const unsigned int parse_declaration = 0x0100;
|
||||
|
||||
// This flag determines if document type declaration (node_doctype) is added to the DOM tree. This flag is off by default.
|
||||
const unsigned int parse_doctype = 0x0200;
|
||||
PUGIXML_INLINE_VAR const unsigned int parse_doctype = 0x0200;
|
||||
|
||||
// This flag determines if plain character data (node_pcdata) that is the only child of the parent node and that consists only
|
||||
// of whitespace is added to the DOM tree.
|
||||
// This flag is off by default; turning it on may result in slower parsing and more memory consumption.
|
||||
const unsigned int parse_ws_pcdata_single = 0x0400;
|
||||
PUGIXML_INLINE_VAR const unsigned int parse_ws_pcdata_single = 0x0400;
|
||||
|
||||
// This flag determines if leading and trailing whitespace is to be removed from plain character data. This flag is off by default.
|
||||
const unsigned int parse_trim_pcdata = 0x0800;
|
||||
PUGIXML_INLINE_VAR const unsigned int parse_trim_pcdata = 0x0800;
|
||||
|
||||
// This flag determines if plain character data that does not have a parent node is added to the DOM tree, and if an empty document
|
||||
// is a valid document. This flag is off by default.
|
||||
const unsigned int parse_fragment = 0x1000;
|
||||
PUGIXML_INLINE_VAR const unsigned int parse_fragment = 0x1000;
|
||||
|
||||
// This flag determines if plain character data is be stored in the parent element's value. This significantly changes the structure of
|
||||
// This flag determines if plain character data is stored in the parent element's value. This significantly changes the structure of
|
||||
// the document; this flag is only recommended for parsing documents with many PCDATA nodes in memory-constrained environments.
|
||||
// This flag is off by default.
|
||||
const unsigned int parse_embed_pcdata = 0x2000;
|
||||
PUGIXML_INLINE_VAR const unsigned int parse_embed_pcdata = 0x2000;
|
||||
|
||||
// This flag determines whether two adjacent pcdata should be merged or not, if no intermediary data are parsed in the document.
|
||||
// This flag is off by default.
|
||||
PUGIXML_INLINE_VAR const unsigned int parse_merge_pcdata = 0x4000;
|
||||
|
||||
// The default parsing mode.
|
||||
// Elements, PCDATA and CDATA sections are added to the DOM tree, character/reference entities are expanded,
|
||||
// End-of-Line characters are normalized, attribute values are normalized using CDATA normalization rules.
|
||||
const unsigned int parse_default = parse_cdata | parse_escapes | parse_wconv_attribute | parse_eol;
|
||||
PUGIXML_INLINE_VAR const unsigned int parse_default = parse_cdata | parse_escapes | parse_wconv_attribute | parse_eol;
|
||||
|
||||
// The full parsing mode.
|
||||
// Nodes of all types are added to the DOM tree, character/reference entities are expanded,
|
||||
// End-of-Line characters are normalized, attribute values are normalized using CDATA normalization rules.
|
||||
const unsigned int parse_full = parse_default | parse_pi | parse_comments | parse_declaration | parse_doctype;
|
||||
PUGIXML_INLINE_VAR const unsigned int parse_full = parse_default | parse_pi | parse_comments | parse_declaration | parse_doctype;
|
||||
|
||||
// These flags determine the encoding of input data for XML document
|
||||
enum xml_encoding
|
||||
@@ -233,47 +265,47 @@ namespace pugi
|
||||
encoding_utf32_be, // Big-endian UTF32
|
||||
encoding_utf32, // UTF32 with native endianness
|
||||
encoding_wchar, // The same encoding wchar_t has (either UTF16 or UTF32)
|
||||
encoding_latin1
|
||||
encoding_latin1 // Latin1 encoding (ISO-8859-1)
|
||||
};
|
||||
|
||||
// Formatting flags
|
||||
|
||||
// Indent the nodes that are written to output stream with as many indentation strings as deep the node is in DOM tree. This flag is on by default.
|
||||
const unsigned int format_indent = 0x01;
|
||||
PUGIXML_INLINE_VAR const unsigned int format_indent = 0x01;
|
||||
|
||||
// Write encoding-specific BOM to the output stream. This flag is off by default.
|
||||
const unsigned int format_write_bom = 0x02;
|
||||
PUGIXML_INLINE_VAR const unsigned int format_write_bom = 0x02;
|
||||
|
||||
// Use raw output mode (no indentation and no line breaks are written). This flag is off by default.
|
||||
const unsigned int format_raw = 0x04;
|
||||
PUGIXML_INLINE_VAR const unsigned int format_raw = 0x04;
|
||||
|
||||
// Omit default XML declaration even if there is no declaration in the document. This flag is off by default.
|
||||
const unsigned int format_no_declaration = 0x08;
|
||||
PUGIXML_INLINE_VAR const unsigned int format_no_declaration = 0x08;
|
||||
|
||||
// Don't escape attribute values and PCDATA contents. This flag is off by default.
|
||||
const unsigned int format_no_escapes = 0x10;
|
||||
PUGIXML_INLINE_VAR const unsigned int format_no_escapes = 0x10;
|
||||
|
||||
// Open file using text mode in xml_document::save_file. This enables special character (i.e. new-line) conversions on some systems. This flag is off by default.
|
||||
const unsigned int format_save_file_text = 0x20;
|
||||
PUGIXML_INLINE_VAR const unsigned int format_save_file_text = 0x20;
|
||||
|
||||
// Write every attribute on a new line with appropriate indentation. This flag is off by default.
|
||||
const unsigned int format_indent_attributes = 0x40;
|
||||
PUGIXML_INLINE_VAR const unsigned int format_indent_attributes = 0x40;
|
||||
|
||||
// Don't output empty element tags, instead writing an explicit start and end tag even if there are no children. This flag is off by default.
|
||||
const unsigned int format_no_empty_element_tags = 0x80;
|
||||
PUGIXML_INLINE_VAR const unsigned int format_no_empty_element_tags = 0x80;
|
||||
|
||||
// Skip characters belonging to range [0; 32) instead of "&#xNN;" encoding. This flag is off by default.
|
||||
const unsigned int format_skip_control_chars = 0x100;
|
||||
PUGIXML_INLINE_VAR const unsigned int format_skip_control_chars = 0x100;
|
||||
|
||||
// Use single quotes ' instead of double quotes " for enclosing attribute values. This flag is off by default.
|
||||
const unsigned int format_attribute_single_quote = 0x200;
|
||||
PUGIXML_INLINE_VAR const unsigned int format_attribute_single_quote = 0x200;
|
||||
|
||||
// The default set of formatting flags.
|
||||
// Nodes are indented depending on their depth in DOM tree, a default declaration is output if document has none.
|
||||
const unsigned int format_default = format_indent;
|
||||
PUGIXML_INLINE_VAR const unsigned int format_default = format_indent;
|
||||
|
||||
const int default_double_precision = 17;
|
||||
const int default_float_precision = 9;
|
||||
PUGIXML_INLINE_VAR const int default_double_precision = 17;
|
||||
PUGIXML_INLINE_VAR const int default_float_precision = 9;
|
||||
|
||||
// Forward declarations
|
||||
struct xml_attribute_struct;
|
||||
@@ -322,7 +354,7 @@ namespace pugi
|
||||
class PUGIXML_CLASS xml_writer
|
||||
{
|
||||
public:
|
||||
virtual ~xml_writer() {}
|
||||
virtual ~xml_writer();
|
||||
|
||||
// Write memory chunk into stream/file/whatever
|
||||
virtual void write(const void* data, size_t size) = 0;
|
||||
@@ -347,14 +379,14 @@ namespace pugi
|
||||
{
|
||||
public:
|
||||
// Construct writer from an output stream object
|
||||
xml_writer_stream(std::basic_ostream<char, std::char_traits<char> >& stream);
|
||||
xml_writer_stream(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >& stream);
|
||||
xml_writer_stream(std::basic_ostream<char>& stream);
|
||||
xml_writer_stream(std::basic_ostream<wchar_t>& stream);
|
||||
|
||||
virtual void write(const void* data, size_t size) PUGIXML_OVERRIDE;
|
||||
|
||||
private:
|
||||
std::basic_ostream<char, std::char_traits<char> >* narrow_stream;
|
||||
std::basic_ostream<wchar_t, std::char_traits<wchar_t> >* wide_stream;
|
||||
std::basic_ostream<char>* narrow_stream;
|
||||
std::basic_ostream<wchar_t>* wide_stream;
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -390,7 +422,7 @@ namespace pugi
|
||||
bool operator<=(const xml_attribute& r) const;
|
||||
bool operator>=(const xml_attribute& r) const;
|
||||
|
||||
// Check if attribute is empty
|
||||
// Check if attribute is empty (null)
|
||||
bool empty() const;
|
||||
|
||||
// Get attribute name/value, or "" if attribute is empty
|
||||
@@ -416,7 +448,15 @@ namespace pugi
|
||||
|
||||
// Set attribute name/value (returns false if attribute is empty or there is not enough memory)
|
||||
bool set_name(const char_t* rhs);
|
||||
bool set_name(const char_t* rhs, size_t size);
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
bool set_name(string_view_t rhs);
|
||||
#endif
|
||||
bool set_value(const char_t* rhs);
|
||||
bool set_value(const char_t* rhs, size_t size);
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
bool set_value(string_view_t rhs);
|
||||
#endif
|
||||
|
||||
// Set attribute value with type conversion (numbers are converted to strings, boolean is converted to "true"/"false")
|
||||
bool set_value(int rhs);
|
||||
@@ -444,6 +484,10 @@ namespace pugi
|
||||
xml_attribute& operator=(float rhs);
|
||||
xml_attribute& operator=(bool rhs);
|
||||
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
xml_attribute& operator=(string_view_t rhs);
|
||||
#endif
|
||||
|
||||
#ifdef PUGIXML_HAS_LONG_LONG
|
||||
xml_attribute& operator=(long long rhs);
|
||||
xml_attribute& operator=(unsigned long long rhs);
|
||||
@@ -499,7 +543,7 @@ namespace pugi
|
||||
bool operator<=(const xml_node& r) const;
|
||||
bool operator>=(const xml_node& r) const;
|
||||
|
||||
// Check if node is empty.
|
||||
// Check if node is empty (null)
|
||||
bool empty() const;
|
||||
|
||||
// Get node type
|
||||
@@ -538,9 +582,18 @@ namespace pugi
|
||||
xml_attribute attribute(const char_t* name) const;
|
||||
xml_node next_sibling(const char_t* name) const;
|
||||
xml_node previous_sibling(const char_t* name) const;
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
xml_node child(string_view_t name) const;
|
||||
xml_attribute attribute(string_view_t name) const;
|
||||
xml_node next_sibling(string_view_t name) const;
|
||||
xml_node previous_sibling(string_view_t name) const;
|
||||
#endif
|
||||
|
||||
// Get attribute, starting the search from a hint (and updating hint so that searching for a sequence of attributes is fast)
|
||||
xml_attribute attribute(const char_t* name, xml_attribute& hint) const;
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
xml_attribute attribute(string_view_t name, xml_attribute& hint) const;
|
||||
#endif
|
||||
|
||||
// Get child value of current node; that is, value of the first child node of type PCDATA/CDATA
|
||||
const char_t* child_value() const;
|
||||
@@ -550,13 +603,33 @@ namespace pugi
|
||||
|
||||
// Set node name/value (returns false if node is empty, there is not enough memory, or node can not have name/value)
|
||||
bool set_name(const char_t* rhs);
|
||||
bool set_name(const char_t* rhs, size_t size);
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
bool set_name(string_view_t rhs);
|
||||
#endif
|
||||
bool set_value(const char_t* rhs);
|
||||
bool set_value(const char_t* rhs, size_t size);
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
bool set_value(string_view_t rhs);
|
||||
#endif
|
||||
|
||||
// Add attribute with specified name. Returns added attribute, or empty attribute on errors.
|
||||
xml_attribute append_attribute(const char_t* name);
|
||||
xml_attribute prepend_attribute(const char_t* name);
|
||||
xml_attribute insert_attribute_after(const char_t* name, const xml_attribute& attr);
|
||||
xml_attribute insert_attribute_before(const char_t* name, const xml_attribute& attr);
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
xml_attribute append_attribute(string_view_t name);
|
||||
xml_attribute prepend_attribute(string_view_t name);
|
||||
xml_attribute insert_attribute_after(string_view_t name, const xml_attribute& attr);
|
||||
xml_attribute insert_attribute_before(string_view_t name, const xml_attribute& attr);
|
||||
#endif
|
||||
|
||||
// Get attribute with specified name, adding one if it does not exist. Returns the existing or added attribute, or empty attribute on errors.
|
||||
xml_attribute ensure_attribute(const char_t* name);
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
xml_attribute ensure_attribute(string_view_t name);
|
||||
#endif
|
||||
|
||||
// Add a copy of the specified attribute. Returns added attribute, or empty attribute on errors.
|
||||
xml_attribute append_copy(const xml_attribute& proto);
|
||||
@@ -575,6 +648,18 @@ namespace pugi
|
||||
xml_node prepend_child(const char_t* name);
|
||||
xml_node insert_child_after(const char_t* name, const xml_node& node);
|
||||
xml_node insert_child_before(const char_t* name, const xml_node& node);
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
xml_node append_child(string_view_t name);
|
||||
xml_node prepend_child(string_view_t name);
|
||||
xml_node insert_child_after(string_view_t name, const xml_node& node);
|
||||
xml_node insert_child_before(string_view_t name, const xml_node& node);
|
||||
#endif
|
||||
|
||||
// Get child with specified name, adding one if it does not exist. Returns the existing or added node, or empty node on errors.
|
||||
xml_node ensure_child(const char_t* name);
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
xml_node ensure_child(string_view_t name);
|
||||
#endif
|
||||
|
||||
// Add a copy of the specified node as a child. Returns added node, or empty node on errors.
|
||||
xml_node append_copy(const xml_node& proto);
|
||||
@@ -591,6 +676,9 @@ namespace pugi
|
||||
// Remove specified attribute
|
||||
bool remove_attribute(const xml_attribute& a);
|
||||
bool remove_attribute(const char_t* name);
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
bool remove_attribute(string_view_t name);
|
||||
#endif
|
||||
|
||||
// Remove all attributes
|
||||
bool remove_attributes();
|
||||
@@ -598,6 +686,9 @@ namespace pugi
|
||||
// Remove specified child
|
||||
bool remove_child(const xml_node& n);
|
||||
bool remove_child(const char_t* name);
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
bool remove_child(string_view_t name);
|
||||
#endif
|
||||
|
||||
// Remove all children
|
||||
bool remove_children();
|
||||
@@ -690,8 +781,8 @@ namespace pugi
|
||||
|
||||
#ifndef PUGIXML_NO_STL
|
||||
// Print subtree to stream
|
||||
void print(std::basic_ostream<char, std::char_traits<char> >& os, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto, unsigned int depth = 0) const;
|
||||
void print(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >& os, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, unsigned int depth = 0) const;
|
||||
void print(std::basic_ostream<char>& os, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto, unsigned int depth = 0) const;
|
||||
void print(std::basic_ostream<wchar_t>& os, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, unsigned int depth = 0) const;
|
||||
#endif
|
||||
|
||||
// Child nodes iterators
|
||||
@@ -708,9 +799,12 @@ namespace pugi
|
||||
|
||||
// Range-based for support
|
||||
xml_object_range<xml_node_iterator> children() const;
|
||||
xml_object_range<xml_named_node_iterator> children(const char_t* name) const;
|
||||
xml_object_range<xml_attribute_iterator> attributes() const;
|
||||
|
||||
// Range-based for support for all children with the specified name
|
||||
// Note: name pointer must have a longer lifetime than the returned object; be careful with passing temporaries!
|
||||
xml_object_range<xml_named_node_iterator> children(const char_t* name) const;
|
||||
|
||||
// Get node offset in parsed file/string (in char_t units) for debugging purposes
|
||||
ptrdiff_t offset_debug() const;
|
||||
|
||||
@@ -751,7 +845,7 @@ namespace pugi
|
||||
// Borland C++ workaround
|
||||
bool operator!() const;
|
||||
|
||||
// Check if text object is empty
|
||||
// Check if text object is empty (null)
|
||||
bool empty() const;
|
||||
|
||||
// Get text, or "" if object is empty
|
||||
@@ -776,6 +870,10 @@ namespace pugi
|
||||
|
||||
// Set text (returns false if object is empty or there is not enough memory)
|
||||
bool set(const char_t* rhs);
|
||||
bool set(const char_t* rhs, size_t size);
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
bool set(string_view_t rhs);
|
||||
#endif
|
||||
|
||||
// Set text with type conversion (numbers are converted to strings, boolean is converted to "true"/"false")
|
||||
bool set(int rhs);
|
||||
@@ -803,6 +901,10 @@ namespace pugi
|
||||
xml_text& operator=(float rhs);
|
||||
xml_text& operator=(bool rhs);
|
||||
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
xml_text& operator=(string_view_t rhs);
|
||||
#endif
|
||||
|
||||
#ifdef PUGIXML_HAS_LONG_LONG
|
||||
xml_text& operator=(long long rhs);
|
||||
xml_text& operator=(unsigned long long rhs);
|
||||
@@ -922,6 +1024,7 @@ namespace pugi
|
||||
xml_named_node_iterator();
|
||||
|
||||
// Construct an iterator which points to the specified node
|
||||
// Note: name pointer is stored in the iterator and must have a longer lifetime than iterator itself
|
||||
xml_named_node_iterator(const xml_node& node, const char_t* name);
|
||||
|
||||
// Iterator operators
|
||||
@@ -1057,8 +1160,8 @@ namespace pugi
|
||||
|
||||
#ifndef PUGIXML_NO_STL
|
||||
// Load document from stream.
|
||||
xml_parse_result load(std::basic_istream<char, std::char_traits<char> >& stream, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
|
||||
xml_parse_result load(std::basic_istream<wchar_t, std::char_traits<wchar_t> >& stream, unsigned int options = parse_default);
|
||||
xml_parse_result load(std::basic_istream<char>& stream, unsigned int options = parse_default, xml_encoding encoding = encoding_auto);
|
||||
xml_parse_result load(std::basic_istream<wchar_t>& stream, unsigned int options = parse_default);
|
||||
#endif
|
||||
|
||||
// (deprecated: use load_string instead) Load document from zero-terminated string. No encoding conversions are applied.
|
||||
@@ -1087,8 +1190,8 @@ namespace pugi
|
||||
|
||||
#ifndef PUGIXML_NO_STL
|
||||
// Save XML document to stream (semantics is slightly different from xml_node::print, see documentation for details).
|
||||
void save(std::basic_ostream<char, std::char_traits<char> >& stream, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const;
|
||||
void save(std::basic_ostream<wchar_t, std::char_traits<wchar_t> >& stream, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default) const;
|
||||
void save(std::basic_ostream<char>& stream, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default, xml_encoding encoding = encoding_auto) const;
|
||||
void save(std::basic_ostream<wchar_t>& stream, const char_t* indent = PUGIXML_TEXT("\t"), unsigned int flags = format_default) const;
|
||||
#endif
|
||||
|
||||
// Save XML to file
|
||||
@@ -1257,7 +1360,7 @@ namespace pugi
|
||||
// Evaluate expression as string value in the specified context; performs type conversion if necessary.
|
||||
// At most capacity characters are written to the destination buffer, full result size is returned (includes terminating zero).
|
||||
// If PUGIXML_NO_EXCEPTIONS is not defined, throws std::bad_alloc on out of memory errors.
|
||||
// If PUGIXML_NO_EXCEPTIONS is defined, returns empty set instead.
|
||||
// If PUGIXML_NO_EXCEPTIONS is defined, returns empty string instead.
|
||||
size_t evaluate_string(char_t* buffer, size_t capacity, const xpath_node& n) const;
|
||||
|
||||
// Evaluate expression as node set in the specified context.
|
||||
@@ -1299,7 +1402,7 @@ namespace pugi
|
||||
explicit xpath_exception(const xpath_parse_result& result);
|
||||
|
||||
// Get error message
|
||||
virtual const char* what() const throw() PUGIXML_OVERRIDE;
|
||||
virtual const char* what() const PUGIXML_NOEXCEPT PUGIXML_OVERRIDE;
|
||||
|
||||
// Get parse result
|
||||
const xpath_parse_result& result() const;
|
||||
@@ -1424,12 +1527,12 @@ namespace pugi
|
||||
|
||||
#ifndef PUGIXML_NO_STL
|
||||
// Convert wide string to UTF8
|
||||
std::basic_string<char, std::char_traits<char>, std::allocator<char> > PUGIXML_FUNCTION as_utf8(const wchar_t* str);
|
||||
std::basic_string<char, std::char_traits<char>, std::allocator<char> > PUGIXML_FUNCTION as_utf8(const std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> >& str);
|
||||
std::basic_string<char> PUGIXML_FUNCTION as_utf8(const wchar_t* str);
|
||||
std::basic_string<char> PUGIXML_FUNCTION as_utf8(const std::basic_string<wchar_t>& str);
|
||||
|
||||
// Convert UTF8 to wide string
|
||||
std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > PUGIXML_FUNCTION as_wide(const char* str);
|
||||
std::basic_string<wchar_t, std::char_traits<wchar_t>, std::allocator<wchar_t> > PUGIXML_FUNCTION as_wide(const std::basic_string<char, std::char_traits<char>, std::allocator<char> >& str);
|
||||
std::basic_string<wchar_t> PUGIXML_FUNCTION as_wide(const char* str);
|
||||
std::basic_string<wchar_t> PUGIXML_FUNCTION as_wide(const std::basic_string<char>& str);
|
||||
#endif
|
||||
|
||||
// Memory allocation function interface; returns pointer to allocated memory or NULL on failure
|
||||
@@ -1476,7 +1579,7 @@ namespace std
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Copyright (c) 2006-2022 Arseny Kapoulkine
|
||||
* Copyright (c) 2006-2026 Arseny Kapoulkine
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person
|
||||
* obtaining a copy of this software and associated documentation
|
||||
|
||||
@@ -12,9 +12,9 @@ function Invoke-CmdScript($scriptName)
|
||||
$sources = @("src/pugixml.cpp") + (Get-ChildItem -Path "tests/*.cpp" -Exclude "fuzz_*.cpp")
|
||||
$failed = $FALSE
|
||||
|
||||
foreach ($vs in $args)
|
||||
foreach ($vs in @($args[0]))
|
||||
{
|
||||
foreach ($arch in "x86","x64")
|
||||
foreach ($arch in @($args[1]))
|
||||
{
|
||||
Write-Output "# Setting up VS$vs $arch"
|
||||
|
||||
@@ -30,6 +30,10 @@ foreach ($vs in $args)
|
||||
$vsdevcmdarch = if ($arch -eq "x64") { "amd64" } else { "x86" }
|
||||
Invoke-CmdScript "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\Tools\VsDevCmd.bat" "-arch=$vsdevcmdarch"
|
||||
}
|
||||
elseif ($vs -eq 26) {
|
||||
$vsdevcmdarch = if ($arch -eq "x64") { "amd64" } else { "x86" }
|
||||
Invoke-CmdScript "C:\Program Files\Microsoft Visual Studio\18\Community\Common7\Tools\VsDevCmd.bat" "-arch=$vsdevcmdarch"
|
||||
}
|
||||
else
|
||||
{
|
||||
Invoke-CmdScript "C:\Program Files (x86)\Microsoft Visual Studio $vs.0\VC\vcvarsall.bat" $arch
|
||||
@@ -37,7 +41,9 @@ foreach ($vs in $args)
|
||||
|
||||
if (! $?) { throw "Error setting up VS$vs $arch" }
|
||||
|
||||
foreach ($defines in "standard", "PUGIXML_WCHAR_MODE", "PUGIXML_COMPACT")
|
||||
$cxx = if ($vs -ge 19) { "/std:c++17" } else { "" }
|
||||
|
||||
foreach ($defines in @($args[2]))
|
||||
{
|
||||
$target = "tests_vs${vs}_${arch}_${defines}"
|
||||
$deflist = if ($defines -eq "standard") { "" } else { "/D$defines" }
|
||||
@@ -45,7 +51,7 @@ foreach ($vs in $args)
|
||||
Add-AppveyorTest $target -Outcome Running
|
||||
|
||||
Write-Output "# Building $target.exe"
|
||||
& cmd /c "cl.exe /Fe$target.exe /EHsc /W4 /WX $deflist $sources 2>&1" | Tee-Object -Variable buildOutput
|
||||
& cmd /c "cl.exe /MP /Fe$target.exe /EHsc /W4 /WX $cxx $deflist $sources 2>&1" | Tee-Object -Variable buildOutput
|
||||
|
||||
if ($?)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
$failed = $FALSE
|
||||
|
||||
$vs = $args[0]
|
||||
$vsy = $args[1]
|
||||
|
||||
$target = "cmake_vs${vs}_${vsy}"
|
||||
|
||||
Add-AppveyorTest $target -Outcome Running
|
||||
|
||||
mkdir $target
|
||||
pushd $target
|
||||
|
||||
try
|
||||
{
|
||||
Write-Output "# Setting up CMake VS$vs"
|
||||
& cmake .. -G "Visual Studio $vs $vsy" | Tee-Object -Variable cmakeOutput
|
||||
|
||||
$sw = [Diagnostics.Stopwatch]::StartNew()
|
||||
|
||||
if ($?)
|
||||
{
|
||||
Write-Output "# Building"
|
||||
|
||||
& cmake --build . | Tee-Object -Variable cmakeOutput
|
||||
|
||||
if ($?)
|
||||
{
|
||||
Write-Output "# Passed"
|
||||
|
||||
Update-AppveyorTest $target -Outcome Passed -StdOut ($cmakeOutput | out-string) -Duration $sw.ElapsedMilliseconds
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Output "# Failed to build"
|
||||
|
||||
Update-AppveyorTest $target -Outcome Failed -StdOut ($cmakeOutput | out-string) -ErrorMessage "Building failed"
|
||||
|
||||
$failed = $TRUE
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Output "# Failed to configure"
|
||||
|
||||
Update-AppveyorTest $target -Outcome Failed -StdOut ($cmakeOutput | out-string) -ErrorMessage "Configuration failed"
|
||||
|
||||
$failed = $TRUE
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
popd
|
||||
}
|
||||
|
||||
if ($failed) { throw "One or more build steps failed" }
|
||||
|
||||
Write-Output "# End"
|
||||
+30
-10
@@ -1,26 +1,46 @@
|
||||
#include "../src/pugixml.hpp"
|
||||
#include "fuzzer/FuzzedDataProvider.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size)
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* Data, size_t Size)
|
||||
{
|
||||
char* text = new char[Size + 1];
|
||||
memcpy(text, Data, Size);
|
||||
text[Size] = 0;
|
||||
FuzzedDataProvider fdp(Data, Size);
|
||||
std::string text = fdp.ConsumeRandomLengthString(1024);
|
||||
|
||||
#ifdef PUGIXML_NO_EXCEPTIONS
|
||||
pugi::xpath_query q(text);
|
||||
#else
|
||||
#ifndef PUGIXML_NO_EXCEPTIONS
|
||||
try
|
||||
#endif
|
||||
{
|
||||
pugi::xpath_query q(text);
|
||||
pugi::xpath_variable_set vars;
|
||||
size_t var_count = fdp.ConsumeIntegralInRange<size_t>(0, 50);
|
||||
std::vector<std::string> var_name_storage;
|
||||
for (size_t i = 0; i < var_count; ++i)
|
||||
{
|
||||
var_name_storage.push_back(fdp.ConsumeRandomLengthString(128));
|
||||
|
||||
const int xpath_value_type_count = pugi::xpath_type_boolean + 1;
|
||||
pugi::xpath_value_type value_type = static_cast<pugi::xpath_value_type>(fdp.ConsumeIntegralInRange(0, xpath_value_type_count));
|
||||
vars.add(var_name_storage.back().c_str(), value_type);
|
||||
}
|
||||
pugi::xpath_query q(text.c_str(), &vars);
|
||||
|
||||
std::vector<uint8_t> xml_buffer = fdp.ConsumeBytes<uint8_t>(fdp.ConsumeIntegralInRange(0, 1024));
|
||||
pugi::xml_document doc;
|
||||
doc.load_buffer(xml_buffer.data(), xml_buffer.size(), pugi::parse_full);
|
||||
|
||||
q.evaluate_boolean(doc);
|
||||
q.evaluate_number(doc);
|
||||
q.evaluate_string(doc);
|
||||
q.evaluate_node(doc);
|
||||
q.evaluate_node_set(doc);
|
||||
}
|
||||
#ifndef PUGIXML_NO_EXCEPTIONS
|
||||
catch (pugi::xpath_exception&)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
delete[] text;
|
||||
return 0;
|
||||
}
|
||||
|
||||
+92
-1
@@ -473,6 +473,17 @@ TEST(document_load_string)
|
||||
CHECK_NODE(doc, STR("<node/>"));
|
||||
}
|
||||
|
||||
TEST(document_load_string_empty)
|
||||
{
|
||||
xml_document doc;
|
||||
|
||||
CHECK(doc.load_string(STR("")).status == status_no_document_element);
|
||||
CHECK(!doc.first_child());
|
||||
|
||||
CHECK(doc.load_string(STR(""), parse_fragment));
|
||||
CHECK(!doc.first_child());
|
||||
}
|
||||
|
||||
TEST(document_load_file)
|
||||
{
|
||||
xml_document doc;
|
||||
@@ -589,7 +600,7 @@ TEST(document_load_file_wide_out_of_memory)
|
||||
CHECK(result.status == status_out_of_memory || result.status == status_file_not_found);
|
||||
}
|
||||
|
||||
#if defined(__APPLE__)
|
||||
#if defined(__linux__) || defined(__APPLE__)
|
||||
TEST(document_load_file_special_folder)
|
||||
{
|
||||
xml_document doc;
|
||||
@@ -605,6 +616,13 @@ TEST(document_load_file_special_device)
|
||||
xml_parse_result result = doc.load_file("/dev/tty");
|
||||
CHECK(result.status == status_file_not_found || result.status == status_io_error);
|
||||
}
|
||||
|
||||
TEST(document_load_file_special_sysfs)
|
||||
{
|
||||
xml_document doc;
|
||||
xml_parse_result result = doc.load_file("/sys/kernel/fscaps");
|
||||
CHECK(result.status == status_file_not_found || result.status == status_io_error);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_XML(document_save, "<node/>")
|
||||
@@ -736,7 +754,12 @@ struct temp_file
|
||||
temp_file()
|
||||
{
|
||||
static int index = 0;
|
||||
|
||||
#if __cplusplus >= 201103 || defined(__APPLE__) // Xcode 14 warns about use of sprintf in C++98 builds
|
||||
snprintf(path, sizeof(path), "%stempfile%d", test_runner::_temp_path, index++);
|
||||
#else
|
||||
sprintf(path, "%stempfile%d", test_runner::_temp_path, index++);
|
||||
#endif
|
||||
}
|
||||
|
||||
~temp_file()
|
||||
@@ -859,6 +882,19 @@ TEST(document_load_buffer_inplace_own)
|
||||
CHECK_NODE(doc, STR("<node/>"));
|
||||
}
|
||||
|
||||
TEST(document_load_buffer_inplace_own_empty)
|
||||
{
|
||||
allocation_function alloc = get_memory_allocation_function();
|
||||
|
||||
void* text1 = alloc(1);
|
||||
void* text2 = alloc(1);
|
||||
CHECK(text1 && text2);
|
||||
|
||||
xml_document doc;
|
||||
CHECK(doc.load_buffer_inplace_own(text1, 0, parse_fragment));
|
||||
CHECK(doc.load_buffer_inplace_own(text2, 0).status == status_no_document_element);
|
||||
}
|
||||
|
||||
TEST(document_parse_result_bool)
|
||||
{
|
||||
xml_parse_result result;
|
||||
@@ -1282,6 +1318,15 @@ TEST(document_load_buffer_empty_fragment)
|
||||
}
|
||||
}
|
||||
|
||||
TEST(document_load_buffer_empty_encoding)
|
||||
{
|
||||
xml_document doc;
|
||||
xml_parse_result result = doc.load_buffer(0, 0, parse_fragment);
|
||||
|
||||
CHECK(result.status == status_ok);
|
||||
CHECK(result.encoding == encoding_utf8);
|
||||
}
|
||||
|
||||
TEST(document_load_buffer_null)
|
||||
{
|
||||
xml_document doc;
|
||||
@@ -1817,3 +1862,49 @@ TEST(document_move_assign_empty)
|
||||
CHECK_NODE(doc, STR("<node2/>"));
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(document_load_buffer_convert_out_of_memory)
|
||||
{
|
||||
const char* source = "<node>\xe7</node>";
|
||||
size_t size = strlen(source);
|
||||
|
||||
test_runner::_memory_fail_threshold = 1;
|
||||
|
||||
xml_document doc;
|
||||
|
||||
xml_parse_result result;
|
||||
result.status = status_out_of_memory;
|
||||
CHECK_ALLOC_FAIL(result = doc.load_buffer(source, size, pugi::parse_default, pugi::encoding_latin1));
|
||||
|
||||
CHECK(result.status == status_out_of_memory);
|
||||
}
|
||||
|
||||
TEST(document_load_buffer_own_convert_out_of_memory)
|
||||
{
|
||||
const char* source = "<node>\xe7</node>";
|
||||
size_t size = strlen(source);
|
||||
|
||||
void* buffer = pugi::get_memory_allocation_function()(size);
|
||||
CHECK(buffer);
|
||||
memcpy(buffer, source, size);
|
||||
|
||||
test_runner::_memory_fail_threshold = 1;
|
||||
|
||||
xml_document doc;
|
||||
|
||||
xml_parse_result result;
|
||||
result.status = status_out_of_memory;
|
||||
CHECK_ALLOC_FAIL(result = doc.load_buffer_inplace_own(buffer, size, pugi::parse_default, pugi::encoding_latin1));
|
||||
|
||||
CHECK(result.status == status_out_of_memory);
|
||||
}
|
||||
|
||||
TEST(document_load_buffer_wide_truncated)
|
||||
{
|
||||
xml_document doc;
|
||||
|
||||
char buf[1] = {};
|
||||
CHECK(doc.load_buffer_inplace(buf, 1, parse_default, encoding_wchar).status == status_no_document_element);
|
||||
CHECK(doc.load_buffer_inplace(buf, 1, parse_fragment, encoding_wchar).status == status_ok);
|
||||
CHECK(!doc.first_child());
|
||||
}
|
||||
|
||||
+287
-10
@@ -33,7 +33,13 @@ TEST_XML(dom_attr_assign, "<node/>")
|
||||
node.append_attribute(STR("attr8")) = true;
|
||||
xml_attribute() = true;
|
||||
|
||||
CHECK_NODE(node, STR("<node attr1=\"v1\" attr2=\"-2147483647\" attr3=\"-2147483648\" attr4=\"4294967295\" attr5=\"4294967294\" attr6=\"0.5\" attr7=\"0.25\" attr8=\"true\"/>"));
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
node.append_attribute(string_view_t(STR("attr9"))) = string_view_t(STR("v2"));
|
||||
#else
|
||||
node.append_attribute(STR("attr9")) = STR("v2");
|
||||
#endif
|
||||
|
||||
CHECK_NODE(node, STR("<node attr1=\"v1\" attr2=\"-2147483647\" attr3=\"-2147483648\" attr4=\"4294967295\" attr5=\"4294967294\" attr6=\"0.5\" attr7=\"0.25\" attr8=\"true\" attr9=\"v2\"/>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_attr_set_name, "<node attr='value' />")
|
||||
@@ -46,6 +52,33 @@ TEST_XML(dom_attr_set_name, "<node attr='value' />")
|
||||
CHECK_NODE(doc, STR("<node n=\"value\"/>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_attr_set_name_with_size, "<node attr='value' />")
|
||||
{
|
||||
xml_attribute attr = doc.child(STR("node")).attribute(STR("attr"));
|
||||
|
||||
CHECK(attr.set_name(STR("n1234"), 1));
|
||||
CHECK(!xml_attribute().set_name(STR("nfail"), 1));
|
||||
|
||||
CHECK_NODE(doc, STR("<node n=\"value\"/>"));
|
||||
}
|
||||
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
TEST_XML(dom_attr_set_name_with_string_view, "<node attr='value' />")
|
||||
{
|
||||
xml_attribute attr = doc.child(STR("node")).attribute(STR("attr"));
|
||||
|
||||
CHECK(attr.set_name(string_view_t()));
|
||||
CHECK(!xml_attribute().set_name(string_view_t()));
|
||||
|
||||
CHECK_NODE(doc, STR("<node :anonymous=\"value\"/>"));
|
||||
|
||||
CHECK(attr.set_name(string_view_t(STR("n1234"), 1)));
|
||||
CHECK(!xml_attribute().set_name(string_view_t(STR("nfail"), 1)));
|
||||
|
||||
CHECK_NODE(doc, STR("<node n=\"value\"/>"));
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_XML(dom_attr_set_value, "<node/>")
|
||||
{
|
||||
xml_node node = doc.child(STR("node"));
|
||||
@@ -70,7 +103,20 @@ TEST_XML(dom_attr_set_value, "<node/>")
|
||||
CHECK(node.append_attribute(STR("attr8")).set_value(true));
|
||||
CHECK(!xml_attribute().set_value(true));
|
||||
|
||||
CHECK_NODE(node, STR("<node attr1=\"v1\" attr2=\"-2147483647\" attr3=\"-2147483648\" attr4=\"4294967295\" attr5=\"4294967294\" attr6=\"0.5\" attr7=\"0.25\" attr8=\"true\"/>"));
|
||||
CHECK(node.append_attribute(STR("attr9")).set_value(STR("v2"), 2));
|
||||
CHECK(!xml_attribute().set_value(STR("v2")));
|
||||
|
||||
CHECK(node.append_attribute(STR("attr10")).set_value(STR("v3foobar"), 2));
|
||||
CHECK(!xml_attribute().set_value(STR("v3")));
|
||||
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
CHECK(node.append_attribute(string_view_t(STR("attr11"))).set_value(string_view_t(STR("v4"))));
|
||||
CHECK(!xml_attribute().set_value(string_view_t(STR("v4"))));
|
||||
#else
|
||||
CHECK(node.append_attribute(STR("attr11")).set_value(STR("v4")));
|
||||
#endif
|
||||
|
||||
CHECK_NODE(node, STR("<node attr1=\"v1\" attr2=\"-2147483647\" attr3=\"-2147483648\" attr4=\"4294967295\" attr5=\"4294967294\" attr6=\"0.5\" attr7=\"0.25\" attr8=\"true\" attr9=\"v2\" attr10=\"v3\" attr11=\"v4\"/>"));
|
||||
}
|
||||
|
||||
#if LONG_MAX > 2147483647
|
||||
@@ -200,6 +246,34 @@ TEST_XML(dom_node_set_name, "<node>text</node>")
|
||||
CHECK_NODE(doc, STR("<n>text</n>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_set_name_with_size, "<node>text</node>")
|
||||
{
|
||||
CHECK(doc.child(STR("node")).set_name(STR("nlongname"), 1));
|
||||
CHECK(!doc.child(STR("node")).first_child().set_name(STR("n42"), 1));
|
||||
CHECK(!xml_node().set_name(STR("nanothername"), 1));
|
||||
|
||||
CHECK_NODE(doc, STR("<n>text</n>"));
|
||||
}
|
||||
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
TEST_XML(dom_node_set_name_with_string_view, "<node>text</node>")
|
||||
{
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
CHECK(node.set_name(string_view_t()));
|
||||
CHECK(!node.first_child().set_name(string_view_t(STR("n42"), 1)));
|
||||
CHECK(!xml_node().set_name(string_view_t(STR("nanothername"), 1)));
|
||||
|
||||
CHECK_NODE(doc, STR("<:anonymous>text</:anonymous>"));
|
||||
|
||||
CHECK(node.set_name(string_view_t(STR("nlongname"), 1)));
|
||||
CHECK(!doc.child(STR("node")).first_child().set_name(string_view_t(STR("n42"), 1)));
|
||||
CHECK(!xml_node().set_name(string_view_t(STR("nanothername"), 1)));
|
||||
|
||||
CHECK_NODE(doc, STR("<n>text</n>"));
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_XML(dom_node_set_value, "<node>text</node>")
|
||||
{
|
||||
CHECK(doc.child(STR("node")).first_child().set_value(STR("no text")));
|
||||
@@ -209,6 +283,44 @@ TEST_XML(dom_node_set_value, "<node>text</node>")
|
||||
CHECK_NODE(doc, STR("<node>no text</node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_set_value_partially_with_size, "<node>text</node>")
|
||||
{
|
||||
CHECK(doc.child(STR("node")).first_child().set_value(STR("no text"), 2));
|
||||
CHECK(!doc.child(STR("node")).set_value(STR("no text"), 2));
|
||||
CHECK(!xml_node().set_value(STR("no text"), 2));
|
||||
|
||||
CHECK_NODE(doc, STR("<node>no</node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_set_value_with_size, "<node>text</node>")
|
||||
{
|
||||
CHECK(doc.child(STR("node")).first_child().set_value(STR("no text"), 7));
|
||||
CHECK(!doc.child(STR("node")).set_value(STR("no text"), 7));
|
||||
CHECK(!xml_node().set_value(STR("no text"), 7));
|
||||
|
||||
CHECK_NODE(doc, STR("<node>no text</node>"));
|
||||
}
|
||||
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
TEST_XML(dom_node_set_value_partially_with_string_view, "<node>text</node>")
|
||||
{
|
||||
CHECK(doc.child(STR("node")).first_child().set_value(string_view_t(STR("no text"), 2)));
|
||||
CHECK(!doc.child(STR("node")).set_value(string_view_t(STR("no text"), 2)));
|
||||
CHECK(!xml_node().set_value(string_view_t(STR("no text"), 2)));
|
||||
|
||||
CHECK_NODE(doc, STR("<node>no</node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_set_value_with_string_view, "<node>text</node>")
|
||||
{
|
||||
CHECK(doc.child(STR("node")).first_child().set_value(string_view_t(STR("no text"), 7)));
|
||||
CHECK(!doc.child(STR("node")).set_value(string_view_t(STR("no text"), 7)));
|
||||
CHECK(!xml_node().set_value(string_view_t(STR("no text"), 7)));
|
||||
|
||||
CHECK_NODE(doc, STR("<node>no text</node>"));
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_XML(dom_node_set_value_allocated, "<node>text</node>")
|
||||
{
|
||||
CHECK(doc.child(STR("node")).first_child().set_value(STR("no text")));
|
||||
@@ -236,7 +348,15 @@ TEST_XML(dom_node_prepend_attribute, "<node><child/></node>")
|
||||
CHECK(a3 && a1 != a3 && a2 != a3);
|
||||
a3 = STR("v3");
|
||||
|
||||
CHECK_NODE(doc, STR("<node a2=\"v2\" a1=\"v1\"><child a3=\"v3\"/></node>"));
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
xml_attribute a4 = doc.child(STR("node")).child(STR("child")).prepend_attribute(string_view_t(STR("a4")));
|
||||
#else
|
||||
xml_attribute a4 = doc.child(STR("node")).child(STR("child")).prepend_attribute(STR("a4"));
|
||||
#endif
|
||||
CHECK(a4 && a1 != a4 && a2 != a4 && a3 != a4);
|
||||
a4 = STR("v4");
|
||||
|
||||
CHECK_NODE(doc, STR("<node a2=\"v2\" a1=\"v1\"><child a4=\"v4\" a3=\"v3\"/></node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_append_attribute, "<node><child/></node>")
|
||||
@@ -259,6 +379,37 @@ TEST_XML(dom_node_append_attribute, "<node><child/></node>")
|
||||
CHECK_NODE(doc, STR("<node a1=\"v1\" a2=\"v2\"><child a3=\"v3\"/></node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_ensure_attribute, "<node a1='v1'><child/></node>")
|
||||
{
|
||||
CHECK(xml_node().ensure_attribute(STR("a")) == xml_attribute());
|
||||
CHECK(doc.ensure_attribute(STR("a")) == xml_attribute());
|
||||
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
// existing attribute is returned as is
|
||||
xml_attribute a1 = node.ensure_attribute(STR("a1"));
|
||||
CHECK(a1 && a1 == node.attribute(STR("a1")));
|
||||
CHECK_STRING(a1.value(), STR("v1"));
|
||||
|
||||
// missing attribute is appended
|
||||
xml_attribute a2 = node.ensure_attribute(STR("a2"));
|
||||
CHECK(a2 && a2 != a1);
|
||||
a2 = STR("v2");
|
||||
|
||||
// ensuring an existing attribute does not add a duplicate
|
||||
CHECK(node.ensure_attribute(STR("a2")) == a2);
|
||||
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
xml_attribute a3 = node.child(STR("child")).ensure_attribute(string_view_t(STR("a3")));
|
||||
#else
|
||||
xml_attribute a3 = node.child(STR("child")).ensure_attribute(STR("a3"));
|
||||
#endif
|
||||
CHECK(a3 && a3 != a1 && a3 != a2);
|
||||
a3 = STR("v3");
|
||||
|
||||
CHECK_NODE(doc, STR("<node a1=\"v1\" a2=\"v2\"><child a3=\"v3\"/></node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_insert_attribute_after, "<node a1='v1'><child a2='v2'/></node>")
|
||||
{
|
||||
CHECK(xml_node().insert_attribute_after(STR("a"), xml_attribute()) == xml_attribute());
|
||||
@@ -286,7 +437,17 @@ TEST_XML(dom_node_insert_attribute_after, "<node a1='v1'><child a2='v2'/></node>
|
||||
|
||||
CHECK(child.insert_attribute_after(STR("a"), a4) == xml_attribute());
|
||||
|
||||
CHECK_NODE(doc, STR("<node a1=\"v1\" a4=\"v4\" a3=\"v3\" a5=\"v5\"><child a2=\"v2\"/></node>"));
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
xml_attribute a6 = node.insert_attribute_after(string_view_t(STR("a6")), a5);
|
||||
CHECK(child.insert_attribute_after(string_view_t(STR("a")), a5) == xml_attribute());
|
||||
#else
|
||||
xml_attribute a6 = node.insert_attribute_after(STR("a6"), a5);
|
||||
CHECK(child.insert_attribute_after(STR("a"), a5) == xml_attribute());
|
||||
#endif
|
||||
CHECK(a6 && a6 != a5 && a6 != a4 && a6 != a3 && a6 != a2 && a6 != a1);
|
||||
a6 = STR("v6");
|
||||
|
||||
CHECK_NODE(doc, STR("<node a1=\"v1\" a4=\"v4\" a3=\"v3\" a5=\"v5\" a6=\"v6\"><child a2=\"v2\"/></node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_insert_attribute_before, "<node a1='v1'><child a2='v2'/></node>")
|
||||
@@ -316,7 +477,17 @@ TEST_XML(dom_node_insert_attribute_before, "<node a1='v1'><child a2='v2'/></node
|
||||
|
||||
CHECK(child.insert_attribute_before(STR("a"), a4) == xml_attribute());
|
||||
|
||||
CHECK_NODE(doc, STR("<node a5=\"v5\" a3=\"v3\" a4=\"v4\" a1=\"v1\"><child a2=\"v2\"/></node>"));
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
xml_attribute a6 = node.insert_attribute_before(string_view_t(STR("a6")), a1);
|
||||
CHECK(child.insert_attribute_before(string_view_t(STR("a")), a4) == xml_attribute());
|
||||
#else
|
||||
xml_attribute a6 = node.insert_attribute_before(STR("a6"), a1);
|
||||
CHECK(child.insert_attribute_before(STR("a"), a4) == xml_attribute());
|
||||
#endif
|
||||
CHECK(a6 && a6 != a5 && a6 != a4 && a6 != a3 && a6 != a2 && a6 != a1);
|
||||
a6 = STR("v6");
|
||||
|
||||
CHECK_NODE(doc, STR("<node a5=\"v5\" a3=\"v3\" a4=\"v4\" a6=\"v6\" a1=\"v1\"><child a2=\"v2\"/></node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_prepend_copy_attribute, "<node a1='v1'><child a2='v2'/><child/></node>")
|
||||
@@ -490,6 +661,14 @@ TEST_XML(dom_node_remove_attribute, "<node a1='v1' a2='v2' a3='v3'><child a4='v4
|
||||
CHECK(child.remove_attribute(STR("a4")));
|
||||
|
||||
CHECK_NODE(doc, STR("<node a2=\"v2\"><child/></node>"));
|
||||
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
CHECK(!node.remove_attribute(string_view_t()));
|
||||
CHECK(!node.remove_attribute(string_view_t(STR("a2"), 1)));
|
||||
CHECK(node.remove_attribute(string_view_t(STR("a2extra"), 2)));
|
||||
|
||||
CHECK_NODE(doc, STR("<node><child/></node>"));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_remove_attributes, "<node a1='v1' a2='v2' a3='v3'><child a4='v4'/></node>")
|
||||
@@ -648,6 +827,10 @@ TEST_XML(dom_node_prepend_child_name, "<node>foo<child/></node>")
|
||||
{
|
||||
CHECK(xml_node().prepend_child(STR("")) == xml_node());
|
||||
CHECK(doc.child(STR("node")).first_child().prepend_child(STR("")) == xml_node());
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
CHECK(xml_node().prepend_child(string_view_t()) == xml_node());
|
||||
CHECK(doc.child(STR("node")).first_child().prepend_child(string_view_t()) == xml_node());
|
||||
#endif
|
||||
|
||||
xml_node n1 = doc.child(STR("node")).prepend_child(STR("n1"));
|
||||
CHECK(n1);
|
||||
@@ -655,7 +838,14 @@ TEST_XML(dom_node_prepend_child_name, "<node>foo<child/></node>")
|
||||
xml_node n2 = doc.child(STR("node")).prepend_child(STR("n2"));
|
||||
CHECK(n2 && n1 != n2);
|
||||
|
||||
CHECK_NODE(doc, STR("<node><n2/><n1/>foo<child/></node>"));
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
xml_node n3 = doc.prepend_child(string_view_t(STR("n3")));
|
||||
#else
|
||||
xml_node n3 = doc.prepend_child(STR("n3"));
|
||||
#endif
|
||||
CHECK(n3 && n1 != n3 && n2 != n3);
|
||||
|
||||
CHECK_NODE(doc, STR("<n3/><node><n2/><n1/>foo<child/></node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_append_child_name, "<node>foo<child/></node>")
|
||||
@@ -669,7 +859,42 @@ TEST_XML(dom_node_append_child_name, "<node>foo<child/></node>")
|
||||
xml_node n2 = doc.child(STR("node")).append_child(STR("n2"));
|
||||
CHECK(n2 && n1 != n2);
|
||||
|
||||
CHECK_NODE(doc, STR("<node>foo<child/><n1/><n2/></node>"));
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
xml_node n3 = doc.append_child(string_view_t(STR("n3")));
|
||||
#else
|
||||
xml_node n3 = doc.append_child(STR("n3"));
|
||||
#endif
|
||||
CHECK(n3 && n3 != n2 && n3 != n1);
|
||||
|
||||
CHECK_NODE(doc, STR("<node>foo<child/><n1/><n2/></node><n3/>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_ensure_child, "<node>foo<child/></node>")
|
||||
{
|
||||
CHECK(xml_node().ensure_child(STR("")) == xml_node());
|
||||
CHECK(doc.child(STR("node")).first_child().ensure_child(STR("n")) == xml_node());
|
||||
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
// existing child is returned as is
|
||||
xml_node child = node.ensure_child(STR("child"));
|
||||
CHECK(child && child == node.child(STR("child")));
|
||||
|
||||
// missing child is appended
|
||||
xml_node n1 = node.ensure_child(STR("n1"));
|
||||
CHECK(n1 && n1 != child);
|
||||
|
||||
// ensuring an existing child does not add a duplicate
|
||||
CHECK(node.ensure_child(STR("child")) == child);
|
||||
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
xml_node n2 = doc.ensure_child(string_view_t(STR("n2")));
|
||||
#else
|
||||
xml_node n2 = doc.ensure_child(STR("n2"));
|
||||
#endif
|
||||
CHECK(n2 && n2 != child && n2 != n1);
|
||||
|
||||
CHECK_NODE(doc, STR("<node>foo<child/><n1/></node><n2/>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_insert_child_after_name, "<node>foo<child/></node>")
|
||||
@@ -691,7 +916,14 @@ TEST_XML(dom_node_insert_child_after_name, "<node>foo<child/></node>")
|
||||
|
||||
CHECK(child.insert_child_after(STR(""), n2) == xml_node());
|
||||
|
||||
CHECK_NODE(doc, STR("<node>foo<child/><n2/><n1/></node>"));
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
xml_node n3 = node.insert_child_after(string_view_t(STR("n3")), n1);
|
||||
#else
|
||||
xml_node n3 = node.insert_child_after(STR("n3"), n1);
|
||||
#endif
|
||||
CHECK(n3 && n3 != node && n3 != child && n3 != n2 && n3 != n1);
|
||||
|
||||
CHECK_NODE(doc, STR("<node>foo<child/><n2/><n1/><n3/></node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_insert_child_before_name, "<node>foo<child/></node>")
|
||||
@@ -713,7 +945,14 @@ TEST_XML(dom_node_insert_child_before_name, "<node>foo<child/></node>")
|
||||
|
||||
CHECK(child.insert_child_before(STR(""), n2) == xml_node());
|
||||
|
||||
CHECK_NODE(doc, STR("<node>foo<n1/><n2/><child/></node>"));
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
xml_node n3 = node.insert_child_before(string_view_t(STR("n3")), child);
|
||||
#else
|
||||
xml_node n3 = node.insert_child_before(STR("n3"), child);
|
||||
#endif
|
||||
CHECK(n3 && n3 != node && n3 != child && n3 != n2 && n3 != n1);
|
||||
|
||||
CHECK_NODE(doc, STR("<node>foo<n1/><n2/><n3/><child/></node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_remove_child, "<node><n1/><n2/><n3/><child><n4/></child></node>")
|
||||
@@ -735,6 +974,20 @@ TEST_XML(dom_node_remove_child, "<node><n1/><n2/><n3/><child><n4/></child></node
|
||||
CHECK(child.remove_child(STR("n4")));
|
||||
|
||||
CHECK_NODE(doc, STR("<node><n2/><child/></node>"));
|
||||
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
CHECK(!node.remove_child(string_view_t()));
|
||||
CHECK(!node.remove_child(string_view_t(STR("child"), 3)));
|
||||
CHECK(!node.remove_child(string_view_t(STR("n2"), 1)));
|
||||
|
||||
CHECK_NODE(doc, STR("<node><n2/><child/></node>"));
|
||||
|
||||
CHECK(node.remove_child(string_view_t(STR("child"))));
|
||||
CHECK_NODE(doc, STR("<node><n2/></node>"));
|
||||
|
||||
CHECK(node.remove_child(string_view_t(STR("n2_notinview"), 2)));
|
||||
CHECK_NODE(doc, STR("<node/>"));
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_remove_children, "<node><n1/><n2/><n3/><child><n4/></child></node>")
|
||||
@@ -1522,6 +1775,30 @@ TEST(dom_node_copy_stackless)
|
||||
CHECK_NODE(doc, data.c_str());
|
||||
}
|
||||
|
||||
TEST(dom_node_remove_child_stackless)
|
||||
{
|
||||
unsigned int count = 20000;
|
||||
std::basic_string<char_t> data = STR("<root>");
|
||||
|
||||
for (unsigned int i = 0; i < count; ++i)
|
||||
data += STR("<a>");
|
||||
|
||||
data += STR("text");
|
||||
|
||||
for (unsigned int j = 0; j < count; ++j)
|
||||
data += STR("</a>");
|
||||
|
||||
data += STR("<tail/></root>");
|
||||
|
||||
xml_document doc;
|
||||
CHECK(doc.load_string(data.c_str()));
|
||||
|
||||
xml_node root = doc.child(STR("root"));
|
||||
CHECK(root.remove_child(root.child(STR("a"))));
|
||||
|
||||
CHECK_NODE(doc, STR("<root><tail/></root>"));
|
||||
}
|
||||
|
||||
TEST(dom_node_copy_copyless)
|
||||
{
|
||||
std::basic_string<char_t> data;
|
||||
@@ -1710,7 +1987,7 @@ TEST_XML(dom_node_set_deallocate, "<node attr='value'>text</node>")
|
||||
node.set_name(STR(""));
|
||||
node.text().set(STR(""));
|
||||
|
||||
CHECK_NODE(doc, STR("<:anonymous :anonymous=\"\"></:anonymous>"));
|
||||
CHECK_NODE(doc, STR("<:anonymous :anonymous=\"\"/>"));
|
||||
}
|
||||
|
||||
TEST(dom_node_copy_declaration_empty_name)
|
||||
|
||||
+158
-4
@@ -119,7 +119,7 @@ TEST_XML(dom_text_as_integer_space, "<node><text1> \t\n1234</text1><text2>\n\t 0
|
||||
CHECK(node.child(STR("text4")).text().as_int() == 0);
|
||||
}
|
||||
|
||||
TEST_XML(dom_text_as_float, "<node><text1>0</text1><text2>1</text2><text3>0.12</text3><text4>-5.1</text4><text5>3e-4</text5><text6>3.14159265358979323846</text6></node>")
|
||||
TEST_XML(dom_text_as_float, "<node><text1>0</text1><text2>1</text2><text3>0.12</text3><text4>-5.1</text4><text5>3e-4</text5><text6>3.14159265358979323846</text6><text7> \t\n+2.5</text7></node>")
|
||||
{
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
@@ -130,9 +130,10 @@ TEST_XML(dom_text_as_float, "<node><text1>0</text1><text2>1</text2><text3>0.12</
|
||||
CHECK_DOUBLE(double(node.child(STR("text4")).text().as_float()), -5.1);
|
||||
CHECK_DOUBLE(double(node.child(STR("text5")).text().as_float()), 3e-4);
|
||||
CHECK_DOUBLE(double(node.child(STR("text6")).text().as_float()), 3.14159265358979323846);
|
||||
CHECK_DOUBLE(double(node.child(STR("text7")).text().as_float()), 2.5);
|
||||
}
|
||||
|
||||
TEST_XML(dom_text_as_double, "<node><text1>0</text1><text2>1</text2><text3>0.12</text3><text4>-5.1</text4><text5>3e-4</text5><text6>3.14159265358979323846</text6></node>")
|
||||
TEST_XML(dom_text_as_double, "<node><text1>0</text1><text2>1</text2><text3>0.12</text3><text4>-5.1</text4><text5>3e-4</text5><text6>3.14159265358979323846</text6><text7> \t\n+2.5</text7></node>")
|
||||
{
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
@@ -143,6 +144,7 @@ TEST_XML(dom_text_as_double, "<node><text1>0</text1><text2>1</text2><text3>0.12<
|
||||
CHECK_DOUBLE(node.child(STR("text4")).text().as_double(), -5.1);
|
||||
CHECK_DOUBLE(node.child(STR("text5")).text().as_double(), 3e-4);
|
||||
CHECK_DOUBLE(node.child(STR("text6")).text().as_double(), 3.14159265358979323846);
|
||||
CHECK_DOUBLE(node.child(STR("text7")).text().as_double(), 2.5);
|
||||
}
|
||||
|
||||
TEST_XML(dom_text_as_bool, "<node><text1>0</text1><text2>1</text2><text3>true</text3><text4>True</text4><text5>Yes</text5><text6>yes</text6><text7>false</text7></node>")
|
||||
@@ -157,6 +159,9 @@ TEST_XML(dom_text_as_bool, "<node><text1>0</text1><text2>1</text2><text3>true</t
|
||||
CHECK(node.child(STR("text5")).text().as_bool());
|
||||
CHECK(node.child(STR("text6")).text().as_bool());
|
||||
CHECK(!node.child(STR("text7")).text().as_bool());
|
||||
|
||||
xml_node text = node.append_child(node_pcdata);
|
||||
CHECK(text.text().as_bool(true) == true);
|
||||
}
|
||||
|
||||
#ifdef PUGIXML_HAS_LONG_LONG
|
||||
@@ -236,7 +241,7 @@ TEST_XML(dom_text_set, "<node/>")
|
||||
|
||||
t.set(STR(""));
|
||||
CHECK(node.first_child().type() == node_pcdata);
|
||||
CHECK_NODE(node, STR("<node></node>"));
|
||||
CHECK_NODE(node, STR("<node/>"));
|
||||
|
||||
t.set(STR("boo"));
|
||||
CHECK(node.first_child().type() == node_pcdata);
|
||||
@@ -247,8 +252,123 @@ TEST_XML(dom_text_set, "<node/>")
|
||||
CHECK(node.first_child().type() == node_pcdata);
|
||||
CHECK(node.first_child() == node.last_child());
|
||||
CHECK_NODE(node, STR("<node>foobarfoobar</node>"));
|
||||
|
||||
t.set(STR(""));
|
||||
CHECK(node.first_child().type() == node_pcdata);
|
||||
CHECK_NODE(node, STR("<node/>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_text_set_with_size, "<node/>")
|
||||
{
|
||||
xml_node node = doc.child(STR("node"));
|
||||
xml_text t = node.text();
|
||||
|
||||
t.set(STR(""), 0);
|
||||
CHECK(node.first_child().type() == node_pcdata);
|
||||
CHECK_NODE(node, STR("<node/>"));
|
||||
|
||||
t.set(STR("boo"), 3);
|
||||
CHECK(node.first_child().type() == node_pcdata);
|
||||
CHECK(node.first_child() == node.last_child());
|
||||
CHECK_NODE(node, STR("<node>boo</node>"));
|
||||
|
||||
t.set(STR("foobarfoobar"), 12);
|
||||
CHECK(node.first_child().type() == node_pcdata);
|
||||
CHECK(node.first_child() == node.last_child());
|
||||
CHECK_NODE(node, STR("<node>foobarfoobar</node>"));
|
||||
|
||||
t.set(STR(""), 0);
|
||||
CHECK(node.first_child().type() == node_pcdata);
|
||||
CHECK_NODE(node, STR("<node/>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_text_set_partially_with_size, "<node/>")
|
||||
{
|
||||
xml_node node = doc.child(STR("node"));
|
||||
xml_text t = node.text();
|
||||
|
||||
t.set(STR("foo"), 0);
|
||||
CHECK(node.first_child().type() == node_pcdata);
|
||||
CHECK_NODE(node, STR("<node/>"));
|
||||
|
||||
t.set(STR("boofoo"), 3);
|
||||
CHECK(node.first_child().type() == node_pcdata);
|
||||
CHECK(node.first_child() == node.last_child());
|
||||
CHECK_NODE(node, STR("<node>boo</node>"));
|
||||
|
||||
t.set(STR("foobarfoobar"), 3);
|
||||
CHECK(node.first_child().type() == node_pcdata);
|
||||
CHECK(node.first_child() == node.last_child());
|
||||
CHECK_NODE(node, STR("<node>foo</node>"));
|
||||
|
||||
t.set(STR("foo"), 0);
|
||||
CHECK(node.first_child().type() == node_pcdata);
|
||||
CHECK_NODE(node, STR("<node/>"));
|
||||
}
|
||||
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
TEST_XML(dom_text_set_with_string_view, "<node/>")
|
||||
{
|
||||
xml_node node = doc.child(STR("node"));
|
||||
xml_text t = node.text();
|
||||
|
||||
t.set(string_view_t(STR("")));
|
||||
CHECK(node.first_child().type() == node_pcdata);
|
||||
CHECK_NODE(node, STR("<node/>"));
|
||||
|
||||
t.set(string_view_t(STR("boo")));
|
||||
CHECK(node.first_child().type() == node_pcdata);
|
||||
CHECK(node.first_child() == node.last_child());
|
||||
CHECK_NODE(node, STR("<node>boo</node>"));
|
||||
|
||||
t.set(string_view_t(STR("foobarfoobar")));
|
||||
CHECK(node.first_child().type() == node_pcdata);
|
||||
CHECK(node.first_child() == node.last_child());
|
||||
CHECK_NODE(node, STR("<node>foobarfoobar</node>"));
|
||||
|
||||
t.set(string_view_t(STR("")));
|
||||
CHECK(node.first_child().type() == node_pcdata);
|
||||
CHECK_NODE(node, STR("<node/>"));
|
||||
|
||||
t.set(string_view_t(STR("something")));
|
||||
CHECK(node.first_child().type() == node_pcdata);
|
||||
CHECK_NODE(node, STR("<node>something</node>"));
|
||||
|
||||
// empty string view (null data pointer)
|
||||
t.set(string_view_t());
|
||||
CHECK(node.first_child().type() == node_pcdata);
|
||||
CHECK_NODE(node, STR("<node/>"));
|
||||
|
||||
t.set(string_view_t(STR("afternulldata")));
|
||||
CHECK(node.first_child().type() == node_pcdata);
|
||||
CHECK_NODE(node, STR("<node>afternulldata</node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_text_set_partially_with_string_view, "<node/>")
|
||||
{
|
||||
xml_node node = doc.child(STR("node"));
|
||||
xml_text t = node.text();
|
||||
|
||||
t.set(string_view_t(STR("foo"), 0));
|
||||
CHECK(node.first_child().type() == node_pcdata);
|
||||
CHECK_NODE(node, STR("<node/>"));
|
||||
|
||||
t.set(string_view_t(STR("boofoo"), 3));
|
||||
CHECK(node.first_child().type() == node_pcdata);
|
||||
CHECK(node.first_child() == node.last_child());
|
||||
CHECK_NODE(node, STR("<node>boo</node>"));
|
||||
|
||||
t.set(string_view_t(STR("foobarfoobar"), 3));
|
||||
CHECK(node.first_child().type() == node_pcdata);
|
||||
CHECK(node.first_child() == node.last_child());
|
||||
CHECK_NODE(node, STR("<node>foo</node>"));
|
||||
|
||||
t.set(string_view_t(STR("foo"), 0));
|
||||
CHECK(node.first_child().type() == node_pcdata);
|
||||
CHECK_NODE(node, STR("<node/>"));
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_XML(dom_text_assign, "<node/>")
|
||||
{
|
||||
xml_node node = doc.child(STR("node"));
|
||||
@@ -273,7 +393,14 @@ TEST_XML(dom_text_assign, "<node/>")
|
||||
node.append_child(STR("text8")).text() = true;
|
||||
xml_text() = true;
|
||||
|
||||
CHECK_NODE(node, STR("<node><text1>v1</text1><text2>-2147483647</text2><text3>-2147483648</text3><text4>4294967295</text4><text5>4294967294</text5><text6>0.5</text6><text7>0.25</text7><text8>true</text8></node>"));
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
node.append_child(string_view_t(STR("text9"))).text() = string_view_t(STR("v2"));
|
||||
xml_text() = string_view_t(STR("text9"));
|
||||
#else
|
||||
node.append_child(STR("text9")).text() = STR("v2");
|
||||
#endif
|
||||
|
||||
CHECK_NODE(node, STR("<node><text1>v1</text1><text2>-2147483647</text2><text3>-2147483648</text3><text4>4294967295</text4><text5>4294967294</text5><text6>0.5</text6><text7>0.25</text7><text8>true</text8><text9>v2</text9></node>"));
|
||||
}
|
||||
|
||||
TEST_XML(dom_text_set_value, "<node/>")
|
||||
@@ -282,6 +409,10 @@ TEST_XML(dom_text_set_value, "<node/>")
|
||||
|
||||
CHECK(node.append_child(STR("text1")).text().set(STR("v1")));
|
||||
CHECK(!xml_text().set(STR("v1")));
|
||||
CHECK(!xml_text().set(STR("v1"), 2));
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
CHECK(!xml_text().set(string_view_t(STR("v1"))));
|
||||
#endif
|
||||
|
||||
CHECK(node.append_child(STR("text2")).text().set(-2147483647));
|
||||
CHECK(node.append_child(STR("text3")).text().set(-2147483647 - 1));
|
||||
@@ -418,6 +549,29 @@ TEST_XML(dom_text_middle, "<node><c1>notthisone</c1>text<c2/></node>")
|
||||
CHECK(t.data() == node.last_child());
|
||||
}
|
||||
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
TEST_XML(dom_text_middle_string_view, "<node><c1>notthisone</c1>text<c2/></node>")
|
||||
{
|
||||
xml_node node = doc.child(STR("node"));
|
||||
xml_text t = node.text();
|
||||
|
||||
CHECK_STRING(t.get(), STR("text"));
|
||||
t.set(string_view_t(STR("notext")));
|
||||
|
||||
CHECK_NODE(node, STR("<node><c1>notthisone</c1>notext<c2/></node>"));
|
||||
CHECK(node.remove_child(t.data()));
|
||||
|
||||
CHECK(!t);
|
||||
CHECK_NODE(node, STR("<node><c1>notthisone</c1><c2/></node>"));
|
||||
|
||||
t.set(string_view_t(STR("yestext")));
|
||||
|
||||
CHECK(t);
|
||||
CHECK_NODE(node, STR("<node><c1>notthisone</c1><c2/>yestext</node>"));
|
||||
CHECK(t.data() == node.last_child());
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_XML_FLAGS(dom_text_data, "<node><a>foo</a><b><![CDATA[bar]]></b><c><?pi value?></c><d/></node>", parse_default | parse_pi)
|
||||
{
|
||||
xml_node node = doc.child(STR("node"));
|
||||
|
||||
+185
-3
@@ -183,6 +183,9 @@ TEST_XML(dom_attr_as_bool, "<node attr1='0' attr2='1' attr3='true' attr4='True'
|
||||
CHECK(node.attribute(STR("attr5")).as_bool());
|
||||
CHECK(node.attribute(STR("attr6")).as_bool());
|
||||
CHECK(!node.attribute(STR("attr7")).as_bool());
|
||||
|
||||
xml_attribute attr = node.append_attribute(STR("attr8"));
|
||||
CHECK(attr.as_bool(true) == true);
|
||||
}
|
||||
|
||||
#ifdef PUGIXML_HAS_LONG_LONG
|
||||
@@ -536,6 +539,42 @@ TEST_XML(dom_node_child, "<node><child1/><child2/></node>")
|
||||
CHECK(doc.child(STR("node")).child(STR("child2")) == doc.child(STR("node")).last_child());
|
||||
}
|
||||
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
TEST_XML(dom_node_child_stringview, "<node><child1/><child2/></node>")
|
||||
{
|
||||
CHECK(xml_node().child(string_view_t(STR("n"))) == xml_node());
|
||||
CHECK(doc.child(string_view_t()) == xml_node());
|
||||
CHECK(doc.child(string_view_t(STR("n"))) == xml_node());
|
||||
|
||||
xml_node node = doc.child(string_view_t(STR("node")));
|
||||
CHECK_NAME_VALUE(node, STR("node"), STR(""));
|
||||
CHECK(node.child(string_view_t(STR("child2"))) == node.last_child());
|
||||
|
||||
// verify only the characters in the view of the string view are included in the comparison
|
||||
CHECK_NAME_VALUE(doc.child(string_view_t(STR("node_andextratext"), 4)), STR("node"), STR(""));
|
||||
CHECK(doc.child(string_view_t(STR("node"), 2)) == xml_node());
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_child_interior_null, "<node><child1/><child2/></node>")
|
||||
{
|
||||
const char_t name[] = STR("node\0extra");
|
||||
size_t len = (sizeof(name) / sizeof(char_t)) - 1;
|
||||
CHECK(len == 10);
|
||||
|
||||
xml_node node = doc.child(string_view_t(name, 4)); // "node" view excluding null
|
||||
CHECK_NAME_VALUE(node, STR("node"), STR(""));
|
||||
CHECK(doc.child(string_view_t(name, 5)) == xml_node()); // "node\0" view including null
|
||||
CHECK(doc.child(string_view_t(name, len)) == xml_node()); // "node\0extra" view
|
||||
|
||||
node.set_name(string_view_t(name, len));
|
||||
CHECK_NODE(doc, STR("<node><child1/><child2/></node>"));
|
||||
CHECK_NAME_VALUE(node, STR("node"), STR(""));
|
||||
CHECK_NAME_VALUE(doc.child(string_view_t(name, 4)), STR("node"), STR("")); // "node" view excluding null
|
||||
CHECK(doc.child(string_view_t(name, 5)) == xml_node()); // "node\0" view including null
|
||||
CHECK(doc.child(string_view_t(name, len)) == xml_node()); // "node\0extra" view
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_XML(dom_node_attribute, "<node attr1='0' attr2='1'/>")
|
||||
{
|
||||
CHECK(xml_node().attribute(STR("a")) == xml_attribute());
|
||||
@@ -547,6 +586,46 @@ TEST_XML(dom_node_attribute, "<node attr1='0' attr2='1'/>")
|
||||
CHECK(node.attribute(STR("attr2")) == node.last_attribute());
|
||||
}
|
||||
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
TEST_XML(dom_node_attribute_stringview, "<node attr1='0' attr2='1'/>")
|
||||
{
|
||||
CHECK(xml_node().attribute(string_view_t(STR("a"))) == xml_attribute());
|
||||
|
||||
xml_node node = doc.child(string_view_t(STR("node")));
|
||||
|
||||
CHECK(node.attribute(string_view_t()) == xml_attribute());
|
||||
CHECK(node.attribute(string_view_t(STR("n"))) == xml_attribute());
|
||||
CHECK_NAME_VALUE(node.attribute(string_view_t(STR("attr1"))), STR("attr1"), STR("0"));
|
||||
CHECK(node.attribute(string_view_t(STR("attr2"))) == node.last_attribute());
|
||||
|
||||
// verify only the characters in the view of the string view are included in the comparison
|
||||
CHECK_NAME_VALUE(node.attribute(string_view_t(STR("attr1_andextratext"), 5)), STR("attr1"), STR("0"));
|
||||
CHECK(node.attribute(string_view_t(STR("attr1"), 2)) == xml_attribute());
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_attribute_interior_null, "<node attr1='0' attr2='1'/>")
|
||||
{
|
||||
xml_node node = doc.child(STR("node"));
|
||||
CHECK_NAME_VALUE(node, STR("node"), STR(""));
|
||||
|
||||
const char_t name[] = STR("attr2\0extra");
|
||||
size_t len = (sizeof(name) / sizeof(char_t)) - 1;
|
||||
CHECK(len == 11);
|
||||
CHECK_NAME_VALUE(node.attribute(string_view_t(name, 5)), STR("attr2"), STR("1")); // "attr2" view excluding null
|
||||
CHECK(node.attribute(string_view_t(name, 6)) == xml_attribute()); // "attr2\0" view including null
|
||||
CHECK(node.attribute(string_view_t(name, len)) == xml_attribute()); // "attr2\0extra" view
|
||||
|
||||
xml_attribute attr = node.attribute(STR("attr2"));
|
||||
CHECK_NAME_VALUE(attr, STR("attr2"), STR("1"));
|
||||
attr.set_name(string_view_t(name, len));
|
||||
|
||||
CHECK_NODE(doc, STR("<node attr1=\"0\" attr2=\"1\"/>"));
|
||||
CHECK_NAME_VALUE(node.attribute(string_view_t(name, 5)), STR("attr2"), STR("1")); // "attr2" view excluding null
|
||||
CHECK(node.attribute(string_view_t(name, 6)) == xml_attribute()); // "attr2\0" view including null
|
||||
CHECK(node.attribute(string_view_t(name, len)) == xml_attribute()); // "attr2\0extra" view
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_XML(dom_node_next_previous_sibling, "<node><child1/><child2/><child3/></node>")
|
||||
{
|
||||
CHECK(xml_node().next_sibling() == xml_node());
|
||||
@@ -567,9 +646,17 @@ TEST_XML(dom_node_next_previous_sibling, "<node><child1/><child2/><child3/></nod
|
||||
|
||||
CHECK(child1.next_sibling(STR("child3")) == child3);
|
||||
CHECK(child1.next_sibling(STR("child")) == xml_node());
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
CHECK(child1.next_sibling(string_view_t(STR("child3"))) == child3);
|
||||
CHECK(child1.next_sibling(string_view_t(STR("child"))) == xml_node());
|
||||
#endif
|
||||
|
||||
CHECK(child3.previous_sibling(STR("child1")) == child1);
|
||||
CHECK(child3.previous_sibling(STR("child")) == xml_node());
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
CHECK(child3.previous_sibling(string_view_t(STR("child1"))) == child1);
|
||||
CHECK(child3.previous_sibling(string_view_t(STR("child"))) == xml_node());
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_child_value, "<node><novalue/><child1>value1</child1><child2>value2<n/></child2><child3><![CDATA[value3]]></child3>value4</node>")
|
||||
@@ -795,7 +882,12 @@ struct test_walker: xml_tree_walker
|
||||
std::basic_string<char_t> depthstr() const
|
||||
{
|
||||
char buf[32];
|
||||
|
||||
#if __cplusplus >= 201103 || defined(__APPLE__) // Xcode 14 warns about use of sprintf in C++98 builds
|
||||
snprintf(buf, sizeof(buf), "%d", depth());
|
||||
#else
|
||||
sprintf(buf, "%d", depth());
|
||||
#endif
|
||||
|
||||
#ifdef PUGIXML_WCHAR_MODE
|
||||
wchar_t wbuf[32];
|
||||
@@ -807,7 +899,7 @@ struct test_walker: xml_tree_walker
|
||||
#endif
|
||||
}
|
||||
|
||||
virtual bool begin(xml_node& node) PUGIXML_OVERRIDE
|
||||
bool begin(xml_node& node) PUGIXML_OVERRIDE
|
||||
{
|
||||
log += STR("|");
|
||||
log += depthstr();
|
||||
@@ -819,7 +911,7 @@ struct test_walker: xml_tree_walker
|
||||
return ++call_count != stop_count && xml_tree_walker::begin(node);
|
||||
}
|
||||
|
||||
virtual bool for_each(xml_node& node) PUGIXML_OVERRIDE
|
||||
bool for_each(xml_node& node) PUGIXML_OVERRIDE
|
||||
{
|
||||
log += STR("|");
|
||||
log += depthstr();
|
||||
@@ -831,7 +923,7 @@ struct test_walker: xml_tree_walker
|
||||
return ++call_count != stop_count && xml_tree_walker::end(node);
|
||||
}
|
||||
|
||||
virtual bool end(xml_node& node) PUGIXML_OVERRIDE
|
||||
bool end(xml_node& node) PUGIXML_OVERRIDE
|
||||
{
|
||||
log += STR("|");
|
||||
log += depthstr();
|
||||
@@ -1161,6 +1253,64 @@ TEST_XML(dom_node_attribute_hinted, "<node attr1='1' attr2='2' attr3='3' />")
|
||||
CHECK(!node.attribute(STR("attr"), hint) && hint == attr2);
|
||||
}
|
||||
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
TEST_XML(dom_node_attribute_hinted_stringview, "<node attr1='1' attr2='2' attr3='3' />")
|
||||
{
|
||||
xml_node node = doc.first_child();
|
||||
string_view_t a1name = string_view_t(STR("attr1"));
|
||||
string_view_t a2name = string_view_t(STR("attr2"));
|
||||
string_view_t a3name = string_view_t(STR("attr3"));
|
||||
xml_attribute attr1 = node.attribute(a1name);
|
||||
xml_attribute attr2 = node.attribute(a2name);
|
||||
xml_attribute attr3 = node.attribute(a3name);
|
||||
|
||||
xml_attribute hint;
|
||||
CHECK(!xml_node().attribute(string_view_t(string_view_t(STR("test"))), hint) && !hint);
|
||||
|
||||
CHECK(node.attribute(a2name, hint) == attr2 && hint == attr3);
|
||||
CHECK(node.attribute(a3name, hint) == attr3 && !hint);
|
||||
|
||||
CHECK(node.attribute(a1name, hint) == attr1 && hint == attr2);
|
||||
CHECK(node.attribute(a2name, hint) == attr2 && hint == attr3);
|
||||
CHECK(node.attribute(a1name, hint) == attr1 && hint == attr2);
|
||||
CHECK(node.attribute(a1name, hint) == attr1 && hint == attr2);
|
||||
|
||||
CHECK(!node.attribute(string_view_t(), hint) && hint == attr2);
|
||||
CHECK(!node.attribute(string_view_t(STR("attr1"), 4), hint) && hint == attr2); // "attr"
|
||||
CHECK(node.attribute(string_view_t(STR("attr3_extra"), 5), hint) == attr3 && !hint); // "attr3"
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_attribute_hint_interior_null, "<node attr1='1' attr2='2' attr3='3' />")
|
||||
{
|
||||
xml_node node = doc.first_child();
|
||||
|
||||
xml_attribute attr1 = node.attribute(STR("attr1"));
|
||||
xml_attribute attr2 = node.attribute(STR("attr2"));
|
||||
xml_attribute attr3 = node.attribute(STR("attr3"));
|
||||
|
||||
CHECK(node && attr1 && attr2 && attr3);
|
||||
|
||||
const char_t name[] = STR("attr2\0extra");
|
||||
size_t len = (sizeof(name) / sizeof(char_t)) - 1;
|
||||
CHECK(len == 11);
|
||||
|
||||
xml_attribute hint;
|
||||
CHECK(node.attribute(string_view_t(name, 5), hint) == attr2 && hint == attr3); // "attr2"
|
||||
CHECK(node.attribute(string_view_t(name, 5), hint) == attr2 && hint == attr3); // "attr2"
|
||||
|
||||
CHECK(!node.attribute(string_view_t(name, 6), hint) && hint == attr3); // "attr2\0"
|
||||
CHECK(!node.attribute(string_view_t(name, len), hint) && hint == attr3); // "attr2\0extra"
|
||||
|
||||
attr2.set_name(string_view_t(name, len)); // attr2\0extra
|
||||
|
||||
CHECK(node.attribute(string_view_t(name, 5), hint) == attr2 && hint == attr3); // "attr2"
|
||||
CHECK(node.attribute(string_view_t(name, 5), hint) == attr2 && hint == attr3); // "attr2"
|
||||
|
||||
CHECK(!node.attribute(string_view_t(name, 6), hint) && hint == attr3); // "attr2\0"
|
||||
CHECK(!node.attribute(string_view_t(name, len), hint) && hint == attr3); // "attr2\0extra"
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_XML(dom_as_int_overflow, "<node attr1='-2147483649' attr2='2147483648' attr3='-4294967296' />")
|
||||
{
|
||||
xml_node node = doc.child(STR("node"));
|
||||
@@ -1297,3 +1447,35 @@ TEST(dom_node_anonymous)
|
||||
CHECK_STRING(doc.child_value(), STR(""));
|
||||
CHECK_STRING(doc.last_child().child_value(), STR(""));
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_anonymous_child, "<node></node>")
|
||||
{
|
||||
xml_node node = doc.child(STR("node"));
|
||||
CHECK_NAME_VALUE(node, STR("node"), STR(""));
|
||||
node.set_name(STR(""));
|
||||
CHECK_NODE(doc, STR("<:anonymous/>"));
|
||||
CHECK(doc.first_child() != xml_node());
|
||||
CHECK_NAME_VALUE(doc.first_child(), STR(""), STR(""));
|
||||
|
||||
// searching for empty string does not find a node with empty name
|
||||
CHECK(doc.child(STR("")) == xml_node());
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
CHECK(doc.child(string_view_t()) == xml_node());
|
||||
CHECK(doc.child(string_view_t(STR("hi"), 0)) == xml_node());
|
||||
#endif
|
||||
}
|
||||
|
||||
TEST_XML(dom_node_anonymous_attribute, "<node attr='0'/>")
|
||||
{
|
||||
xml_attribute attr = doc.first_child().attribute(STR("attr"));
|
||||
CHECK(attr != xml_attribute());
|
||||
attr.set_name(STR(""));
|
||||
CHECK_NODE(doc, STR("<node :anonymous=\"0\"/>"));
|
||||
CHECK_NAME_VALUE(doc.first_child().first_attribute(), STR(""), STR("0"));
|
||||
|
||||
CHECK(doc.first_child().attribute(STR("")) == xml_attribute());
|
||||
#ifdef PUGIXML_HAS_STRING_VIEW
|
||||
CHECK(doc.first_child().attribute(string_view_t()) == xml_attribute());
|
||||
CHECK(doc.first_child().attribute(string_view_t(STR("hi"), 0)) == xml_attribute());
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1252,6 +1252,112 @@ TEST_XML_FLAGS(parse_embed_pcdata_comment, "<n>text1<!---->text2</n>", parse_emb
|
||||
CHECK_STRING(n.last_child().value(), STR("text2"));
|
||||
}
|
||||
|
||||
TEST(parse_merge_pcdata)
|
||||
{
|
||||
unsigned int flag_sets[] = {parse_cdata, parse_pi, parse_comments, parse_declaration};
|
||||
|
||||
for (unsigned int i = 0; i < sizeof(flag_sets) / sizeof(flag_sets[0]); ++i)
|
||||
{
|
||||
unsigned int flags = parse_merge_pcdata | flag_sets[i];
|
||||
|
||||
xml_document doc;
|
||||
xml_parse_result res = doc.load_string(STR("<node>First text<!-- here is a mesh node -->Second text<![CDATA[someothertext]]>some more text<?include somedata?>Last text</node>"), flags);
|
||||
CHECK(res);
|
||||
|
||||
xml_node child = doc.child(STR("node"));
|
||||
|
||||
if (flags & parse_comments)
|
||||
{
|
||||
CHECK_STRING(child.first_child().value(), STR("First text"));
|
||||
CHECK(child.first_child().next_sibling().type() == node_comment);
|
||||
CHECK_NODE(doc, STR("<node>First text<!-- here is a mesh node -->Second textsome more textLast text</node>"));
|
||||
}
|
||||
else if (flags & parse_cdata)
|
||||
{
|
||||
CHECK_STRING(child.first_child().value(), STR("First textSecond text"));
|
||||
CHECK(child.first_child().next_sibling().type() == node_cdata);
|
||||
CHECK_NODE(doc, STR("<node>First textSecond text<![CDATA[someothertext]]>some more textLast text</node>"));
|
||||
}
|
||||
else if (flags & parse_pi)
|
||||
{
|
||||
CHECK_STRING(child.first_child().value(), STR("First textSecond textsome more text"));
|
||||
CHECK(child.first_child().next_sibling().type() == node_pi);
|
||||
CHECK_NODE(doc, STR("<node>First textSecond textsome more text<?include somedata?>Last text</node>"));
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK(child.first_child() == child.last_child());
|
||||
CHECK(child.first_child().type() == node_pcdata);
|
||||
CHECK_NODE(doc, STR("<node>First textSecond textsome more textLast text</node>"));
|
||||
}
|
||||
|
||||
CHECK(child.last_child().type() == node_pcdata);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(parse_merge_pcdata_escape)
|
||||
{
|
||||
xml_document doc;
|
||||
xml_parse_result res = doc.load_string(STR("<node>First &lt; <!-- comment 1 --> Second &gt; <!-- comment 2 --> Third &quot;</node>"), parse_default | parse_merge_pcdata);
|
||||
CHECK(res);
|
||||
|
||||
CHECK_STRING(doc.child(STR("node")).child_value(), STR("First < Second > Third ""));
|
||||
}
|
||||
|
||||
TEST(parse_merge_pcdata_whitespace)
|
||||
{
|
||||
unsigned int flag_sets[] = {0, parse_ws_pcdata, parse_ws_pcdata_single};
|
||||
|
||||
for (unsigned int i = 0; i < sizeof(flag_sets) / sizeof(flag_sets[0]); ++i)
|
||||
{
|
||||
unsigned int flags = parse_merge_pcdata | flag_sets[i];
|
||||
|
||||
xml_document doc;
|
||||
xml_parse_result res = doc.load_string(STR("<node><child1> <!-- comment 1 -->\t<!-- comment 2 -->\n</child1><child2>text<!-- comment 1-->\t<!-- comment2 --> end</child2></node>"), flags);
|
||||
CHECK(res);
|
||||
|
||||
if (flags & parse_ws_pcdata)
|
||||
{
|
||||
CHECK_STRING(doc.child(STR("node")).child(STR("child1")).child_value(), STR(" \t\n"));
|
||||
CHECK_STRING(doc.child(STR("node")).child(STR("child2")).child_value(), STR("text\t end"));
|
||||
}
|
||||
else if (flags & parse_ws_pcdata_single)
|
||||
{
|
||||
CHECK_STRING(doc.child(STR("node")).child(STR("child1")).child_value(), STR("\n"));
|
||||
CHECK_STRING(doc.child(STR("node")).child(STR("child2")).child_value(), STR("text end"));
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK(!doc.child(STR("node")).child(STR("child1")).first_child());
|
||||
CHECK_STRING(doc.child(STR("node")).child(STR("child2")).child_value(), STR("text end"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TEST(parse_merge_pcdata_append)
|
||||
{
|
||||
xml_document doc;
|
||||
doc.append_child(STR("node")).append_child(node_pcdata);
|
||||
xml_parse_result res = doc.child(STR("node")).append_buffer("hello <!--comment-->world", 25, parse_merge_pcdata | parse_fragment);
|
||||
|
||||
CHECK(res.status == status_append_invalid_root);
|
||||
CHECK_STRING(doc.child(STR("node")).first_child().value(), STR(""));
|
||||
|
||||
doc.child(STR("node")).remove_children();
|
||||
res = doc.child(STR("node")).append_buffer("hello <!--comment-->world", 25, parse_merge_pcdata | parse_fragment);
|
||||
|
||||
CHECK(res.status == status_ok);
|
||||
CHECK_STRING(doc.child(STR("node")).first_child().value(), STR("hello world"));
|
||||
}
|
||||
|
||||
TEST(parse_merge_pcdata_overlap)
|
||||
{
|
||||
xml_document doc;
|
||||
xml_parse_result res = doc.load_string(STR("<node>short <!-- --> this string is very long so long that copying it will overlap itself</node>"), parse_merge_pcdata);
|
||||
CHECK(res);
|
||||
CHECK_STRING(doc.child_value(STR("node")), STR("short this string is very long so long that copying it will overlap itself"));
|
||||
}
|
||||
|
||||
TEST(parse_encoding_detect)
|
||||
{
|
||||
char test[] = "<?xml version='1.0' encoding='utf-8'?><n/>";
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#ifndef PUGIXML_NO_STL
|
||||
|
||||
#include "test.hpp"
|
||||
|
||||
#include <string>
|
||||
@@ -8,6 +6,7 @@ using namespace pugi;
|
||||
|
||||
// letters taken from http://www.utf8-chartable.de/
|
||||
|
||||
#ifndef PUGIXML_NO_STL
|
||||
TEST(as_wide_empty)
|
||||
{
|
||||
CHECK(as_wide("") == L"");
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#include "../src/pugixml.hpp"
|
||||
|
||||
#if PUGIXML_VERSION != 1110
|
||||
#if PUGIXML_VERSION != 1160 // 1.16
|
||||
#error Unexpected pugixml version
|
||||
#endif
|
||||
|
||||
+28
-4
@@ -237,7 +237,7 @@ struct test_writer: xml_writer
|
||||
{
|
||||
std::basic_string<char_t> contents;
|
||||
|
||||
virtual void write(const void* data, size_t size) PUGIXML_OVERRIDE
|
||||
void write(const void* data, size_t size) PUGIXML_OVERRIDE
|
||||
{
|
||||
CHECK(size % sizeof(char_t) == 0);
|
||||
contents.append(static_cast<const char_t*>(data), size / sizeof(char_t));
|
||||
@@ -572,12 +572,36 @@ TEST(write_pcdata_null)
|
||||
xml_document doc;
|
||||
doc.append_child(STR("node")).append_child(node_pcdata);
|
||||
|
||||
CHECK_NODE(doc, STR("<node></node>"));
|
||||
CHECK_NODE_EX(doc, STR("<node></node>\n"), STR("\t"), format_indent);
|
||||
CHECK_NODE(doc, STR("<node/>"));
|
||||
CHECK_NODE_EX(doc, STR("<node />\n"), STR("\t"), format_indent);
|
||||
CHECK_NODE_EX(doc, STR("<node></node>"), STR("\t"), format_raw | format_no_empty_element_tags);
|
||||
CHECK_NODE_EX(doc, STR("<node></node>\n"), STR("\t"), format_indent | format_no_empty_element_tags);
|
||||
|
||||
doc.first_child().append_child(node_pcdata);
|
||||
|
||||
CHECK_NODE(doc, STR("<node></node>"));
|
||||
CHECK_NODE_EX(doc, STR("<node></node>\n"), STR("\t"), format_indent);
|
||||
CHECK_NODE_EX(doc, STR("<node></node>\n"), STR("\t"), format_indent | format_no_empty_element_tags);
|
||||
}
|
||||
|
||||
TEST(write_pcdata_basic)
|
||||
{
|
||||
xml_document doc;
|
||||
doc.append_child(STR("node")).append_child(node_pcdata).set_value(STR("text"));
|
||||
|
||||
CHECK_NODE(doc, STR("<node>text</node>"));
|
||||
CHECK_NODE_EX(doc, STR("<node>text</node>\n"), STR("\t"), format_indent);
|
||||
CHECK_NODE_EX(doc, STR("<node>text</node>"), STR("\t"), format_raw | format_no_empty_element_tags);
|
||||
}
|
||||
|
||||
TEST(write_pcdata_empty_text)
|
||||
{
|
||||
xml_document doc;
|
||||
doc.append_child(STR("node")).text().set(STR(""));
|
||||
|
||||
CHECK_NODE(doc, STR("<node/>"));
|
||||
CHECK_NODE_EX(doc, STR("<node />\n"), STR("\t"), format_indent);
|
||||
CHECK_NODE_EX(doc, STR("<node></node>"), STR("\t"), format_raw | format_no_empty_element_tags);
|
||||
}
|
||||
|
||||
TEST(write_pcdata_whitespace_fixedpoint)
|
||||
@@ -687,7 +711,7 @@ TEST(write_flush_coverage)
|
||||
#ifndef PUGIXML_NO_EXCEPTIONS
|
||||
struct throwing_writer: xml_writer
|
||||
{
|
||||
virtual void write(const void*, size_t) PUGIXML_OVERRIDE
|
||||
void write(const void*, size_t) PUGIXML_OVERRIDE
|
||||
{
|
||||
throw std::runtime_error("write failed");
|
||||
}
|
||||
|
||||
+36
-10
@@ -10,14 +10,6 @@
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
|
||||
// std::random_shuffle is deprecated in c++14, is removed in c++17.
|
||||
#if defined(__cplusplus) && (__cplusplus >= 201402L)
|
||||
# include <random>
|
||||
# define PUGIXML_SHUFFLE(rng) std::shuffle(rng.begin(), rng.end(), std::default_random_engine{std::random_device{}()})
|
||||
#else
|
||||
# define PUGIXML_SHUFFLE(rng) std::random_shuffle(rng.begin(), rng.end())
|
||||
#endif
|
||||
|
||||
using namespace pugi;
|
||||
|
||||
static void load_document_copy(xml_document& doc, const char_t* text)
|
||||
@@ -28,6 +20,22 @@ static void load_document_copy(xml_document& doc, const char_t* text)
|
||||
doc.append_copy(source.first_child());
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
static void random_shuffle(std::vector<T>& v)
|
||||
{
|
||||
size_t rng = 2147483647;
|
||||
|
||||
for (size_t i = v.size() - 1; i > 0; --i)
|
||||
{
|
||||
// Fisher-Yates shuffle
|
||||
size_t j = rng % (i + 1);
|
||||
std::swap(v[j], v[i]);
|
||||
|
||||
// LCG RNG, constants from Numerical Recipes
|
||||
rng = rng * 1664525 + 1013904223;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(xpath_allocator_many_pages)
|
||||
{
|
||||
std::basic_string<char_t> query = STR("0");
|
||||
@@ -163,7 +171,7 @@ TEST(xpath_sort_random_medium)
|
||||
xpath_node_set ns = doc.select_nodes(STR("//node() | //@*"));
|
||||
|
||||
std::vector<xpath_node> nsv(ns.begin(), ns.end());
|
||||
PUGIXML_SHUFFLE(nsv);
|
||||
random_shuffle(nsv);
|
||||
|
||||
xpath_node_set copy(&nsv[0], &nsv[0] + nsv.size());
|
||||
copy.sort();
|
||||
@@ -192,7 +200,7 @@ TEST(xpath_sort_random_large)
|
||||
xpath_node_set ns = doc.select_nodes(STR("//node() | //@*"));
|
||||
|
||||
std::vector<xpath_node> nsv(ns.begin(), ns.end());
|
||||
PUGIXML_SHUFFLE(nsv);
|
||||
random_shuffle(nsv);
|
||||
|
||||
xpath_node_set copy(&nsv[0], &nsv[0] + nsv.size());
|
||||
copy.sort();
|
||||
@@ -202,6 +210,24 @@ TEST(xpath_sort_random_large)
|
||||
for (unsigned int i = 2; i < 129; ++i) tester % i;
|
||||
}
|
||||
|
||||
TEST_XML(xpath_sort_coverage, "<node><a/><b/></node>")
|
||||
{
|
||||
xml_node a = doc.child(STR("node")).child(STR("a"));
|
||||
xml_node b = doc.child(STR("node")).child(STR("b"));
|
||||
|
||||
xpath_node nodes[17];
|
||||
for (size_t i = 0; i < sizeof(nodes) / sizeof(nodes[0]); ++i)
|
||||
nodes[i] = (i == 0 || i == 8 || i == 16) ? a : b;
|
||||
|
||||
xpath_node_set ns(nodes, nodes + sizeof(nodes) / sizeof(nodes[0]), xpath_node_set::type_unsorted);
|
||||
ns.sort();
|
||||
|
||||
CHECK(ns.type() == xpath_node_set::type_sorted);
|
||||
|
||||
for (size_t i = 0; i < ns.size(); ++i)
|
||||
CHECK(ns[i].node() == (i < 3 ? a : b));
|
||||
}
|
||||
|
||||
TEST(xpath_long_numbers_parse)
|
||||
{
|
||||
const char_t* str_flt_max = STR("340282346638528860000000000000000000000");
|
||||
|
||||
@@ -573,7 +573,8 @@ TEST_XML(xpath_api_nodeset_move_assign_self, "<node><foo/><foo/><bar/></node>")
|
||||
|
||||
test_runner::_memory_fail_threshold = 1;
|
||||
|
||||
set = std::move(*&set);
|
||||
xpath_node_set* self = &set;
|
||||
set = std::move(*self);
|
||||
}
|
||||
|
||||
TEST(xpath_api_query_move)
|
||||
@@ -614,7 +615,8 @@ TEST(xpath_api_query_move)
|
||||
CHECK(q4);
|
||||
CHECK(q4.evaluate_boolean(c));
|
||||
|
||||
q4 = std::move(*&q4);
|
||||
xpath_query* q4self = &q4;
|
||||
q4 = std::move(*q4self);
|
||||
|
||||
CHECK(q4);
|
||||
CHECK(q4.evaluate_boolean(c));
|
||||
|
||||
@@ -405,6 +405,18 @@ TEST(xpath_parse_depth_limit)
|
||||
CHECK_XPATH_FAIL((STR("/foo") + rep(STR("//x"), limit / 2)).c_str());
|
||||
}
|
||||
|
||||
TEST(xpath_parse_depth_limit_coverage)
|
||||
{
|
||||
const size_t almost_limit = 1023;
|
||||
|
||||
CHECK_XPATH_FAIL((rep(STR("("), almost_limit) + STR("string(1)") + rep(STR(")"), almost_limit)).c_str());
|
||||
CHECK_XPATH_FAIL((rep(STR("("), almost_limit) + STR("foo[1]") + rep(STR(")"), almost_limit)).c_str());
|
||||
|
||||
xpath_variable_set vars;
|
||||
CHECK(vars.set(STR("x"), xpath_node_set()));
|
||||
CHECK_XPATH_FAIL_VAR((rep(STR("("), almost_limit) + STR("$x[1]") + rep(STR(")"), almost_limit)).c_str(), &vars);
|
||||
}
|
||||
|
||||
TEST_XML(xpath_parse_location_path, "<node><child/></node>")
|
||||
{
|
||||
CHECK_XPATH_NODESET(doc, STR("/node")) % 2;
|
||||
|
||||
@@ -639,9 +639,13 @@ TEST_XML(xpath_paths_unsorted_child, "<node><foo><bar/></foo><node><foo><bar/></
|
||||
|
||||
TEST_XML(xpath_paths_optimize_compare_attribute, "<node id='1' /><node id='2' /><node xmlns='3' />")
|
||||
{
|
||||
xml_node node = doc.first_child();
|
||||
|
||||
CHECK_XPATH_NODESET(doc, STR("node[@id = '1']")) % 2;
|
||||
CHECK_XPATH_NODESET(doc, STR("node[@id = '2']")) % 4;
|
||||
CHECK_XPATH_NODESET(doc, STR("node[@id = 2]")) % 4;
|
||||
CHECK_XPATH_BOOLEAN(node, STR("@id < 2"), true);
|
||||
CHECK_XPATH_BOOLEAN(node, STR("2 > @id"), true);
|
||||
CHECK_XPATH_NODESET(doc, STR("node[@id[. > 3] = '2']"));
|
||||
CHECK_XPATH_NODESET(doc, STR("node['1' = @id]")) % 2;
|
||||
|
||||
|
||||
@@ -463,6 +463,16 @@ TEST_XML(xpath_variables_copy, "<node />")
|
||||
CHECK(!set3.get(STR("a")));
|
||||
}
|
||||
|
||||
TEST(xpath_variables_copy_unset_string)
|
||||
{
|
||||
xpath_variable_set set1;
|
||||
CHECK(set1.add(STR("v"), xpath_type_string));
|
||||
|
||||
xpath_variable_set set2 = set1;
|
||||
CHECK(set2.get(STR("v")));
|
||||
CHECK_STRING(set2.get(STR("v"))->get_string(), STR(""));
|
||||
}
|
||||
|
||||
TEST_XML(xpath_variables_copy_out_of_memory, "<node1 /><node2 />")
|
||||
{
|
||||
xpath_variable_set set1;
|
||||
|
||||
Reference in New Issue
Block a user