Saturday 14 May 2016

Пример работы с xml объектами в C++

Установка

В данном разделе приведена инструкция по установке в Microsoft Visual Studio 2012, возможно, для других версий подтребуется дополнительные действия, но общая логика останется прежней. 

  1. Скачать библиотеку pugixml. На странице проекта нужно нажать на кнопку "Download ZIP";
  2. Распаковать скаченный zip архив;
  3. В распакованном проекте открыть проект MVS в каталоге "pugixml-1.7\scripts". Открывать желательно проект той версии MVS, которая у вас установлена. В моем случаи MVS 2012 не было, поэтому был открыт "pugixml_vs2015.vcxproj".
  4. Открытый проект необходимо собрать и в результате будет надпись вида:1>------ Rebuild All started: Project: pugixml_vs2015, Configuration: Debug Win32 ------1>Project file contains ToolsVersion="14.0". This toolset is unknown or missing. You may be able to resolve this by installing the appropriate .NET Framework for this toolset. Treating the project as if it had ToolsVersion="4.0".1>  pugixml.cpp1>  pugixml_vs2015.vcxproj -> C:\Users\rdo\Downloads\pugixml-1.7\pugixml-1.7\scripts\vs2015\Win32_Debug\pugixml.lib========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========
  5. При сборке может дополнительно потребоваться изменить настроки компилятора, например, для MVS 2012 необходимо изменить версию "Platform Toolset" (Project -> Properties -> General -> Platform Toolset) с "v140" на "Visual Studio 2012 (v110)";
  6. Создать новый проект в MVS, если он еще не был создан.
  7. Из распакованного архива в новый проект скопировать файлы "pugixml.hpp" и "pugiconfig.hpp" из каталога "pugixml-1.7\src";
  8. Открыть проект, в заголовочные файлы проекта добавить скопированные файлы.
  9. В настройках проекта изменить следующие настроки:
    1. Project -> Properties -> Linker -> General: В поле "Additional libraries directories" прописать путь до каталога, в котором лежит скопилированная библиотека pugixml.lib (см. п4.). Например: "C:\Users\rdo\Downloads\pugixml-1.7\pugixml-1.7\scripts\vs2015\Win32_Debug";
    2. Project -> Properties -> Linker -> Input: В поле "Additional dependencies" указать сборщику, что нужно в проекте использовать дополнительную библиотеку "pugixml.lib". В итоге в поле должно быть запись вида "pugixml.lib;%(AdditionalDependencies)";
  10. Библиотека добавлена. 

Примеры работы с библиотекой

Полный список примеров можно посмотреть на еще одном сайте проекта.

Считывание с файла/строки

#include <iostream>
#include <iostream>
#include "pugixml.hpp"

std::string XML_CONTENT = "<xml>"
  "<element1>value1</element1>"
  "<element2>value2</element2>"
  "<element3>value3</element3>"
  "<element4>"
    "<element5 attr=\"attribute-value\">5</element5>"
    "<element6/>"
  "</element4>"
  "</xml>";


int main() {
  std::cout << "Example 1: loading from string/file" << std::endl;
  pugi::xml_document doc;
  pugi::xml_parse_result result 
                      = doc.load_string(XML_CONTENT.c_str());
  //pugi::xml_parse_result result = doc.load_file("filename.xml");

  std::cout << "Load result:" << result.description() << std::endl;
  return 0;
}
-------
Вывод на консоль:
Example 1: loading from string/file
Load results:No error

Получение значений

std::cout << "Example 2: getting elements value" << std::endl;
std::cout << "xml->element1: " << doc.child("xml")
                                     .child("element1")
                                     .text()
                                     .as_string() << std::endl;
std::cout << "xml->element4->element5: " << doc.child("xml")
                                               .child("element4")
                                               .child("element5")
                                               .text()
                                               .as_int() << std::endl;
std::cout << "xml->element4->element6: " << doc.child("xml")
                                               .child("element4")
                                               .child("element6")
                                               .text()
                                                .as_bool() << std::endl;
std::cout << "xml->element4->element5(attribute): " 
          << doc.child("xml")
                .child("element4")
                .child("element5")
                .attribute("attr")
                .as_string() << std::endl;

-------
Вывод на консоль:
Example 2: getting elements value
xml->element1: value1
xml->element4->element5: 5
xml->element4->element6: 0
xml->element4->element5(attribute): attribute-value


Итерирование

int Count(pugi::xml_node_iterator& begin, pugi::xml_node_iterator& end) {
  int r = -1;
  while (begin != end) {
    ++r; 
    ++begin;
  }
  return r;
}

void IterateNode(pugi::xml_node& root, int offset = 0) {
  for (pugi::xml_node node: root.children()) {
    int i = offset;
    while (i > 0) {
      std::cout << " ";
      --i;
    }
    if (Count(node.begin(), node.end()) > 0) {
      std::cout << "Node: " << node.name() << " :" << std::endl;
      IterateNode(node, offset + 2);
      return;
    }
    std::cout << "Node: " << node.name() << "; value: " << node.text().as_string() << std::endl;
  }
}

//main
std::cout << "Example 3: children iteration" << std::endl;
IterateNode(doc.child("xml"));
-------
Вывод на консоль:
Example 3: children iteration
Node: element1; value: value1
Node: element2; value: value2
Node: element3; value: value3
Node: element4 :
  Node: element5; value: 5
  Node: element6; value:


Файл проекта


Файл проекта с примерами.

No comments:

Post a Comment