Program Tip

Boost를 사용하여 XML 파일 읽기 및 쓰기

programtip 2020. 11. 4. 08:16
반응형

Boost를 사용하여 XML 파일 읽기 및 쓰기


Boost를 사용하여 XML 파일을 읽고 쓰는 좋은 방법 (그리고 간단한 방법도 있음)이 있습니까?

Boost를 사용하여 XML 파일을 읽는 간단한 샘플을 찾을 수없는 것 같습니다. XML 파일을 읽고 쓰는 데 Boost를 사용하는 간단한 샘플을 알려 주시겠습니까?

Boost가 아니라면 추천 할 수있는 XML 파일을 읽고 쓸 수있는 좋고 간단한 라이브러리가 있습니까? (C ++ 라이브러리 여야 함)


pugixml C ++ 용 가볍고 간단하며 빠른 XML 파서를 사용해보십시오.

pugixml의 가장 좋은 점은 TinyXML과 RapidXML에없는 XPath 지원입니다.

RapidXML의 저자 "이 프로젝트에 영감을 준 pugixml에 대한 작업에 대해 Arseny Kapoulkine에게 감사를 표하고 싶습니다."그리고 "내가 아는 가장 빠른 XML 파서 인 pugixml보다 5 %-30 % 빠름"그는 버전 0.3에 대해 테스트했습니다. 최근 0.42 버전에 도달 한 pugixml의.

다음은 pugixml 문서에서 발췌 한 것입니다.

주요 기능은 다음과 같습니다.

  • 낮은 메모리 소비 및 조각화 (pugxml에 대한 승리는 ~ 1.3 배, TinyXML-~ 2.5 배, Xerces (DOM)-~ 4.3 배 1) 정확한 숫자는 기존 파서와 비교 섹션에서 볼 수 있습니다.
  • 매우 빠른 파싱 속도 (pugxml에 대한 승리는 ~ 6 배, TinyXML-~ 10 배, Xerces-DOM-~ 17.6 배 1
  • 매우 빠른 구문 분석 속도 (글쎄요, 반복하고 있지만 너무 빠르기 때문에 테스트 XML에서 Expat보다 2.8 배 성능이 뛰어납니다) 2
  • 어느 정도 표준 준수 (DTD 관련 문제를 제외하고 모든 표준 준수 파일을 올바르게 구문 분석합니다)
  • 오류에 대해 거의 무시 함 (외국인의 의지처럼 You & Me와 같은 것에 질식하지 않고 잘못된 인코딩의 데이터로 파일을 구문 분석합니다. 등)
  • 깨끗한 인터페이스 (강하게 리팩터링 된 pugxml의 것)
  • 어느 정도 유니 코드를 인식합니다 (실제로는 입력 데이터의 UTF-8 인코딩을 가정하지만 ANSI에서 쉽게 작동하지만 현재로서는 UTF-16이 없습니다 (향후 작업 참조). 도우미 변환 함수 (UTF-8 <- > UTF-16 / 32 (std :: wstring 및 wchar_t의 기본값은 무엇이든))
  • 완전 표준 호환 C ++ 코드 (Comeau 엄격 모드에서 승인 됨) 라이브러리는 다중 플랫폼입니다 (플랫폼 목록에 대한 참조 참조).
  • 높은 유연성. 구문 분석 옵션을 통해 파일 구문 분석 및 DOM 트리 구축의 여러 측면을 제어 할 수 있습니다.

좋아요, 당신은 물어볼 수 있습니다-캐치가 무엇입니까? 모든 것이 매우 귀엽습니다. XML 구문 분석을위한 작고 빠르며 강력하고 깨끗한 솔루션입니다. 없어진 물건 있어요? 좋습니다. 우리는 공정한 개발자입니다. 여기에 잘못된 기능 목록이 있습니다.

  • 메모리 소비. 내가 아는 모든 DOM 기반 파서를 능가합니다.하지만 SAX 파서가 나오면 기회가 없습니다. 4Gb 미만의 메모리로 2Gb XML 파일을 처리 할 수 ​​없으며 빠르게 처리 할 수 ​​있습니다. pugixml은 다른 모든 DOM 기반 파서보다 더 잘 작동하므로 DOM을 사용하는 경우 문제가되지 않습니다.
  • 메모리 소비. 좋아, 나는 반복하고있다. 다시. 다른 파서가 일정한 저장소 (또는 메모리 매핑 영역)에 XML 파일을 제공하도록 허용하면 pugixml은 그렇지 않습니다. 따라서 전체 데이터를 일정하지 않은 저장소에 복사해야합니다. 또한 파서의 수명 동안 지속되어야합니다 (그 이유와 수명에 대한 자세한 내용은 아래에 설명되어 있습니다). 다시 말하지만, DOM을 사용해도 괜찮다면 전체 메모리 소비가 적기 때문에 문제가되지 않습니다 (문제가 될 수있는 연속적인 메모리 청크가 필요하지만).
  • 유효성 검사 부족, DTD 처리, XML 네임 스페이스, 적절한 인코딩 처리. 필요한 경우 MSXML이나 XercesC 또는 이와 유사한 것을 가져 가십시오.

TinyXML 은 아마도 좋은 선택 일 것입니다. Boost에 관해서 :

있다 Property_Tree의 에서 라이브러리 부스트 리포지토리 . 승인되었지만 현재 지원이 부족한 것 같습니다 (편집 : Property_Tree 는 이제 버전 1.41 이후 Boost의 일부입니다 . XML 기능에 관한 문서읽으 십시오 ).

Daniel Nuffer는 Boost Spirit에 대한 xml 파서구현했습니다 .


멋지고 작은 C ++ 라이브러리 인 TinyXML있습니다. 낮은 수준의 라이브러리를 찾고 있다면 RapidXML 이 좋은 출발점입니다.


Boost속성 트리를 채우는 방법 페이지의 XML 파서 장에 설명 된대로 RapidXML사용합니다 .

불행히도이 글을 쓰는 시점 에서 Boost 에는 XML 파서 가 없습니다 . 따라서 라이브러리에는 XML 구문 분석 지원을 제공 하는 빠르고 작은 RapidXML 구문 분석기 (현재 버전 1.13)가 포함되어 있습니다. RapidXML은 XML 표준을 완전히 지원하지 않습니다. DTD를 구문 분석 할 수 없으므로 전체 엔티티 대체를 수행 할 수 없습니다.

XML 부스트 자습서 도 참조하십시오 .

OP는 "부스트를 사용하여 xml 파일을 읽고 쓰는 간단한 방법"을 원하므로 아래에 매우 기본적인 예를 제공합니다.

<main>
    <owner>Matt</owner>
    <cats>
        <cat>Scarface Max</cat>
        <cat>Moose</cat>
        <cat>Snowball</cat>
        <cat>Powerball</cat>
        <cat>Miss Pudge</cat>
        <cat>Needlenose</cat>
        <cat>Sweety Pie</cat>
        <cat>Peacey</cat>
        <cat>Funnyface</cat>
    </cats>
</main>

(고양이 이름은 Matt Mahoney의 홈페이지 에서 가져온 것입니다 )

C ++의 해당 구조 :

struct Catowner
{
    std::string           owner;
    std::set<std::string> cats;
};

read_xml() 용법:

#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>

Catowner load(const std::string &file)
{
    boost::property_tree::ptree pt;
    read_xml(file, pt);

    Catowner co;

    co.owner = pt.get<std::string>("main.owner");

    BOOST_FOREACH(
       boost::property_tree::ptree::value_type &v,
       pt.get_child("main.cats"))
       co.cats.insert(v.second.data());

    return co;
}

write_xml() 용법:

void save(const Catowner &co, const std::string &file)
{
   boost::property_tree::ptree pt;

   pt.put("main.owner", co.owner);

   BOOST_FOREACH(
      const std::string &name, co.cats)
      pt.add("main.cats.cat", name);

   write_xml(file, pt);
}

XML 구문 분석을위한 특정 라이브러리는 없지만 많은 대안이 있습니다. libxml , Xerces , Expat

물론 자신의 라이브러리를 만드는 데 도움을주기 위해 다른 라이브러리 중 일부를 사용할 수는 있지만 아마도 상당한 작업이 될 것입니다.

그리고 여기 에 IBM의 주제에 대한 전체 기사 가 있습니다.


Boost는 XML 파서 atm을 제공하지 않습니다.

Poco XML ( Poco C ++ libs 의 일부 )은 훌륭하고 간단합니다.


부스트 직렬화가 목적에 충분하다면 XML의 아카이브에서 읽고 쓸 수있는 것처럼 보입니다.

Boost로 더 쉬워 진 XML


TinyXML * 좋아요 * 사용


아라비카 살펴보기


If you are looking for DOM functionality only, there are some suggestions already in this thread. I personally would probably not bother with a library lacking XPath support, and in C++, would use Qt. There's also TinyXPath, and Arabica claims to have XPath support, but I cannot say anything at all about those.


From my experiences lurking on the Boost mailing list, it appears that every time XML comes up as a subject, it is diverted into a discussion about Unicode. However, since there is a potential Unicode library looming right now, I don't think it will take too long for an XML library to appear there.

In the meantime, I too have been using TinyXML.

Interesting link about RapidXML. I'll take a look at that.


A warning. I love RapidXML, but it has a very nasty bug when parsing UTF16. Some valid values cause it to crash.

I would love to recommend pugixml - but it lacks namespace support, which I know is going to cause me problems.


There is a GSoC proposed work to improve the existing proposal of Boost.XML : https://github.com/stefanseefeld/boost.xml but as Andrzej proposed Boost.PropertyTree is nice for this task. Depending naturally of the xml size and the validation support needed.

There is also a library which was recently proposed on the Boost Mailing List : http://www.codesynthesis.com/projects/libstudxml/doc/intro.xhtml


What about boost.spirit?

Here, they show a "Mini XML" parser


<?xml version="1.0"?>
<Settings>
  <GroupA>
      <One>4</One>
      <Two>7</Two>
      <Three>9</Three> 
  </GroupA>
  <GroupA>
      <One>454</One>
      <Two>47</Two>
      <Three>29</Three> 
  </GroupA>
  <GroupB>
      <A>String A</A>
      <B>String B</B>  
  </GroupB>  
</Settings>

There is an easy way to read XML with BOOST. This example is with std::wstring based:

#include <string> 
#include <boost/property_tree/xml_parser.hpp>
#include <boost/property_tree/ptree.hpp>
#include <boost/foreach.hpp>

bool CMyClass::ReadXML(std::wstring &full_path)
{
    using boost::property_tree::wptree;

    // Populate tree structure pt:
    wptree pt;
    std::wstringstream ss; ss << load_text_file(full_path); // See below for ref.
    read_xml(ss, pt);

    // Traverse pt:
    BOOST_FOREACH(wptree::value_type const& v, pt.get_child(L"Settings"))
    {
        if (v.first == L"GroupA")
        {
            unsigned int n1 = v.second.get<unsigned int>(L"One");
            unsigned int n2 = v.second.get<unsigned int>(L"Two");
            unsigned int n3= v.second.get<unsigned int>(L"Three");
        }
        else if (v.first == L"GroupB")
        {
            std::wstring wstrA = v.second.get<std::wstring>(L"A");
            std::wstring wstrB = v.second.get<std::wstring>(L"B");
        }
    };
}

To read attributes is just a little bit more complicated.

-

Just for the reference:

std::wstring load_text_file(std::wstring &full_path)
{
    std::wifstream wif(full_path);

    wif.seekg(0, std::ios::end);
    buffer.resize(wif.tellg());
    wif.seekg(0);
    wif.read(buffer.data(), buffer.size());

    return buffer;
}

참고URL : https://stackoverflow.com/questions/1042855/using-boost-to-read-and-write-xml-files

반응형