C ++에서 어떤 XML 파서를 사용해야합니까?
구문 분석해야하는 XML 문서가 있거나 XML 문서를 작성하여 텍스트 (파일 또는 메모리)에 작성해야합니다. C ++ 표준 라이브러리에는이를위한 라이브러리가 없으므로 무엇을 사용해야합니까?
참고 : 이것은 결정적인 C ++-FAQ 스타일 질문입니다. 예, 그것은 다른 것들과 중복됩니다. 나는 그들이 다른 질문들을 좀 더 구체적으로 요구하는 경향이 있기 때문에 단순히 적절한 질문을하지 않았다. 이 질문은 더 일반적입니다.
표준 라이브러리 컨테이너와 마찬가지로 사용해야 할 라이브러리는 필요에 따라 다릅니다. 다음은 편리한 순서도입니다.
첫 번째 질문은 이것입니다 : 당신은 무엇을 필요로합니까?
완전한 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는 C 스타일의 인터페이스를 제공하지만 (실제로 귀찮게하면 Xerces를 사용하십시오), 인터페이스는 적어도 객체 기반이며 쉽게 래핑됩니다. XInclude 지원 (콜백을 사용하여 파일을 가져 오는 위치를 알려줄 수 있음), XPath 1.0 인식기, RelaxNG 및 Schematron 지원 (오류 메시지가 많이 남아 있지만)과 같은 많은 기능 을 제공합니다. 등등.
iconv에 대한 종속성이 있지만 해당 종속성없이 구성 할 수 있습니다. 그렇더라도 구문 분석 할 수있는 텍스트 인코딩이 더 제한되어 있음을 의미합니다.
MIT 라이센스를 사용합니다.
완전한 XML 규정 준수가 필요하지 않습니다
따라서 완전한 XML 규정 준수는 중요하지 않습니다. XML 문서는 완전히 제어 할 수 있거나 네임 스페이스, 엔터티 등이 아닌 XML의 "기본 하위 집합"을 사용하도록 보장됩니다.
그래서 당신에게 중요한 것은 무엇입니까? 다음 질문은 XML 작업에서 가장 중요한 것이 무엇입니까?
최대 XML 파싱 성능
응용 프로그램은 XML을 가져 와서이 변환이 발생할 수있는 한 빨리 C ++ 데이터 구조로 변환해야합니다.
당신은 선택했다 :
이 XML 파서는 주석에서 정확히 말한 것입니다 : 빠른 XML. 파일을 메모리로 가져 오는 것조차 다루지 않습니다. 어떻게 일어나는지는 당신에게 달려 있습니다. 처리하는 것은 액세스 할 수있는 일련의 C ++ 데이터 구조로 구문 분석하는 것입니다. 그리고 파일을 바이트 단위로 스캔하는 데 걸리는 속도만큼이 작업을 수행합니다.
물론, 무료 점심 식사는 없습니다. XML 사양을 신경 쓰지 않는 대부분의 XML 파서와 마찬가지로 Rapid XML은 네임 스페이스, DocTypes, 엔티티 (문자 엔티티 및 6 개의 기본 XML 제외) 등을 건드리지 않습니다. 기본적으로 노드, 요소, 속성 등
또한 DOM 스타일 파서입니다. 따라서 모든 텍스트를 읽어야합니다. 그러나 그렇지 않은 것은 해당 텍스트를 복사 하는 것입니다 (보통). RapidXML이 속도를 최대한 활용하는 방법은 현 위치 에서 문자열을 참조하는 것 입니다. 이를 위해서는 더 많은 메모리 관리가 필요합니다 (RapidXML이보고있는 동안 해당 문자열을 유지해야합니다).
RapidXML의 DOM은 기본입니다. 사물에 대한 문자열 값을 얻을 수 있습니다. 이름별로 속성을 검색 할 수 있습니다. 그게 다야. 속성을 다른 값 (숫자, 날짜 등)으로 바꾸는 편리한 기능은 없습니다. 당신은 문자열을 얻을 수 있습니다.
RapidXML의 또 다른 단점은 XML 작성에 어려움이 있다는 것입니다 . DOM을 빌드하려면 문자열 이름의 명시 적 메모리 할당을 많이 수행해야합니다. 그것은 일종의 문자열 버퍼를 제공하지만 여전히 많은 명시적인 작업이 필요합니다. 확실히 기능적이지만 사용하기가 어렵습니다.
MIT 라이센스를 사용합니다. 종속성이없는 헤더 전용 라이브러리입니다.
- 네임 스페이스에 대해서도 작업 할 수 있는 RapidXML "GitHub 패치" 가 있습니다.
나는 성능에 관심이 있지만 그다지 중요하지는 않습니다.
예, 성능이 중요합니다. 그러나 어쩌면 조금 덜 뼈가 필요한 것이 있습니다. 더 많은 유니 코드를 처리 할 수 있거나 너무 많은 사용자 제어 메모리 관리가 필요하지 않은 것일 수 있습니다. 성능은 여전히 중요하지만 조금 덜 직접적인 것을 원합니다.
당신은 선택했다 :
역사적으로 이것은 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.5이며 지난 달 (2017-10-31)에 릴리스되었습니다.
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을이 슬롯에 넣었습니다. XML 파서가 사용하는 데 사용하기 쉬운 두뇌 데드에 불과하기 때문입니다. 예, 느리지 만 간단하고 명백합니다. 속성 등을 변환하기위한 많은 편의 기능이 있습니다.
TinyXML에서 XML 작성은 문제가되지 않습니다. 당신은 new
몇 가지 물건을 올려 놓고 함께 붙이고 문서를에 보내면 std::ostream
모든 사람들이 행복합니다.
더 반복자 친화적 인 API와 XPath 1.0 구현을 기반으로 TinyXML을 기반으로 구축 된 에코 시스템도 있습니다.
TinyXML은 이름이 다른 MIT 라이센스 인 zLib 라이센스를 사용합니다.
XML 데이터 바인딩이라고하는 XML을 처리하는 또 다른 방법이 있습니다. 특히 XML 스키마와 같이 XML 어휘에 대한 공식적인 사양이 이미있는 경우.
XML 데이터 바인딩을 사용하면 실제로 XML 구문 분석이나 직렬화를 수행하지 않고도 XML을 사용할 수 있습니다. 데이터 바인딩 컴파일러는 모든 하위 수준 코드를 자동 생성하고 구문 분석 된 데이터를 응용 프로그램 도메인에 해당하는 C ++ 클래스로 표시합니다. 그런 다음 문자열을 비교하고 텍스트를 구문 분석하는 대신 함수를 호출하고 C ++ 유형 (int, double 등)을 사용하여이 데이터로 작업합니다 (DOM 또는 SAX와 같은 저수준 XML 액세스 API로 수행하는 작업).
예를 들어 필자가 작성한 오픈 소스 XML 데이터 바인딩 구현 인 CodeSynthesis XSD 와 더 가볍고 의존성이없는 버전 인 CodeSynthesis XSD / e를 참조하십시오 .
내 것도 넣어
http://www.codeproject.com/Articles/998388/XMLplusplus-version-The-Cplusplus-update-of-my-XML
XML 유효성 검사 기능은 없지만 빠릅니다.
국외 거주자에 대한 또 다른 참고 사항 : 임베디드 시스템 작업을 살펴볼 가치가 있습니다. 그러나 웹에서 찾을 수있는 문서는 고대와 잘못되었습니다. 소스 코드는 실제로 상당히 철저한 기능 수준 주석을 가지고 있지만 이해하기 위해서는 약간의 지식이 필요합니다.
자 그리고 나서. 목록 중 어느 것도 내 요구를 충족시키지 못했기 때문에 새로운 것을 만들었습니다.
혜택:
- 낮은 수준의 풀 파서 스트리밍 API ( Java StAX like )
- 지원되는 예외 및 RTTI 모드
- 메모리 사용 제한, 대용량 파일 지원 (100 mib XMark 파일 에서 테스트 , 속도는 하드웨어에 따라 다름)
- 입력 소스 인코딩을위한 UNICODE 지원 및 자동 감지
- 구조 / POCO 로 읽기위한 고급 API
- xml 구조 (속성 및 중첩 태그)를 지원하여 구조 / POCO 에서 XSD를 작성하고 생성하기위한 메타 프로그래밍 API (XSD 생성에는 RTTI가 필요하지만 한 번만 만들려면 디버그에서만 사용할 수 있음)
- C ++ 11-GCC 및 VC ++ 15+
단점 :
- 아직 제공되지 않은 DTD 및 XSD 유효성 검사
- 아직 완료되지 않은 HTTP / HTTPS로 XML / XSD 확보
- 새로운 도서관
에서 보안 글로브 , 주식 회사 우리는 사용 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);
참고 URL : https://stackoverflow.com/questions/9387610/what-xml-parser-should-i-use-in-c
'Programming' 카테고리의 다른 글
Bash의 명령에서 작은 따옴표 안의 변수 확장 (0) | 2020.03.06 |
---|---|
AngularJS : 컨트롤러간에 변수를 전달하는 방법은 무엇입니까? (0) | 2020.03.06 |
파이썬 문자열에서 어떻게 백분율 (%)을 이스케이프 처리 할 수 있습니까? (0) | 2020.03.06 |
git remote prune, git prune, git fetch --prune 등의 차이점은 무엇입니까? (0) | 2020.03.06 |
int a [] = {1,2,}; (0) | 2020.03.06 |