Как я могу избавиться от EOFException при использовании vtd- xml в c ++? - PullRequest
0 голосов
/ 09 февраля 2020

Я пишу программу для обработки старого набора данных в c ++. Мне уже удалось преобразовать файлы из sgml в xml с помощью инструмента sx от James Clark . Поскольку у меня был опыт использования vtd- xml с Matlab (который основан на java), а vtd- xml имеет порт c ++, я решил использовать его для своего проекта. Я использую vtd- xml версия 2.12 , так как это была самая новая версия порта c ++, которую я смог найти. Мне удалось скомпилировать его с помощью Visual Studio 2019, изменив все вызовы wcsdup на _wcsdup и используя определение препроцессора _CRT_SECURE_NO_WARNINGS . Моя программа, показанная ниже, дает правильный вывод, но она также выдает исключение при разборе файла xml (тестовый файл xml также находится ниже). Исключением является EOFException . Я не вижу ничего явно неправильного в моих xml файлах, и ошибка воспроизводится с помощью теста xml ниже, который я не конвертировал из sgml. Моя интуиция заключается в том, что если бы была ошибка в порте c ++, было бы легче найти информацию о ней, когда Googling for vtd- xml EOFException. Таким образом, мне кажется, что изменения, которые я сделал, чтобы заставить его скомпилировать, скорее всего виновны, но я не могу понять, как избавиться от исключения. Любые идеи будут приветствоваться. Если дело доходит до этого, я готов использовать другую библиотеку xml для моей программы, если она бесплатна.

Мой код:

#include <iostream>
#include <fstream>
#include "VTDGen.h"
#include "autoPilot.h"
#include "customTypes.h"

using namespace std;
using namespace com_ximpleware;

int main() {
    ifstream xml(".\\cd_catalog_short.xml", ios::binary | ios::ate);
    ifstream::pos_type pos = xml.tellg();
    long int length = static_cast<long int>(pos);
    char* pChars = new char[length];
    xml.seekg(0, ios::beg);
    xml.read(pChars, pos);
    xml.close();

    UCSChar node_path[] = L"/CATALOG/CD/TITLE";
    UCSChar* title;
    VTDGen vg;
    vg.setDoc(pChars, length);
    vg.parse(false);
    AutoPilot ap;
    ap.selectXPath(node_path);
    VTDNav* vn = vg.getNav();
    ap.bind(vn);
    while (ap.evalXPath() != -1) {
        int ind = vn->getText();
        if (ind != -1) {
            title = vn->toNormalizedString(ind);
            wcout << title << endl;
            delete[] title;
        }
    }
    return 0;
}

Тестовый файл xml:

<?xml version="1.0" encoding="UTF-8"?>
<CATALOG>
  <CD>
    <TITLE>For the good times</TITLE>
    <ARTIST>Kenny Rogers</ARTIST>
    <COUNTRY>UK</COUNTRY>
    <COMPANY>Mucik Master</COMPANY>
    <PRICE>8.70</PRICE>
    <YEAR>1995</YEAR>
  </CD>
  <CD>
    <TITLE>Big Willie style</TITLE>
    <ARTIST>Will Smith</ARTIST>
    <COUNTRY>USA</COUNTRY>
    <COMPANY>Columbia</COMPANY>
    <PRICE>9.90</PRICE>
    <YEAR>1997</YEAR>
  </CD>
  <CD>
    <TITLE>Tupelo Honey</TITLE>
    <ARTIST>Van Morrison</ARTIST>
    <COUNTRY>UK</COUNTRY>
    <COMPANY>Polydor</COMPANY>
    <PRICE>8.20</PRICE>
    <YEAR>1971</YEAR>
  </CD>
</CATALOG>

Вывод моей программы:

Исключение, выданное 0x00007FF96A36A839 в em.exe: исключение Microsoft C ++: com_ximpleware :: EOFException в ячейке памяти 0x0000005498B6F350.

Для хороших времен

Большая воля ie стиль

Tupelo Honey

C: \ Users \ Joe \ source \ repos \ em \ x64 \ Release \ em .exe (процесс 16308) завершен с кодом 0.

Чтобы автоматически закрывать консоль при остановке отладки, включите Инструменты-> Параметры-> Отладка-> Автоматически закрывать консоль при остановке отладки.

Нажмите любую клавишу, чтобы закрыть это окно. , .

1 Ответ

0 голосов
/ 11 февраля 2020

vtd- xml, похоже, использует EOFException скорее как сигнал, чем как истинное состояние ошибки. Я исключил возможность того, что ошибка произошла из-за изменений, внесенных для ее компиляции в Visual Studio (C ++), при запуске версии программы java. При этом используется последняя java версия vtd- xml (2.13-4- java), и он по-прежнему перехватывает EOFException. Если бы я запускал программу на С ++ через консоль вместо среды IDE Visual Studio, я бы никогда не узнал об этом исключении.

Вот код java:

/* 
 * Copyright (C) 2002-2011 XimpleWare, info@ximpleware.com
 */
import com.ximpleware.*;
import com.ximpleware.xpath.*;
import java.io.*;

public class Tester {

  public static void main(String argv[]){


    VTDGen vg = new VTDGen();

        if (vg.parseFile("./cd_catalog_short.xml",false)){
        try {
            VTDNav vn = vg.getNav();
            AutoPilot ap = new AutoPilot(vn);
                    ap.selectXPath("/CATALOG/CD/TITLE");
                    int result = -1;
            int count = 0;
            while((result = ap.evalXPath())!=-1){
            System.out.print(""+result+"  ");     
            System.out.print("Element name ==> "+vn.toString(result));
            int t = vn.getText(); // get the index of the text (char data or CDATA)
            if (t!=-1)
              System.out.println(" Text  ==> "+vn.toNormalizedString(t));
            System.out.println("\n ============================== ");
            count++;
            }
            System.out.println("Total # of element "+count);
        }
            catch (NavException e){
             System.out.println(" Exception during navigation "+e);
            }
            catch (XPathParseException e){
             System.out.println(" Exception during parse "+e);
            }
            catch (XPathEvalException e){
             System.out.println(" Exception during xpath evaluation "+e);
            }
        }
  }
}

А вот вывод программы в jdb:

jdb -classpath.; Ximpleware-2.13-4- java Tester

Инициализация jdb ...

catch com.ximpleware.EOFException

Отложено все com.ximpleware.EOFException. Он будет установлен после загрузки класса.

run

run Tester

Set uncaught java .lang.Throwable Set deferred uncaught java .lang.Throwable

VM запустилась: установить отложенное все com.ximpleware.EOFException

Произошло исключение: com.ximpleware.EOFException (для перехвата: com.ximpleware.VTDGen.parse (), line = 2,663 bci = 1,597) "thread = main", com.ximpleware.VTDGen $ UTF8Reader.getChar (), строка = 774 bci = 24 774 броска e;

main [1] продолжение

7 Название элемента ==> TITLE Text ==> Для хороших времен

=============================

20 Имя элемента ==> НАЗВАНИЕ Текст ==> Большая воля ie стиль

========================== =========

33 Имя элемента ==> НАЗВАНИЕ Текст ==> Тупело Мед

================ ==============

Всего # элемента 3

Приложение закрыто

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...