C ++에서 어떤 XML 파서를 사용해야합니까? [닫은]


344

구문 분석해야하는 XML 문서가 있거나 XML 문서를 작성하여 텍스트 (파일 또는 메모리)에 작성해야합니다. C ++ 표준 라이브러리에는이를위한 라이브러리가 없으므로 무엇을 사용해야합니까?

참고 : 이것은 결정적인 C ++-FAQ 스타일 질문입니다. 예, 그것은 다른 것들과 중복됩니다. 나는 그들이 다른 질문들을 좀 더 구체적으로 요구하는 경향이 있기 때문에 단순히 적절한 질문을하지 않았다. 이 질문은 더 일반적입니다.


나는 tiCpp code.google.com/p/ticpp를 좋아하지만 문서는 훌륭하지 않지만 (아직?) 라이브러리는 깨끗하고 코드는 훌륭합니다.

난 내 자신의 쓴 github.com/igagis/mikroxml을
igagis

답변:


679

표준 라이브러리 컨테이너와 마찬가지로 사용해야 할 라이브러리는 필요에 따라 다릅니다. 다음은 편리한 순서도입니다.

여기에 이미지 설명을 입력하십시오

첫 번째 질문은 이것입니다 : 당신은 무엇을 필요로합니까?

완전한 XML 규정 준수가 필요합니다

좋습니다. 따라서 XML을 처리해야합니다. 장난감 XML이 아니라 실제 XML. 분석이 쉽지 않은 구문 분석 비트뿐만 아니라 모든 XML 사양 을 읽고 쓸 수 있어야합니다 . 네임 스페이스, DocType, 엔티티 대체, 작업이 필요합니다. 전체적으로 W3C XML 사양.

다음 질문은 API가 DOM 또는 SAX를 준수해야합니까?

정확한 DOM 및 / 또는 SAX 적합성이 필요합니다

OK이므로 API가 DOM 및 / 또는 SAX 여야합니다. SAX 스타일 푸시 파서 또는 DOM 스타일 유지 파서 일 수는 없습니다. 그것은 해야 C ++가 허용하는 범위까지 실제 또는 실제 DOM SAX 될.

당신은 선택했다 :

제르 세스

그게 당신의 선택입니다. DOM 및 SAX 규격을 완벽하게 갖춘 C ++ XML 파서 / 라이터입니다. 또한 XInclude 지원, XML 스키마 지원 및 기타 다양한 기능이 있습니다.

실제 의존성이 없습니다. Apache 라이센스를 사용합니다.

DOM 및 / 또는 SAX 적합성에 관심이 없습니다.

당신은 선택했다 :

LibXML2

LibXML2는 C 스타일 인터페이스를 제공하지만 (실제로 귀찮게하면 Xerces를 사용하십시오) 인터페이스는 적어도 객체 기반이며 쉽게 감싸 져 있습니다. XInclude 지원 (콜백을 사용하여 파일을 가져 오는 위치를 알려줄 수 있음), XPath 1.0 인식기, RelaxNG 및 Schematron 지원 (오류 메시지가 많이 남아 있지만)과 같은 많은 기능 을 제공합니다. 등등.

iconv에 대한 종속성이 있지만 해당 종속성없이 구성 할 수 있습니다. 그렇더라도 구문 분석 할 수있는 텍스트 인코딩이 더 제한되어 있음을 의미합니다.

MIT 라이센스를 사용합니다.

완전한 XML 규정 준수가 필요하지 않습니다

자, 완전한 XML 규정 준수는 중요하지 않습니다. XML 문서는 완전히 제어 할 수 있거나 네임 스페이스, 엔터티 등이 아닌 XML의 "기본 하위 집합"을 사용하도록 보장됩니다.

그래서 당신에게 중요한 것은 무엇입니까? 다음 질문은 XML 작업에서 가장 중요한 것이 무엇입니까?

최대 XML 파싱 성능

응용 프로그램은 XML을 가져 와서이 변환이 발생할 수있는 한 빨리 C ++ 데이터 구조로 변환해야합니다.

당신은 선택했다 :

RapidXML

이 XML 파서는 주석에서 정확히 말한 것입니다 : 빠른 XML. 파일을 메모리로 가져 오는 것조차 다루지 않습니다. 어떻게 일어나는지는 당신에게 달려 있습니다. 처리하는 것은 액세스 할 수있는 일련의 C ++ 데이터 구조로 구문 분석하는 것입니다. 그리고 파일을 바이트 단위로 스캔하는 데 걸리는 속도만큼이 작업을 수행합니다.

물론 무료 점심 식사는 없습니다. XML 사양을 신경 쓰지 않는 대부분의 XML 파서와 마찬가지로 Rapid XML은 네임 스페이스, DocType, 엔티티 (문자 엔티티 및 6 개의 기본 XML 제외) 등을 건드리지 않습니다. 기본적으로 노드, 요소, 속성 등

또한 DOM 스타일 파서입니다. 따라서 모든 텍스트를 읽어야합니다. 그러나 그렇지 않은 것은 해당 텍스트를 복사 하는 것입니다 (보통). RapidXML이 속도를 최대한 활용하는 방법은 현 위치 에서 문자열을 참조하는 입니다. 이를 위해서는 더 많은 메모리 관리가 필요합니다 (RapidXML이보고있는 동안 해당 문자열을 유지해야합니다).

RapidXML의 DOM은 기본입니다. 사물에 대한 문자열 값을 얻을 수 있습니다. 이름별로 속성을 검색 할 수 있습니다. 그게 다야. 속성을 다른 값 (숫자, 날짜 등)으로 바꾸는 편리한 함수는 없습니다. 당신은 문자열을 얻을 수 있습니다.

RapidXML의 또 다른 단점은 XML 작성에 어려움이 있다는 것입니다 . DOM을 빌드하려면 문자열 이름의 명시 적 메모리 할당을 많이 수행해야합니다. 그것은 일종의 문자열 버퍼를 제공하지만 여전히 많은 명시적인 작업이 필요합니다. 확실히 기능적이지만 사용하기가 어렵습니다.

MIT 라이센스를 사용합니다. 종속성이없는 헤더 전용 라이브러리입니다.

나는 성능에 관심이 있지만 그다지 중요하지는 않습니다.

예, 성능이 중요합니다. 그러나 어쩌면 조금 덜 뼈가 필요한 것이 있습니다. 더 많은 유니 코드를 처리 할 수 ​​있거나 많은 사용자 제어 메모리 관리가 필요하지 않은 것일 수 있습니다. 성능은 여전히 ​​중요하지만 조금 덜 직접적인 것을 원합니다.

당신은 선택했다 :

PugiXML

역사적으로 이것은 RapidXML에 영감을주었습니다. 그러나 Pugi가 더 많은 기능을 제공하면서 RapidXML은 전적으로 속도에 중점을 두면서 두 프로젝트가 분기되었습니다.

PugiXML은 유니 코드 변환 지원을 제공하므로 UTF-16 문서를 가지고 있고 UTF-8로 읽고 자하는 경우 Pugi가 제공합니다. 그런 종류의 것이 필요한 경우 XPath 1.0 구현도 있습니다.

그러나 푸기는 여전히 빠릅니다. RapidXML과 마찬가지로 종속 관계가 없으며 MIT 라이센스에 따라 배포됩니다.

거대한 문서 읽기

기가 바이트 단위로 측정 된 문서를 읽어야 합니다. 어쩌면 당신은 stdin에서 다른 프로세스에 의해 공급 받고있을 것입니다. 또는 방대한 파일에서 읽습니다. 또는 무엇이든. 요점은 처리하기 위해 전체 파일을 한 번에 메모리로 읽을 필요가 없다는 것입니다.

당신은 선택했다 :

LibXML2

Xerces의 SAX 스타일 API는이 용량에서 작동하지만 LibXML2가 여기에 있습니다. SAX 스타일 API는 푸시 API입니다. 스트림 구문 분석을 시작하고 잡아야하는 이벤트를 시작합니다. 컨텍스트, 상태 등을 관리해야합니다. SAX 스타일 API를 읽는 코드는 원하는 것보다 훨씬 더 널리 퍼져 있습니다.

LibXML2의 xmlReader객체는 풀 API입니다. 당신 에게 다음 XML 노드 또는 요소로 이동합니다; 당신은 들리지 않습니다. 이를 통해 상황에 맞는 컨텍스트를 저장하고 콜백보다 코드에서 훨씬 더 읽기 쉬운 방식으로 다른 엔티티를 처리 할 수 ​​있습니다.

대안

국외 거주자

Expat은 풀 파서 API를 사용하는 잘 알려진 C ++ 파서입니다. James Clark이 작성했습니다.

현재 상태입니다. 최신 버전은 2.2.9이며 (2019-09-25)에 릴리스되었습니다.

LlamaXML

StAX 스타일 API의 구현입니다. LibXML2의 xmlReader파서 와 비슷한 풀 파서입니다.

그러나 2005 년 이후로 업데이트되지 않았습니다. 다시 Caveat Emptor입니다.

XPath 지원

XPath는 XML 트리 내의 요소를 쿼리하기위한 시스템입니다. 표준화 된 구문을 사용하여 공통 속성으로 요소 또는 요소 컬렉션을 효과적으로 명명하는 편리한 방법입니다. 많은 XML 라이브러리는 XPath 지원을 제공합니다.

여기에는 실제로 세 가지 선택이 있습니다.

  • LibXML2 : 완전한 XPath 1.0 지원을 제공합니다. 다시 말하지만, 그것은 C API이므로 귀찮게하는 경우 대안이 있습니다.
  • PugiXML : XPath 1.0도 지원합니다. 위와 같이 LibXML2보다 C ++ API가 많으므로 더 편할 수 있습니다.
  • TinyXML : XPath 지원이 제공되지 않지만이 를 제공 하는 TinyXPath 라이브러리가 있습니다. TinyXML이 버전 2.0으로 변환 중이므로 API가 크게 변경되어 TinyXPath가 새 API에서 작동하지 않을 수 있습니다. TinyXML 자체와 마찬가지로 TinyXPath는 zLib 라이센스에 따라 배포됩니다.

그냥 일을 끝내

따라서 XML 정확성에 관심이 없습니다. 성능은 문제가되지 않습니다. 스트리밍은 관련이 없습니다. 당신이 원하는 모든입니다 뭔가 메모리에 XML을 얻고 당신이 다시 디스크에 대항 할 수 있습니다. 무엇 당신이 상관은 약 API입니다.

작고, 설치하기 쉽고, 사용하기 쉽고, 최종 실행 파일의 크기와 관련이 없을 정도로 작은 XML 파서가 필요합니다.

당신은 선택했다 :

TinyXML

TinyXML을이 슬롯에 넣었습니다. XML 파서가 사용하는 데 사용하기에 매우 간단하기 때문입니다. 예, 느리지 만 간단하고 명백합니다. 속성 등을 변환하기위한 많은 편의 기능이 있습니다.

TinyXML에서 XML 작성은 문제가되지 않습니다. 당신은 new몇 가지 물건을 위로 올려 놓고 함께 붙이고 문서를에 보내면 std::ostream모든 사람들이 행복합니다.

더 반복하기 쉬운 API와 XPath 1.0 구현으로 TinyXML을 기반으로 구축 된 에코 시스템도 있습니다.

TinyXML은 이름이 다른 MIT 라이센스 인 zLib 라이센스를 사용합니다.


6
이것은 복사 붙여 넣기처럼 보입니다. 소스 문서를 연결할 수 있습니까?
Joel

28
@Joel : 누군가가 자신의 질문에 좋은 글을 올릴 때는 종종 Jeff의 조언을 따르고 있기 때문입니다. 그 사람이 정답을 쓰고 있다면 게시하십시오. 그는 질문 : 니콜이 우리에게 제공 요청하기 전에 응답을 준비하는 시간을 복용함으로써 모든 미래의 닫기 -> 중복 질문에 대한 훌륭한 후보자를.
sarnold

28
@Joel : 나는 할 수 없습니다. 메모장 ++에서 복사 한 임시 문서 일뿐입니다. 나는 그것을 저장하지 않았다, 그래서 나는 당신을 그것에 연결할 수 없습니다;)
Nicol Bolas

6
TinyXML의 최신 버전을 언급 할 가치가 있습니다. TinyXML-2는 TinyXML-1과 동일한 API 및 풍부한 테스트 사례를 사용합니다. 그러나 파서의 구현은 게임에서 사용하기에 더 적합하도록 완전히 다시 작성되었습니다. 적은 메모리를 사용하고 더 빠르며 훨씬 적은 메모리 할당을 사용합니다.
johnbakers

6
나는이 질문과 답변을 좋아하지만 너무 유닉스 편향되어 있습니다. MSXML 및 XmlLite에 대한 언급이 없습니까? 다중 플랫폼 휴대 성이 이식을 배제한 이유라면, 이것이 질문과 답변에 명확하게 언급되어야합니다. (그렇지 않으면 일부 사람들은 쉽게 피할 수있는 두통을 요구하는 Windows 전용 프로젝트의 경우 Libxml2를 선택하게 될 수도 있습니다.)
Scrontch

17

XML 데이터 바인딩이라고하는 XML을 처리하는 또 다른 방법이 있습니다. 특히 XML 스키마와 같이 XML 어휘에 대한 공식 사양이 이미있는 경우

XML 데이터 바인딩을 사용하면 실제로 XML 구문 분석이나 직렬화를 수행하지 않고도 XML을 사용할 수 있습니다. 데이터 바인딩 컴파일러는 모든 하위 수준 코드를 자동 생성하고 구문 분석 된 데이터를 응용 프로그램 도메인에 해당하는 C ++ 클래스로 표시합니다. 그런 다음 문자열을 비교하고 텍스트를 구문 분석하는 대신 함수를 호출하고 C ++ 유형 (int, double 등)을 사용하여이 데이터로 작업합니다 (DOM 또는 SAX와 같은 저수준 XML 액세스 API로 수행하는 작업).

예를 들어 필자가 작성한 오픈 소스 XML 데이터 바인딩 구현 인 CodeSynthesis XSD 와 더 가볍고 의존성이없는 버전 인 CodeSynthesis XSD / e를 참조하십시오 .


13
나는 게시물을 신경 쓰지 않지만 SO 정책은 당신이 작성한 것을 제안하면 완전한 공개를 위해 그것을 쓴 것을 언급해야한다고 말합니다.
Nicol Bolas

@Nicol 나는 그것을 답변으로 편집했습니다.
JBentley

아마도이 목록이 도움이 되겠지만 그 목록 의 저자가 누구인지 알 수 없었습니다 (공개 공개없이 설명과 등급이 의미가 있는지 알 수 없음). 아마도 공개 도메인에 있고 테스트 및보고에 사용 된 여러 데이터 바인딩 도구 를 나열 하는 W3C 데이터 바인딩 작업 그룹 을 볼 수 있습니다 . 도구).
Dr. Alex RE

1

Expat에 대한 또 다른 참고 사항 : 임베디드 시스템 작업을 살펴볼 가치가 있습니다. 그러나 웹에서 찾을 수있는 문서는 고대와 잘못되었습니다. 소스 코드는 실제로 상당히 철저한 기능 수준 주석을 가지고 있지만 이해하기 위해서는 약간의 지식이 필요합니다.



0

자 그리고 나서. 목록 중 어느 것도 내 요구를 충족시키지 못했기 때문에 새로운 것을 만들었습니다.

혜택:

  1. 낮은 수준의 풀 파서 스트리밍 API ( Java StAX like )
  2. 지원되는 예외 및 RTTI 모드
  3. 메모리 사용 제한, 대용량 파일 지원 (100 mib XMark 파일 에서 테스트 , 속도는 하드웨어에 따라 다름)
  4. 입력 소스 인코딩을위한 UNICODE 지원 및 자동 감지
  5. 구조 / POCO 로 읽기위한 고급 API
  6. xml 구조 (속성 및 중첩 태그)를 지원하여 구조 / POCO 에서 XSD를 작성하고 생성하기위한 메타 프로그래밍 API (XSD 생성에는 RTTI가 필요하지만 한 번만 만들려면 디버그에서만 사용할 수 있음)
  7. C ++ 11-GCC 및 VC ++ 15+

단점 :

  1. 아직 제공되지 않은 DTD 및 XSD 검증
  2. 아직 완료되지 않은 HTTP / HTTPS로 XML / XSD 확보
  3. 새로운 도서관

프로젝트 홈


1
벤치 마크를 추가 할 수 있습니까?
Vadim Peretokin

-1

에서 보안 글로브 , 주식 회사 우리는 사용 rapidxml을 . 우리는 다른 모든 것을 시도했지만 rapidxml이 우리에게 가장 좋은 선택 인 것 같습니다.

예를 들면 다음과 같습니다.

 rapidxml::xml_document<char> doc;
    doc.parse<0>(xmlData);
    rapidxml::xml_node<char>* root = doc.first_node();

    rapidxml::xml_node<char>* node_account = 0;
    if (GetNodeByElementName(root, "Account", &node_account) == true)
    {
        rapidxml::xml_node<char>* node_default = 0;
        if (GetNodeByElementName(node_account, "default", &node_default) == true)
        {
            swprintf(result, 100, L"%hs", node_default->value());
            free(xmlData);
            return true;
        }
    }
    free(xmlData);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.