【问题标题】:How can I get rid of the EOFException when using vtd-xml in c++?在 c++ 中使用 vtd-xml 时如何摆脱 EOFException?
【发布时间】:2020-02-09 04:24:42
【问题描述】:

我正在编写一个程序来处理 c++ 中的旧dataset。我已经设法使用sx tool from James Clark 将文件从sgml 转换为xml。由于我过去有使用 Matlab(基于 java)的 vtd-xml 的经验,并且由于 vtd-xml 有一个 c++ 端口,所以我决定将它用于我的项目。我正在使用vtd-xml version 2.12,因为那是我能找到的最新版本的 c++ 端口。我通过更改 wcsdup to _wcsdup 的所有调用并使用 _CRT_SECURE_NO_WARNINGS 预处理器定义,设法使用 Visual Studio 2019 编译它。我下面的程序似乎给出了正确的输出,但它在解析 xml 文件期间也会引发异常(下面还有一个测试 xml 文件)。例外是EOFException。我没有看到我的 xml 文件有任何明显错误,并且该错误通过下面的测试 xml 重现,这不是我从 sgml 转换的。我的直觉是,如果 c++ 端口中存在错误,那么在谷歌搜索 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>

我的程序输出:

在 em.exe 中的 0x00007FF96A36A839 处引发异常:Microsoft C++ 异常:com_ximpleware::EOFException 在内存位置 0x0000005498B6F350。

为了美好的时光

大威利风格

图珀洛蜂蜜

C:\Users\Joe\source\repos\em\x64\Release\em.exe(进程 16308)以代码 0 退出。

要在调试停止时自动关闭控制台,启用工具->选项->调试->在调试停止时自动关闭控制台。

按任意键关闭此窗口。 . .

【问题讨论】:

    标签: c++ visual-studio vtd-xml


    【解决方案1】:

    vtd-xml 似乎使用 EOFException 更像是一个信号,而不是真正的错误状态。我通过运行程序的 java 版本消除了错误来自为使其在 Visual Studio (C++) 中编译而进行的更改的可能性。这使用 vtd-xml (2.13-4-java) 的最新 java 版本,它仍然捕获 EOFException。如果我一直通过控制台而不是 Visual Studio IDE 运行 c++ 程序,我可能永远不会知道这个异常。

    这里是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 测试器

    正在初始化 jdb ...

    捕获 com.ximpleware.EOFException

    推迟所有 com.ximpleware.EOFException。 它会在类加载后设置。

    运行

    运行测试器

    设置未捕获的 java.lang.Throwable 设置延迟未捕获的 java.lang.Throwable

    VM 已启动:设置 deferred all 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章

    主要[1]续

    7 元素名称 ==> TITLE Text ==> 美好时光

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

    20 元素名称 ==> 标题文字 ==> 大威利风格

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

    33 元素名称 ==> 标题文本 ==> 图珀洛蜂蜜

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

    元素 3 的总数

    应用程序退出

    【讨论】:

      猜你喜欢
      • 2011-05-11
      • 1970-01-01
      • 1970-01-01
      • 2013-04-17
      • 1970-01-01
      • 2020-05-09
      • 1970-01-01
      • 1970-01-01
      • 2019-09-13
      相关资源
      最近更新 更多