<commit_before>/*
tinyxml2ex - a set of add-on classes and helper functions bringing C++11/14 features, such as iterators, strings and exceptions, to tinyxml2


Copyright (c) 2016 <NAME>

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

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

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


tinyxml2 is the work of <NAME> (www.grinninglizard.com) and others.
It can be found here: https://github.com/leethomason/tinyxml2 and has it's own licensing terms.

*/


#include <string>
#include <iostream>
#include <conio.h>


// include the header for tinyxml2ex which includes tinyxml2, remember to put them on your include path
#include <tixml2ex.h>

using namespace std;
using namespace std::literals::string_literals;


int main()
{
	// a simple XML document
	string testXml {R"-(
<?xml version="1.0" encoding="UTF-8"?>
<A>
	<B id="one">
		<C code="1234">
			A-B(one)-C.1234
		</C>
		<C code="5678">
			<![CDATA[A-B(one)-C.5678]]>
		</C>
		<C code="9ABC">A-B(one)-C.9ABC</C>
		<D code="9ABC" id="dd" />
	</B>
	<B id="two">
		<D id="dd" />
	</B>
	<B id="three" org="extern">
		<C code="1234">
			A-B(three)-C.1234
		</C>
		<C code="9ABC">A-B(three)-C.9ABC</C>
		<D description="A-B(three)-D.9ABC" />
	</B>
	<B id="four">
	</B>
</A>
)-"s};


	// these three blocks are equivalent and demonstrate different ways to iterate over
	// all <C> element children of <B> element children of the document element <A>
	// 1) native TinyXML2
	{
		printf ("\n1)   <C> element children of <B> element children of the document element <A>\nnative TinyXML2\n");
		tinyxml2::XMLDocument doc;
		if (doc .Parse (testXml .c_str()) == 0/*XML_NO_ERORR*/)
		{
			tinyxml2::XMLElement * eA = doc .FirstChildElement();
			if (eA)
			{
				tinyxml2::XMLElement * eB = eA -> FirstChildElement("B");
				while (eB)
				{
					tinyxml2::XMLElement * eC = eB -> FirstChildElement ("C");
					while (eC)
					{
						printf ("%s = %s\n", eC -> Name(), eC -> GetText());
						eC = eC -> NextSiblingElement ("C");
					}
					eB = eB -> NextSiblingElement ("B");
				}
			}
			else
				printf ("unable to load XML document\n");
		}
	}
	cout << "----" << endl << endl;


	// 2) tixml2ex XPath selector
	cout << "2)   <C> element children of <B> element children of the document element <A>" << endl
		<< "tixml2ex XPath selector" << endl;
	try
	{
		auto doc = tinyxml2::load_document (testXml);
		for (auto eC : tinyxml2::Selector (*doc, "A/B/C"))
			cout << eC -> Name() << " = " << text (eC) << endl;
	}
	catch (tinyxml2::XmlException & e)
	{
		cout << "XmlException caught" << e .what() << endl;
	}
	cout << "----" << endl << endl;


	// 3) simple tixml2ex element iterator
	cout << endl << "3)   <C> element children of <B> element children of the document element <A>" << endl
		<< "simple tixml2ex element iterator" << endl;
	try
	{
		auto doc = tinyxml2::load_document (testXml);
		auto eA = doc -> FirstChildElement();
		if (eA)
			for (auto eB : eA)
			{
				for (auto eC : eB)
				{
					// simple iterators are just that, they iterate over all children
					// therefore we must test element name (type) to examine only <C> elements
					if (strcmp (eC -> Name(), "C") == 0)
						cout << eC -> Name() << " = " << text (eC) << endl;
				}
			}
	}
	catch (tinyxml2::XmlException & e)
	{
		cout << "XmlException caught" << e .what() << endl;
	}

	cout << "=================================================" << endl << endl;


	// additional element selection and iteration using XPath syntax
	// illustrating helper functions
	try<commit_msg>update example 3 to iterate with std::for_each<commit_after>/*
tinyxml2ex - a set of add-on classes and helper functions bringing C++11/14 features, such as iterators, strings and exceptions, to tinyxml2


Copyright (c) 2016 <NAME>

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

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

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


tinyxml2 is the work of <NAME> (www.grinninglizard.com) and others.
It can be found here: https://github.com/leethomason/tinyxml2 and has it's own licensing terms.

*/


#include <string>
#include <iostream>
#include <algorithm>
#include <conio.h>


// include the header for tinyxml2ex which includes tinyxml2, remember to put them on your include path
#include <tixml2ex.h>

using namespace std;
using namespace std::literals::string_literals;


int main()
{
	// a simple XML document
	string testXml {R"-(
<?xml version="1.0" encoding="UTF-8"?>
<A>
	<B id="one">
		<C code="1234">
			A-B(one)-C.1234
		</C>
		<C code="5678">
			<![CDATA[A-B(one)-C.5678]]>
		</C>
		<C code="9ABC">A-B(one)-C.9ABC</C>
		<D code="9ABC" id="dd" />
	</B>
	<B id="two">
		<D id="dd" />
	</B>
	<B id="three" org="extern">
		<C code="1234">
			A-B(three)-C.1234
		</C>
		<C code="9ABC">A-B(three)-C.9ABC</C>
		<D description="A-B(three)-D.9ABC" />
	</B>
	<B id="four">
	</B>
</A>
)-"s};


	// these three blocks are equivalent and demonstrate different ways to iterate over
	// all <C> element children of <B> element children of the document element <A>
	// 1) native TinyXML2
	{
		printf ("\n1)   <C> element children of <B> element children of the document element <A>\nnative TinyXML2\n");
		tinyxml2::XMLDocument doc;
		if (doc .Parse (testXml .c_str()) == 0/*XML_NO_ERORR*/)
		{
			tinyxml2::XMLElement * eA = doc .FirstChildElement();
			if (eA)
			{
				tinyxml2::XMLElement * eB = eA -> FirstChildElement("B");
				while (eB)
				{
					tinyxml2::XMLElement * eC = eB -> FirstChildElement ("C");
					while (eC)
					{
						printf ("%s = %s\n", eC -> Name(), eC -> GetText());
						eC = eC -> NextSiblingElement ("C");
					}
					eB = eB -> NextSiblingElement ("B");
				}
			}
			else
				printf ("unable to load XML document\n");
		}
	}
	cout << "----" << endl << endl;


	// 2) tixml2ex XPath selector
	cout << "2)   <C> element children of <B> element children of the document element <A>" << endl
		<< "tixml2ex XPath selector" << endl;
	try
	{
		auto doc = tinyxml2::load_document (testXml);
		for (auto eC : tinyxml2::Selector (*doc, "A/B/C"))
			cout << eC -> Name() << " = " << text (eC) << endl;
	}
	catch (tinyxml2::XmlException & e)
	{
		cout << "XmlException caught" << e .what() << endl;
	}
	cout << "----" << endl << endl;


	// 3) simple tixml2ex element iterator
	cout << endl << "3)   <C> element children of <B> element children of the document element <A>" << endl
		<< "simple tixml2ex element iterator" << endl;
	try
	{
		auto doc = tinyxml2::load_document (testXml);
		auto eA = doc -> FirstChildElement();
		if (eA)
			for (auto eB : eA)
			{
				// just for fun, use standard algorithm for_each to iterate over the children of <B>
				for_each (begin (eB), end (eB),
					[](auto e)
				{
						// simple iterators are just that, they iterate over all children
						// therefore we must test element name (type) to examine only <C> elements
					if (strcmp (e -> Name(), "C") == 0) cout << e -> Name() << " = " << text (e) << endl;
				});
			}
	}
	catch (tinyxml2::XmlException & e)
	{
		cout << "XmlException caught" << e .what() << endl;
	}

	cout << "=================================================" << endl << endl;


	// additional element selection and iteration using XPath syntax
	// illustrating helper functions
	try
{'fraction_non_alphanumeric': 0.1495409799800907, 'fraction_numerical': 0.01581683442097113, 'mean_word_length': 3.4519940915805023, 'pattern_counts': {'":': 0, '<': 221, '<?xml version=': 2, '>': 113, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, 'xml': 42}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5235482', 'n_tokens_mistral': 3335, 'n_tokens_neox': 2943, 'n_words': 1102}