Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
xmlmanipulation.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2016 Quaternion Risk Management Ltd
3 All rights reserved.
4
5 This file is part of ORE, a free-software/open-source library
6 for transparent pricing and risk analysis - http://opensourcerisk.org
7
8 ORE is free software: you can redistribute it and/or modify it
9 under the terms of the Modified BSD License. You should have received a
10 copy of the license along with this program.
11 The license is also available online at <http://opensourcerisk.org>
12
13 This program is distributed on the basis that it will form a useful
14 contribution to risk analytics and model standardisation, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17*/
18
19#include <boost/lexical_cast.hpp>
20#include <boost/test/unit_test.hpp>
22#include <oret/toplevelfixture.hpp>
23#include <ql/errors.hpp>
24#include <ql/types.hpp>
25
26using namespace ore::data;
27using namespace boost::unit_test_framework;
28using namespace std;
29using namespace QuantLib;
30
31using ore::test::TopLevelFixture;
32
33namespace {
34
35// Fixture used in each test case below
36class F : public TopLevelFixture {
37public:
38 XMLDocument testDoc;
39
40 F() {
41 // dummy xml test string
42 string testXML = "<root>"
43 "<level1>"
44 "<level1a>"
45 "<data1a attr = \"0.7736\">17.5</data1a>"
46 "</level1a>"
47 "<level1b>"
48 "<vector1b>"
49 "<vector1bval>12.3</vector1bval><vector1bval>45.6</vector1bval><vector1bval>78.9</vector1bval>"
50 "</vector1b>"
51 "</level1b>"
52 "</level1>"
53 "<level2>"
54 "<level2aDuplicates></level2aDuplicates>"
55 "<level2aDuplicates></level2aDuplicates>"
56 "<level2aDuplicates></level2aDuplicates>"
57 "<level2aDuplicates></level2aDuplicates>"
58 "</level2>"
59 "</root>";
60
61 // test creation of XML document from hardcoded string
62 testDoc.fromXMLString(testXML);
63 }
64
65 ~F() {}
66};
67
68} // namespace
69
70BOOST_FIXTURE_TEST_SUITE(OREDataTestSuite, TopLevelFixture)
71
72BOOST_AUTO_TEST_SUITE(XmlManipulationTests)
73
74BOOST_FIXTURE_TEST_CASE(testXMLDataGetters, F) {
75
76 BOOST_TEST_MESSAGE("Testing XML (scalar) data getters");
77
78 // check that the root node is as expected
79 XMLNode* root = testDoc.getFirstNode("root");
80 BOOST_CHECK_NO_THROW(XMLUtils::checkNode(root, "root"));
81
82 // check that getChildNode works as expected
83 XMLNode* level1 = XMLUtils::getChildNode(root, "level1");
84 BOOST_CHECK_NO_THROW(XMLUtils::checkNode(level1, "level1"));
85
86 // check that getChildValue works as expected
87 XMLNode* level1a = XMLUtils::getChildNode(level1, "level1a");
88 string expectedStr = "17.5";
89 string data1a_str = XMLUtils::getChildValue(level1a, "data1a");
90 BOOST_CHECK_EQUAL(data1a_str, expectedStr);
91 // ensure that cast to double works as expected
92 Real expectedReal = 17.5;
93 Real data1a_real = XMLUtils::getChildValueAsDouble(level1a, "data1a");
94 BOOST_CHECK_EQUAL(data1a_real, expectedReal);
95 // ensure that error thrown if value cast fails
96 BOOST_CHECK_THROW(XMLUtils::getChildValueAsInt(level1a, "data1a"), QuantLib::Error);
97 // ensure that error thrown if mandatory element is not found
98 BOOST_CHECK_THROW(XMLUtils::getChildValue(level1a, "data1b", true), QuantLib::Error);
99 // ensure that no error thrown if element is not mandatory
100 BOOST_CHECK_NO_THROW(XMLUtils::getChildValue(level1a, "data1b", false));
101 // test that default value of mandatory is false
102 BOOST_CHECK_NO_THROW(XMLUtils::getChildValue(level1a, "data1b"));
103 // test getNodeValue
104 XMLNode* data1a = XMLUtils::getChildNode(level1a, "data1a");
105 BOOST_CHECK(data1a);
106 // test getAttributeValue
107 string expAttribVal = "0.7736";
108 string attribVal = XMLUtils::getAttribute(data1a, "attr");
109 BOOST_CHECK_EQUAL(attribVal, expAttribVal);
110 BOOST_CHECK_NO_THROW(XMLUtils::getAttribute(data1a, "garbagename"));
111}
112
113BOOST_FIXTURE_TEST_CASE(testXMLVectorDataGetters, F) {
114
115 BOOST_TEST_MESSAGE("Testing XML vector data getters");
116
117 // check that the root node is as expected
118 XMLNode* root = testDoc.getFirstNode("root");
119 BOOST_CHECK_NO_THROW(XMLUtils::checkNode(root, "root"));
120
121 // check that getChildNode works as expected
122 XMLNode* level1 = XMLUtils::getChildNode(root, "level1");
123 BOOST_CHECK_NO_THROW(XMLUtils::checkNode(level1, "level1"));
124
125 // test getChildrenValues
126 XMLNode* level1b = XMLUtils::getChildNode(level1, "level1b");
127 XMLNode* vector1b = XMLUtils::getChildNode(level1b, "vector1b");
128 vector<string> expVecStr = {"12.3", "45.6", "78.9"};
129 vector<Real> expVecReal;
130 for (auto s : expVecStr)
131 expVecReal.push_back(boost::lexical_cast<Real>(s));
132 vector<string> vec1b_str = XMLUtils::getChildrenValues(level1b, "vector1b", "vector1bval");
133 BOOST_CHECK_EQUAL_COLLECTIONS(vec1b_str.begin(), vec1b_str.end(), expVecStr.begin(), expVecStr.end());
134 vector<Real> vec1bReal = XMLUtils::getChildrenValuesAsDoubles(level1b, "vector1b", "vector1bval");
135 BOOST_CHECK_EQUAL_COLLECTIONS(vec1bReal.begin(), vec1bReal.end(), expVecReal.begin(), expVecReal.end());
136 // test getChildrenNodes
137 vector<XMLNode*> vecNodes = XMLUtils::getChildrenNodes(vector1b, "vector1bval");
138 vector<string> manualVectorString;
139 for (auto c : vecNodes)
140 manualVectorString.push_back(XMLUtils::getNodeValue(c));
141 BOOST_CHECK_EQUAL_COLLECTIONS(manualVectorString.begin(), manualVectorString.end(), expVecStr.begin(),
142 expVecStr.end());
143}
144
145BOOST_FIXTURE_TEST_CASE(testXMLDataSetters, F) {
146
147 BOOST_TEST_MESSAGE("Testing XML data setters");
148
149 // check that the root node is as expected
150 XMLNode* root = testDoc.getFirstNode("root");
151 BOOST_CHECK_NO_THROW(XMLUtils::checkNode(root, "root"));
152
153 string newNodeVal = "value17.3";
154 XMLUtils::addChild(testDoc, root, "NewNode", newNodeVal);
155
156 string newNodeValCheck = XMLUtils::getChildValue(root, "NewNode", true);
157 BOOST_CHECK_EQUAL(newNodeValCheck, newNodeVal);
158
159 vector<Real> nodesVec = {11.1, 22.2, 33.4, 55.6};
160 XMLUtils::addChildren(testDoc, root, "nodeContainingVector", "vectorElement", nodesVec);
161
162 vector<Real> nodesVecCheck =
163 XMLUtils::getChildrenValuesAsDoubles(root, "nodeContainingVector", "vectorElement", true);
164 BOOST_CHECK_EQUAL_COLLECTIONS(nodesVecCheck.begin(), nodesVecCheck.end(), nodesVec.begin(), nodesVec.end());
165}
166
167BOOST_FIXTURE_TEST_CASE(testXMLAttributes, F) {
168
169 BOOST_TEST_MESSAGE("Testing XML attributes");
170
171 // check that the root node is as expected
172 XMLNode* root = testDoc.getFirstNode("root");
173 BOOST_CHECK_NO_THROW(XMLUtils::checkNode(root, "root"));
174
175 // check that getChildNode works as expected
176 XMLNode* level1 = XMLUtils::getChildNode(root, "level1");
177 XMLNode* level1a = XMLUtils::getChildNode(level1, "level1a");
178 XMLNode* data1a = XMLUtils::getChildNode(level1a, "data1a");
179
180 // test getAttributeValue
181 string attrExpVal = "0.7736";
182 string attrVal = XMLUtils::getAttribute(data1a, "attr");
183 BOOST_CHECK_EQUAL(attrVal, attrExpVal);
184
185 // test add attribute
186 string level1aAttrName = "level1aAttrName";
187 string level1aAttrVal = "14.2";
188 XMLUtils::addAttribute(testDoc, level1a, level1aAttrName, level1aAttrVal);
189 string level1aAttrValExract = XMLUtils::getAttribute(level1a, level1aAttrName);
190 BOOST_CHECK_EQUAL(level1aAttrValExract, level1aAttrVal);
191}
192
193BOOST_AUTO_TEST_SUITE_END()
194
195BOOST_AUTO_TEST_SUITE_END()
Small XML Document wrapper class.
Definition: xmlutils.hpp:65
void fromXMLString(const string &xmlString)
load a document from a hard-coded string
Definition: xmlutils.cpp:103
static void addAttribute(XMLDocument &doc, XMLNode *node, const string &attrName, const string &attrValue)
Definition: xmlutils.cpp:412
static vector< Real > getChildrenValuesAsDoubles(XMLNode *node, const string &names, const string &name, bool mandatory=false)
Definition: xmlutils.cpp:319
static void addChildren(XMLDocument &doc, XMLNode *n, const string &names, const string &name, const vector< T > &values)
Definition: xmlutils.cpp:502
static string getAttribute(XMLNode *node, const string &attrName)
Definition: xmlutils.cpp:419
static void checkNode(XMLNode *n, const string &expectedName)
Definition: xmlutils.cpp:175
static vector< XMLNode * > getChildrenNodes(XMLNode *node, const string &name)
Returns all the children with a given name.
Definition: xmlutils.cpp:428
static Real getChildValueAsDouble(XMLNode *node, const string &name, bool mandatory=false, double defaultValue=0.0)
Definition: xmlutils.cpp:286
static string getChildValue(XMLNode *node, const string &name, bool mandatory=false, const string &defaultValue=string())
Definition: xmlutils.cpp:277
static XMLNode * getChildNode(XMLNode *n, const string &name="")
Definition: xmlutils.cpp:387
static string getNodeValue(XMLNode *node)
Get a node's value.
Definition: xmlutils.cpp:489
static int getChildValueAsInt(XMLNode *node, const string &name, bool mandatory=false, int defaultValue=0)
Definition: xmlutils.cpp:291
static vector< string > getChildrenValues(XMLNode *node, const string &names, const string &name, bool mandatory=false)
Definition: xmlutils.cpp:306
static XMLNode * addChild(XMLDocument &doc, XMLNode *n, const string &name)
Definition: xmlutils.cpp:181
BOOST_FIXTURE_TEST_CASE(testXMLDataGetters, F)
XML utility functions.