2

わかりました、これが私の問題です。

シリアル化によってxml文字列を作成するブーストオブジェクトがありますが、これは問題なく機能します。

ブーストバージョン1.38の使用

そのxml文字列を取得し、SQLサーバーデータベーステーブルにxmlデータ型で保存します。これも正常に機能します。

次に、データベーステーブルからxml文字列を取得しますが、フォーマットが挿入されたときからわずかに変更されており、基本的に空白の値に短いタグが付けられています<data></data><data/>

前後のxmlの例を次に示します。

<grid class_id="0" tracking_level="0" version="0">
    <name>test_table</name>
    <columns class_id="1" tracking_level="0" version="0">
        <count>2</count>
        <item_version>0</item_version>
        <item class_id="2" tracking_level="1" version="0" object_id="_0">
            <label>AAAA</label>
            <data>xxxx</data>
        </item>
        <item class_id_reference="2" object_id="_1">
      <label>BBBB</label>
      <data></data>
    </item>
    </columns>
</grid>

<grid class_id="0" tracking_level="0" version="0">
  <name>test_table</name>
  <columns class_id="1" tracking_level="0" version="0">
    <count>2</count>
    <item_version>0</item_version>
    <item class_id="2" tracking_level="1" version="0" object_id="_0">
      <label>AAAA</label>
      <data>xxxx</data>
    </item>
    <item class_id_reference="2" object_id="_1">
      <label>BBBB</label>
      <data /> <!-- NOW SHORT TAGGED -->
    </item>
  </columns>
</grid>

これも問題なく、完全に受け入れられ、予期しないことではありません。

このxml文字列を取得して、xmlをboostオブジェクトにシリアル化しようとすると、問題が発生します。xml文字列の短いタグ付きタグに遭遇すると、例外がスローされます。

私はこれでレンガの壁にぶつかりましたが、問題を解決する方法がわかりません。また、Webでこの問題への参照を見つけることができないため、助けていただければ幸いです。

:)

これが私のコードです。問題なくコンパイルできるはずです。db部分の空白を埋めるだけです。

grid.hpp

////////////////////////////////////////////////////////////////
// grid boost serialization object
//
#pragma once

#include <string>
#include <iomanip>
#include <iostream>
#include <fstream>

#include <boost/serialization/nvp.hpp>
#include <boost/serialization/utility.hpp>
#include <boost/serialization/list.hpp>
#include <boost/serialization/version.hpp>

/////////////////////////////////////////////////////////////
// Column
//
namespace sdcm
{

class Column
{
public:
    // every serializable class needs a constructor
    Column()
    {
    }

    Column(const std::string& _label, const std::string& _data)
    :   label(_label),
        data(_data)
    {
    }

private:
    friend class boost::serialization::access;
    friend std::ostream & operator<<(std::ostream &os, const Column &col);

    std::string label;
    std::string data;

    template<class Archive>
    void serialize(Archive & ar, const unsigned int /* file_version */)
    {
        ar  & BOOST_SERIALIZATION_NVP(label)
            & BOOST_SERIALIZATION_NVP(data)
            ;
    }
};

class Grid
{
public:
    // every serializable class needs a constructor
    Grid()
    {
    }

    Grid(const std::string& _name)
    :   name(_name)
    {
    }

    void append(Column* col)
    {
        columns.insert(columns.end(), col);
    }

private:
    friend class boost::serialization::access;
    friend std::ostream & operator<<(std::ostream &os, const Grid &grid);

    std::string name;

    typedef Column* GRID_COLUMNS;
    std::list<GRID_COLUMNS> columns;

    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        ar  & BOOST_SERIALIZATION_NVP(name)
            & BOOST_SERIALIZATION_NVP(columns);
    }
};

} // end namespace

main.cpp

// boost_test.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <sstream>
#include <iostream>
#include <string>

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

std::string get_grid_as_xml_str(sdcm::Grid& grid)
{
    std::ostringstream xml ;
    unsigned int flags = boost::archive::no_header
                        //| boost::archive::no_codecvt
                        //| boost::archive::no_xml_tag_checking
                        //| boost::archive::no_tracking
                        ;

    boost::archive::xml_oarchive oa(xml, flags);
    oa << BOOST_SERIALIZATION_NVP(grid);
    return xml.str();
}

void restore_grid_from_xml_str(sdcm::Grid& grid, const std::string& xml_str)
{
    std::istringstream xml(xml_str);
    unsigned int flags = boost::archive::no_header
                        //| boost::archive::no_codecvt
                        //| boost::archive::no_xml_tag_checking
                        //| boost::archive::no_tracking
                        ;

    boost::archive::xml_iarchive ia(xml, flags);
    ia >> BOOST_SERIALIZATION_NVP(grid);
}

int _tmain(int argc, _TCHAR* argv[])
{   
    // create grid obj with cols
    sdcm::Grid grid("MY GRID");
    grid.append(new sdcm::Column("AAAA", "xxxx")) ;
    grid.append(new sdcm::Column("BBBB", "")) ;

    // get grid as xml string
    std::string xml = get_grid_as_xml_str(grid) ;

    // Assume xml is saved to SQL Server DB table in XML datatype,
    // and the data has be retrived is a shorted tag format used
    // where blank values are present in tags

    // make a new grid
    sdcm::Grid new_grid;
    restore_grid_from_xml_str(new_grid, xml);

    return 0;
}
4

1 に答える 1

0

少し遅れましたが、ブーストから返信メールが届きました。

はい、それは多少のバグですが、彼らはそれを修正するつもりはありません。

興味のある方はこちらから返信してください。

The xml_archive code, as does all the serialization code presumes that we load exactly what we save. Generally trying to make it more general never seemed worth the risk. If you want to create, test and submit a patch to the spirit parser which would handle the tags I would look at it. But lacking this, I'm not inclined to spend time on this.

于 2012-07-16T11:28:34.047 に答える