1

(I am under windows and use visual studio 2015.) I receive the xml put at the end of the question, in a one line format but I pretty printed (XML only with line breaks) with notepad++ for conveniance.

std::ifstream file("D:\\FILES\\anxmlfile.xml");
char msg[500];
strerror_s(msg,errno);
try
{
    boost::archive::xml_iarchive ia(file);
    interestRateCurve IRCurve;
    ia >> BOOST_SERIALIZATION_NVP(IRCurve);
}
catch (boost::archive::archive_exception ex)
{
    // blah
}

where msg receives "No error" and where

boost::archive::xml_iarchive ia(file);

triggers a boost::archive::archive_exception with {m_buffer=0x00e8f504 "unrecognized XML syntax" code=other_exception }. The interestRateCurve class is defined as follows :

#pragma once

#include <string>

#include "boost/archive/text_oarchive.hpp"
#include "boost/archive/text_iarchive.hpp"

#include <boost/archive/xml_oarchive.hpp> 
#include <boost/archive/xml_iarchive.hpp> 

class calendars
{
public:
    std::string calendar;
    template<class Archive> void serialize(Archive& archive, const unsigned int version)
    {
        archive & BOOST_SERIALIZATION_NVP(calendar);
    }
};

class curvepoint
{
public:
    std::string tenor;
    std::string maturitydate;
    double parrate;
    template<class Archive> void serialize(Archive& archive, const unsigned int version)
    {
        archive & BOOST_SERIALIZATION_NVP(tenor);
        archive & BOOST_SERIALIZATION_NVP(maturitydate);
        archive & BOOST_SERIALIZATION_NVP(parrate);
    }
};

class interestRateCurveDeposits
{
public:
    std::string daycountconvention;
    std::string snaptime;
    std::string spotdate;
    calendars m_calendars;
    curvepoint curvepoint;
    template<class Archive> void serialize(Archive& archive, const unsigned int version)
    {
        archive & BOOST_SERIALIZATION_NVP(daycountconvention);
        archive & BOOST_SERIALIZATION_NVP(snaptime);
        archive & BOOST_SERIALIZATION_NVP(spotdate);
        archive & BOOST_SERIALIZATION_NVP(m_calendars);
        archive & BOOST_SERIALIZATION_NVP(curvepoint);
    }
};

class interestRateCurveSwaps
{
public:
    std::string fixeddaycountconvention;
    std::string floatingdaycountconvention;
    std::string fixedpaymentfrequency;
    std::string floatingpaymentfrequency;
    std::string snaptime;
    std::string spotdate;
    calendars calendars[1];
    curvepoint curvepoint[1];
    template<class Archive> void serialize(Archive& archive, const unsigned int version)
    {
        archive & BOOST_SERIALIZATION_NVP(fixeddaycountconvention);
        archive & BOOST_SERIALIZATION_NVP(floatingdaycountconvention);
        archive & BOOST_SERIALIZATION_NVP(fixedpaymentfrequency);
        archive & BOOST_SERIALIZATION_NVP(floatingpaymentfrequency);
        archive & BOOST_SERIALIZATION_NVP(snaptime);
        archive & BOOST_SERIALIZATION_NVP(spotdate);
        archive & BOOST_SERIALIZATION_NVP(calendars);
        archive & BOOST_SERIALIZATION_NVP(curvepoint);
    }
};

class interestRateCurve
{
public:
    std::string effectiveasof;
    std::string currency;
    std::string baddayconvention;
    interestRateCurveDeposits deposits[1];
    interestRateCurveSwaps swaps[1];
    template<class Archive> void serialize(Archive& archive, const unsigned int version)
    {
        archive & BOOST_SERIALIZATION_NVP(effectiveasof);
        archive & BOOST_SERIALIZATION_NVP(currency);
        archive & BOOST_SERIALIZATION_NVP(baddayconvention);
        archive & BOOST_SERIALIZATION_NVP(deposits);
        archive & BOOST_SERIALIZATION_NVP(swaps);
    }
};

The following short xml (produces with a boost code snippet) doesn't trigger the same error :

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="15">
<d class_id="0" tracking_level="0" version="0">
    <m_day>15</m_day>
    <m_month>8</m_month>
    <m_year>1947</m_year>
</d>
</boost_serialization>

My problematic xml does :

<?xml version="1.0" standalone="yes" ?>
<interestRateCurve>
    <effectiveasof>2009-01-05</effectiveasof>
    <currency>USD</currency>
    <baddayconvention>M</baddayconvention>
    <deposits>
        <daycountconvention>ACT/360</daycountconvention>
        <snaptime>2009-01-02T21:00:00.000Z</snaptime>
        <spotdate>2009-01-07</spotdate>
        <calendars>
            <calendar>none</calendar>
        </calendars>
        <curvepoint>
            <tenor>1M</tenor>
            <maturitydate>2009-02-09</maturitydate>
            <parrate>0.0043</parrate>
        </curvepoint>
        <curvepoint>
            <tenor>2M</tenor>
            <maturitydate>2009-03-09</maturitydate>
            <parrate>0.010988</parrate>
        </curvepoint>
        <curvepoint>
            <tenor>3M</tenor>
            <maturitydate>2009-04-07</maturitydate>
            <parrate>0.014125</parrate>
        </curvepoint>
        <curvepoint>
            <tenor>6M</tenor>
            <maturitydate>2009-07-07</maturitydate>
            <parrate>0.017525</parrate>
        </curvepoint>
        <curvepoint>
            <tenor>9M</tenor>
            <maturitydate>2009-10-07</maturitydate>
            <parrate>0.019063</parrate>
        </curvepoint>
        <curvepoint>
            <tenor>1Y</tenor>
            <maturitydate>2010-01-07</maturitydate>
            <parrate>0.020238</parrate>
        </curvepoint>
    </deposits>
    <swaps>
        <fixeddaycountconvention>30/360</fixeddaycountconvention>
        <floatingdaycountconvention>ACT/360</floatingdaycountconvention>
        <fixedpaymentfrequency>6M</fixedpaymentfrequency>
        <floatingpaymentfrequency>3M</floatingpaymentfrequency>
        <snaptime>2009-01-02T21:00:00.000Z</snaptime>
        <spotdate>2009-01-07</spotdate>
        <calendars>
            <calendar>none</calendar>
        </calendars>
        <curvepoint>
            <tenor>2Y</tenor>
            <maturitydate>2011-01-07</maturitydate>
            <parrate>0.016509</parrate>
        </curvepoint>
        <curvepoint>
            <tenor>3Y</tenor>
            <maturitydate>2012-01-07</maturitydate>
            <parrate>0.019413</parrate>
        </curvepoint>
        <curvepoint>
            <tenor>4Y</tenor>
            <maturitydate>2013-01-07</maturitydate>
            <parrate>0.021521</parrate>
        </curvepoint>
        <curvepoint>
            <tenor>5Y</tenor>
            <maturitydate>2014-01-07</maturitydate>
            <parrate>0.023315</parrate>
        </curvepoint>
        <curvepoint>
            <tenor>6Y</tenor>
            <maturitydate>2015-01-07</maturitydate>
            <parrate>0.024588</parrate>
        </curvepoint>
        <curvepoint>
            <tenor>7Y</tenor>
            <maturitydate>2016-01-07</maturitydate>
            <parrate>0.025719</parrate>
        </curvepoint>
        <curvepoint>
            <tenor>8Y</tenor>
            <maturitydate>2017-01-07</maturitydate>
            <parrate>0.02656</parrate>
        </curvepoint>
        <curvepoint>
            <tenor>9Y</tenor>
            <maturitydate>2018-01-07</maturitydate>
            <parrate>0.02726</parrate>
        </curvepoint>
        <curvepoint>
            <tenor>10Y</tenor>
            <maturitydate>2019-01-07</maturitydate>
            <parrate>0.028</parrate>
        </curvepoint>
        <curvepoint>
            <tenor>12Y</tenor>
            <maturitydate>2021-01-07</maturitydate>
            <parrate>0.02893</parrate>
        </curvepoint>
        <curvepoint>
            <tenor>15Y</tenor>
            <maturitydate>2024-01-07</maturitydate>
            <parrate>0.029989</parrate>
        </curvepoint>
        <curvepoint>
            <tenor>20Y</tenor>
            <maturitydate>2029-01-07</maturitydate>
            <parrate>0.030029</parrate>
        </curvepoint>
        <curvepoint>
            <tenor>25Y</tenor>
            <maturitydate>2034-01-07</maturitydate>
            <parrate>0.029639</parrate>
        </curvepoint>
        <curvepoint>
            <tenor>30Y</tenor>
            <maturitydate>2039-01-07</maturitydate>
            <parrate>0.029505</parrate>
        </curvepoint>
    </swaps>
</interestRateCurve>

What am I doing wrong ? Is the format really wrong and why ? If not, what to do ?

EDIT. Enclosing the

<interestRateCurve>
...
</interestRateCurve>

of my xml in

<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="15">
...
</boost_serialization>

solves the problem, but of course is not a viable solution for me, as I have millions of xml of the same form than the one I'm fighting with ...

Olórin
  • 3,367
  • 2
  • 22
  • 42

2 Answers2

1

The problem is that Boost has no XML library.

You seem to think that Boost Serialization can read XML. In fact, it can only read a subset of XML documents, namely Boost Serialization Archives, which are a specific format. If you don't have that format, you can't use Boost Serialization to read it.

Instead, simply use an XML library. I suggest PugiXML or libxml2:

What XML parser should I use in C++?

Community
  • 1
  • 1
sehe
  • 374,641
  • 47
  • 450
  • 633
  • Oh, ok, didn't indeed know that Boost Serialization can only read a subset of XML documents, thx ! PugiXML I tried, really ok but doesn't use precompiled headers, which is an issue in the big solution I am operating in. I will give a shot to libxml2 : I can use that under windows with mvs ? What do you think of http://stackoverflow.com/questions/28037909/xml-parsing-using-boost ? I know, it's not deserialization per se ... – Olórin Apr 27 '17 at 12:32
  • Huh. PugiXML can work fine if you use precompiled headers. Also, that NEVER a problem in a "large solution" unless you don't know how to avoid tight coupling. Basically, makes sure you never include the XML library headers in a "public" or shared header file. Only include it in the (one) cpp that uses it. – sehe Apr 27 '17 at 12:34
  • I like that answer you linked :) It says exactly the same. If you need help with PugiXML, look at [some samples I made using it](https://stackoverflow.com/search?tab=votes&q=user%3a85371%20pugixml). Libxml2 is gonna be a bit harder to set up under MSVC – sehe Apr 27 '17 at 12:38
  • "PugiXML can work fine if you use precompiled headers" --> How ? I have the precompiled header issue described here https://github.com/zeux/pugixml/blob/master/docs/manual.adoc and the only solution they provided what disabling compiled header. To be honest, I don't even want to try to look at that aspect in the solution I work in. – Olórin Apr 27 '17 at 12:39
  • Let me see you samples – Olórin Apr 27 '17 at 12:39
  • PugiXML can also work fine without precompiled headers. The point is, if it matters, you are not decoupling your dependencies. – sehe Apr 27 '17 at 12:47
  • By the way, the non-recommended way to avoid the fiasco with precompiled headers, is simply to insert `#include "stdafx.h"` at the start of `pugixml.cpp`. Precompiled headers on MSVC are a non-portable mess, which is why PugiXML don't want to bother. Like I said, there is no gain, unless you use PugiXML in all your compilation units. – sehe Apr 27 '17 at 12:49
  • Oh, and perhaps you simply misread. That manual says: _"The correct way to resolve this is to disable precompiled headers **for pugixml.cpp**"_. That doesn't affect any of your other compilation units. At all. – sehe Apr 27 '17 at 12:52
  • 1
    I indeed misread ... You are right, I do what I want, with precompiled headers, with pugixml ! Thx a lot for pointing out my stupidity, sometime it is really useful ;-) – Olórin Apr 27 '17 at 13:03
  • `doc.child("interestRateCurve").attribute("currency").value()` doesn't work in my case – Olórin Apr 27 '17 at 13:41
0
std::ifstream file("D:\\FILES\\anxmlfile.xml");
char msg[500];
strerror_s(msg,errno);
try
{
    unsigned int flags = boost::archive::no_header;
    boost::archive::xml_iarchive ia(file, flags);
    interestRateCurve IRCurve;
    ia >> BOOST_SERIALIZATION_NVP(IRCurve);
}
catch (boost::archive::archive_exception ex)
{
    // blah
}

does the trick but then

ia >> BOOST_SERIALIZATION_NVP(IRCurve);

triggers a ""input stream error" code=input_stream_error". I don't know if it is because of a bad design of the interestRateCurve class which is therefore not able to do the job, or if my answer is simply not a right answer, resulting in a "bad" bst::archive::xml_iarchive ? (The bst::archive::xml_iarchive looks normal at debug though.)

Olórin
  • 3,367
  • 2
  • 22
  • 42